From 510fc443e8965e55b63989275275ea85e65ecd19 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 27 Mar 2023 17:29:42 +0200 Subject: [PATCH] Refactor CoreCLR runtime into explicit dotnet api instead of mocking mono api Required by platforms that will use mono under the hood for .Net 7 New `USE_CSHARP` define for C# ability Engine doesn't use `mono_*` apis directly but via MCore/MClass/MMethod/ apis --- .../Content/Import/TextureImportEntry.cs | 4 +- .../Editor/Content/Items/VisualScriptItem.cs | 2 +- Source/Editor/Cooker/GameCooker.cpp | 12 +- .../CustomEditors/CustomEditorsUtil.cpp | 44 +- .../Editor/CustomEditors/CustomEditorsUtil.h | 4 +- .../Editor/Managed/ManagedEditor.Internal.cpp | 158 +- Source/Editor/Managed/ManagedEditor.cpp | 19 +- Source/Editor/Scripting/ScriptsBuilder.cpp | 14 +- Source/Editor/Windows/AboutDialog.cs | 3 + Source/Engine/Animations/AnimEvent.cpp | 2 +- .../Animations/Graph/AnimGraph.Custom.cpp | 55 +- .../SceneAnimations/SceneAnimationPlayer.cpp | 35 +- .../SceneAnimations/SceneAnimationPlayer.h | 2 +- Source/Engine/Content/Asset.cpp | 9 +- Source/Engine/Content/Assets/Texture.cpp | 2 +- Source/Engine/Content/Assets/VisualScript.cpp | 13 +- Source/Engine/ContentImporters/CreateJson.cpp | 2 +- Source/Engine/ContentImporters/CreateJson.h | 2 +- Source/Engine/Core/Types/String.h | 2 + Source/Engine/Core/Types/StringView.h | 2 + Source/Engine/Core/Types/Variant.cpp | 110 +- Source/Engine/Core/Types/Variant.h | 11 +- Source/Engine/Debug/DebugLog.cpp | 64 +- .../Debug/Exceptions/CLRInnerException.h | 8 +- Source/Engine/Engine/Engine.cpp | 6 +- Source/Engine/Engine/Globals.cpp | 2 +- Source/Engine/Engine/Globals.h | 2 +- Source/Engine/Engine/NativeInterop.cs | 478 +- Source/Engine/Engine/NativeInterop_Invoker.cs | 42 +- Source/Engine/Graphics/Models/Mesh.cpp | 42 +- Source/Engine/Graphics/Models/Mesh.h | 10 +- Source/Engine/Graphics/Models/SkinnedMesh.cpp | 34 +- Source/Engine/Graphics/Models/SkinnedMesh.h | 6 +- Source/Engine/Level/Actors/Spline.cpp | 15 +- Source/Engine/Level/Actors/Spline.h | 4 +- Source/Engine/Level/Level.cpp | 2 +- Source/Engine/Level/SceneObject.cpp | 2 +- .../Engine/Localization/CultureInfo.Tables.h | 8634 +++++++++++++++++ Source/Engine/Localization/CultureInfo.cpp | 84 +- Source/Engine/Localization/CultureInfo.h | 6 +- Source/Engine/Platform/Base/ThreadBase.cpp | 2 +- Source/Engine/Platform/Base/WindowBase.cpp | 14 +- Source/Engine/Scripting/BinaryModule.cpp | 196 +- Source/Engine/Scripting/BinaryModule.h | 17 +- Source/Engine/Scripting/DotNet/CoreCLR.cpp | 386 - Source/Engine/Scripting/DotNet/CoreCLR.h | 71 - Source/Engine/Scripting/DotNet/MonoApi.cpp | 1641 ---- .../EngineInternalCalls.cpp} | 119 +- .../Scripting/{ => Internal}/InternalCalls.h | 8 +- .../MainThreadManagedInvokeAction.cpp | 2 +- .../MainThreadManagedInvokeAction.h | 18 +- .../ManagedBitArray.h | 26 +- .../ManagedDictionary.h | 99 +- .../{ => Internal}/ManagedSerialization.cpp | 22 +- .../{ => Internal}/ManagedSerialization.h | 5 +- .../{ => Internal}/StdTypesContainer.cpp | 12 +- .../{ => Internal}/StdTypesContainer.h | 0 .../InternalCalls/EngineInternalCalls.cpp | 92 - Source/Engine/Scripting/MException.cpp | 38 - .../Engine/Scripting/ManagedCLR/MAssembly.cpp | 420 - .../Engine/Scripting/ManagedCLR/MAssembly.h | 66 +- .../Scripting/ManagedCLR/MAssemblyOptions.h | 32 - Source/Engine/Scripting/ManagedCLR/MClass.cpp | 442 - Source/Engine/Scripting/ManagedCLR/MClass.h | 173 +- Source/Engine/Scripting/ManagedCLR/MCore.cpp | 2437 +---- Source/Engine/Scripting/ManagedCLR/MCore.h | 156 +- .../Engine/Scripting/ManagedCLR/MDomain.cpp | 87 - Source/Engine/Scripting/ManagedCLR/MDomain.h | 43 +- Source/Engine/Scripting/ManagedCLR/MEvent.cpp | 144 - Source/Engine/Scripting/ManagedCLR/MEvent.h | 36 +- .../Scripting/{ => ManagedCLR}/MException.h | 33 +- Source/Engine/Scripting/ManagedCLR/MField.cpp | 162 - Source/Engine/Scripting/ManagedCLR/MField.h | 22 +- .../Engine/Scripting/ManagedCLR/MMethod.cpp | 217 - Source/Engine/Scripting/ManagedCLR/MMethod.h | 38 +- .../Engine/Scripting/ManagedCLR/MProperty.cpp | 203 - .../Engine/Scripting/ManagedCLR/MProperty.h | 40 +- .../Scripting/ManagedCLR/MStaticConverter.h | 70 - Source/Engine/Scripting/ManagedCLR/MType.cpp | 50 - Source/Engine/Scripting/ManagedCLR/MType.h | 78 - Source/Engine/Scripting/ManagedCLR/MTypes.h | 53 +- Source/Engine/Scripting/ManagedCLR/MUtils.cpp | 902 +- Source/Engine/Scripting/ManagedCLR/MUtils.h | 422 +- .../Scripting/Plugins/PluginManager.cpp | 2 +- Source/Engine/Scripting/Runtime/DotNet.cpp | 1827 ++++ Source/Engine/Scripting/Runtime/Mono.cpp | 3564 +++++++ Source/Engine/Scripting/Runtime/None.cpp | 537 + Source/Engine/Scripting/Script.cpp | 2 +- Source/Engine/Scripting/Scripting.Build.cs | 6 +- Source/Engine/Scripting/Scripting.cpp | 113 +- Source/Engine/Scripting/Scripting.cs | 6 + Source/Engine/Scripting/Scripting.h | 16 - Source/Engine/Scripting/ScriptingObject.cpp | 146 +- Source/Engine/Scripting/ScriptingObject.h | 14 +- Source/Engine/Scripting/ScriptingType.h | 4 +- Source/Engine/Scripting/Types.h | 77 +- Source/Engine/Serialization/JsonWriter.h | 14 +- Source/Engine/Serialization/Serialization.cpp | 24 +- Source/Engine/Serialization/Stream.cpp | 23 +- Source/Engine/Threading/JobSystem.cpp | 16 +- Source/Engine/UI/UICanvas.cpp | 15 +- Source/Engine/UI/UIControl.cpp | 32 +- Source/Engine/Utilities/Utils.cs | 2 +- Source/Engine/Visject/VisjectGraph.cpp | 7 +- Source/FlaxEngine.Gen.cpp | 2 +- Source/ThirdParty/mono-2.0/mono.Build.cs | 1 + Source/ThirdParty/nethost/nethost.Build.cs | 2 +- .../Bindings/BindingsGenerator.CSharp.cs | 34 +- .../Bindings/BindingsGenerator.Cpp.cs | 269 +- .../Tools/Flax.Build/Build/ProjectTarget.cs | 14 - .../Flax.Build/Deps/Dependencies/mono.cs | 2 +- 111 files changed, 17048 insertions(+), 8765 deletions(-) create mode 100644 Source/Engine/Localization/CultureInfo.Tables.h delete mode 100644 Source/Engine/Scripting/DotNet/CoreCLR.cpp delete mode 100644 Source/Engine/Scripting/DotNet/CoreCLR.h delete mode 100644 Source/Engine/Scripting/DotNet/MonoApi.cpp rename Source/Engine/Scripting/{Scripting.Internal.cpp => Internal/EngineInternalCalls.cpp} (50%) rename Source/Engine/Scripting/{ => Internal}/InternalCalls.h (96%) rename Source/Engine/Scripting/{ => Internal}/MainThreadManagedInvokeAction.cpp (98%) rename Source/Engine/Scripting/{ => Internal}/MainThreadManagedInvokeAction.h (92%) rename Source/Engine/Scripting/{InternalCalls => Internal}/ManagedBitArray.h (69%) rename Source/Engine/Scripting/{InternalCalls => Internal}/ManagedDictionary.h (50%) rename Source/Engine/Scripting/{ => Internal}/ManagedSerialization.cpp (80%) rename Source/Engine/Scripting/{ => Internal}/ManagedSerialization.h (96%) rename Source/Engine/Scripting/{ => Internal}/StdTypesContainer.cpp (92%) rename Source/Engine/Scripting/{ => Internal}/StdTypesContainer.h (100%) delete mode 100644 Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp delete mode 100644 Source/Engine/Scripting/MException.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MAssembly.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MAssemblyOptions.h delete mode 100644 Source/Engine/Scripting/ManagedCLR/MClass.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MDomain.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MEvent.cpp rename Source/Engine/Scripting/{ => ManagedCLR}/MException.h (50%) delete mode 100644 Source/Engine/Scripting/ManagedCLR/MField.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MMethod.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MProperty.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MStaticConverter.h delete mode 100644 Source/Engine/Scripting/ManagedCLR/MType.cpp delete mode 100644 Source/Engine/Scripting/ManagedCLR/MType.h create mode 100644 Source/Engine/Scripting/Runtime/DotNet.cpp create mode 100644 Source/Engine/Scripting/Runtime/Mono.cpp create mode 100644 Source/Engine/Scripting/Runtime/None.cpp diff --git a/Source/Editor/Content/Import/TextureImportEntry.cs b/Source/Editor/Content/Import/TextureImportEntry.cs index 29bb62c96..3e8006f73 100644 --- a/Source/Editor/Content/Import/TextureImportEntry.cs +++ b/Source/Editor/Content/Import/TextureImportEntry.cs @@ -391,8 +391,8 @@ namespace FlaxEditor.Content.Import MaxSize = managed.MaxSize, TextureGroup = managed.TextureGroup, Size = managed.Size, - SpriteAreas = managed.SpriteAreas?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteAreas)))) : IntPtr.Zero, - SpriteNames = managed.SpriteNames?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteNames)))) : IntPtr.Zero, + SpriteAreas = managed.SpriteAreas?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteAreas))) : IntPtr.Zero, + SpriteNames = managed.SpriteNames?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteNames))) : IntPtr.Zero, }; } internal static void Free(InternalOptionsNative unmanaged) diff --git a/Source/Editor/Content/Items/VisualScriptItem.cs b/Source/Editor/Content/Items/VisualScriptItem.cs index 6638c2c67..eeb0fcd8f 100644 --- a/Source/Editor/Content/Items/VisualScriptItem.cs +++ b/Source/Editor/Content/Items/VisualScriptItem.cs @@ -134,7 +134,7 @@ namespace FlaxEditor.Content _index = index; type.Asset.GetMethodSignature(index, out _name, out _flags, out var returnTypeName, out var paramNames, out var paramTypeNames, out var paramOuts); _returnType = TypeUtils.GetType(returnTypeName); - if (paramNames.Length != 0) + if (paramNames != null && paramNames.Length != 0) { _parameters = new ScriptMemberInfo.Parameter[paramNames.Length]; for (int i = 0; i < _parameters.Length; i++) diff --git a/Source/Editor/Cooker/GameCooker.cpp b/Source/Editor/Cooker/GameCooker.cpp index 71fe6d7a7..aac9e744a 100644 --- a/Source/Editor/Cooker/GameCooker.cpp +++ b/Source/Editor/Cooker/GameCooker.cpp @@ -3,9 +3,10 @@ #include "GameCooker.h" #include "PlatformTools.h" #include "FlaxEngine.Gen.h" -#include "Engine/Scripting/MainThreadManagedInvokeAction.h" #include "Engine/Scripting/ManagedCLR/MTypes.h" #include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/BinaryModule.h" @@ -29,7 +30,6 @@ #include "Engine/Scripting/ManagedCLR/MAssembly.h" #include "Engine/Content/JsonAsset.h" #include "Engine/Content/AssetReference.h" -#include "Engine/Scripting/MException.h" #if PLATFORM_TOOLS_WINDOWS #include "Platform/Windows/WindowsPlatformTools.h" #include "Engine/Platform/Windows/WindowsPlatformSettings.h" @@ -596,9 +596,9 @@ void GameCookerImpl::OnCollectAssets(HashSet& assets) ASSERT(GameCookerImpl::Internal_OnCollectAssets); } - MCore::AttachThread(); + MCore::Thread::Attach(); MObject* exception = nullptr; - auto list = (MonoArray*)Internal_OnCollectAssets->Invoke(nullptr, nullptr, &exception); + auto list = (MArray*)Internal_OnCollectAssets->Invoke(nullptr, nullptr, &exception); if (exception) { MException ex(exception); @@ -632,7 +632,7 @@ bool GameCookerImpl::Build() Steps.Add(New()); } - MCore::AttachThread(); + MCore::Thread::Attach(); // Build Started CallEvent(GameCooker::EventType::BuildStarted); @@ -760,7 +760,7 @@ void GameCookerService::Update() } MainThreadManagedInvokeAction::ParamsBuilder params; - params.AddParam(ProgressMsg, Scripting::GetScriptsDomain()->GetNative()); + params.AddParam(ProgressMsg, Scripting::GetScriptsDomain()); params.AddParam(ProgressValue); MainThreadManagedInvokeAction::Invoke(Internal_OnProgress, params); GameCooker::OnProgress(ProgressMsg, ProgressValue); diff --git a/Source/Editor/CustomEditors/CustomEditorsUtil.cpp b/Source/Editor/CustomEditors/CustomEditorsUtil.cpp index cf64d1c83..d0c10c13d 100644 --- a/Source/Editor/CustomEditors/CustomEditorsUtil.cpp +++ b/Source/Editor/CustomEditors/CustomEditorsUtil.cpp @@ -13,7 +13,6 @@ #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "FlaxEngine.Gen.h" -#include #define TRACK_ASSEMBLY(assembly) \ if (assembly->IsLoaded()) \ @@ -49,24 +48,24 @@ struct Entry } }; -Dictionary Cache(512); +Dictionary Cache(512); void OnAssemblyLoaded(MAssembly* assembly); void OnAssemblyUnloading(MAssembly* assembly); void OnBinaryModuleLoaded(BinaryModule* module); -MonoReflectionType* CustomEditorsUtil::GetCustomEditor(MonoReflectionType* refType) +MTypeObject* CustomEditorsUtil::GetCustomEditor(MTypeObject* refType) { if (!refType) return nullptr; - MonoType* type = mono_reflection_type_get_type(refType); + MType* type = INTERNAL_TYPE_OBJECT_GET(refType); Entry result; if (Cache.TryGet(type, result)) { - const auto editor = result.CustomEditor ? result.CustomEditor : result.DefaultEditor; + MClass* editor = result.CustomEditor ? result.CustomEditor : result.DefaultEditor; if (editor) { - return MUtils::GetType(editor->GetNative()); + return MUtils::GetType(editor); } } return nullptr; @@ -123,19 +122,19 @@ void OnAssemblyLoaded(MAssembly* assembly) continue; const auto attribute = mclass->GetAttribute(customEditorAttribute); - if (attribute == nullptr || mono_object_get_class(attribute) != customEditorAttribute->GetNative()) + if (attribute == nullptr || MCore::Object::GetClass(attribute) != customEditorAttribute) continue; // Check if attribute references a valid class - MonoReflectionType* refType = nullptr; + MTypeObject* refType = nullptr; customEditorTypeField->GetValue(attribute, &refType); if (refType == nullptr) continue; - MonoType* type = mono_reflection_type_get_type(refType); + MType* type = INTERNAL_TYPE_OBJECT_GET(refType); if (type == nullptr) continue; - MonoClass* typeClass = mono_type_get_class(type); + MClass* typeClass = MCore::Type::GetClass(type); // Check if it's a custom editor class if (mclass->IsSubClassOf(customEditor)) @@ -152,18 +151,14 @@ void OnAssemblyLoaded(MAssembly* assembly) entry.CustomEditor = mclass; } - //LOG(Info, "Custom Editor {0} for type {1} (default: {2})", String(mclass->GetFullName()), String(mono_type_get_name(type)), isDefault); + //LOG(Info, "Custom Editor {0} for type {1} (default: {2})", String(mclass->GetFullName()), MCore::Type::ToString(type), isDefault); } else if (typeClass) { - MClass* referencedClass = Scripting::FindClass(typeClass); - if (referencedClass) - { - auto& entry = Cache[mono_class_get_type(mclass->GetNative())]; - entry.CustomEditor = referencedClass; + auto& entry = Cache[mclass->GetType()]; + entry.CustomEditor = typeClass; - //LOG(Info, "Custom Editor {0} for type {1}", String(referencedClass->GetFullName()), String(mclass->GetFullName())); - } + //LOG(Info, "Custom Editor {0} for type {1}", String(typeClass->GetFullName()), String(mclass->GetFullName())); } } @@ -183,21 +178,16 @@ void OnAssemblyUnloading(MAssembly* assembly) // Remove entries with user classes for (auto i = Cache.Begin(); i.IsNotEnd(); ++i) { -#if USE_NETCORE - MonoClass* monoClass = mono_type_get_class(i->Key); -#else - MonoClass* monoClass = (MonoClass*)(void*)i->Key; -#endif - - if (assembly->GetClass(monoClass)) + MClass* mClass = MCore::Type::GetClass(i->Key); + if (mClass && mClass->GetAssembly() == assembly) { Cache.Remove(i); } else { - if (i->Value.DefaultEditor && assembly->GetClass(i->Value.DefaultEditor->GetNative())) + if (i->Value.DefaultEditor && i->Value.DefaultEditor->GetAssembly() == assembly) i->Value.DefaultEditor = nullptr; - if (i->Value.CustomEditor && assembly->GetClass(i->Value.CustomEditor->GetNative())) + if (i->Value.CustomEditor && i->Value.CustomEditor->GetAssembly() == assembly) i->Value.CustomEditor = nullptr; } } diff --git a/Source/Editor/CustomEditors/CustomEditorsUtil.h b/Source/Editor/CustomEditors/CustomEditorsUtil.h index 287602369..aea45729e 100644 --- a/Source/Editor/CustomEditors/CustomEditorsUtil.h +++ b/Source/Editor/CustomEditors/CustomEditorsUtil.h @@ -11,7 +11,7 @@ class CustomEditorsUtil { public: -#if USE_MONO - static MonoReflectionType* GetCustomEditor(MonoReflectionType* refType); +#if USE_CSHARP + static MTypeObject* GetCustomEditor(MTypeObject* refType); #endif }; diff --git a/Source/Editor/Managed/ManagedEditor.Internal.cpp b/Source/Editor/Managed/ManagedEditor.Internal.cpp index 4f0799b60..c42123e41 100644 --- a/Source/Editor/Managed/ManagedEditor.Internal.cpp +++ b/Source/Editor/Managed/ManagedEditor.Internal.cpp @@ -9,11 +9,11 @@ #include "Engine/ContentExporters/AssetsExportingManager.h" #include "Editor/CustomEditors/CustomEditorsUtil.h" #include "Engine/Scripting/Scripting.h" -#include "Engine/Scripting/InternalCalls.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MAssembly.h" -#include "Engine/Scripting/StdTypesContainer.h" +#include "Engine/Scripting/Internal/InternalCalls.h" +#include "Engine/Scripting/Internal/StdTypesContainer.h" #include "Engine/Graphics/Shaders/Cache/ShaderCacheManager.h" #include "Engine/ShadowsOfMordor/Builder.h" #include "Engine/Physics/CollisionData.h" @@ -47,7 +47,6 @@ #include "FlaxEngine.Gen.h" #include "Engine/Level/Actors/AnimatedModel.h" #include "Engine/Serialization/JsonTools.h" -#include Guid ManagedEditor::ObjectID(0x91970b4e, 0x99634f61, 0x84723632, 0x54c776af); @@ -75,8 +74,8 @@ struct InternalTextureOptions int32 TextureGroup; int32 SizeX; int32 SizeY; - MonoArray* SpriteAreas; - MonoArray* SpriteNames; + MArray* SpriteAreas; + MArray* SpriteNames; static void Convert(InternalTextureOptions* from, ImportTexture::Options* to) { @@ -99,14 +98,16 @@ struct InternalTextureOptions to->Sprites.Clear(); if (from->SpriteNames != nullptr) { - int32 count = (int32)mono_array_length(from->SpriteNames); - ASSERT(count == (int32)mono_array_length(from->SpriteAreas)); - to->Sprites.EnsureCapacity(count); + int32 count = MCore::Array::GetLength(from->SpriteNames); + ASSERT(count == MCore::Array::GetLength(from->SpriteAreas)); + to->Sprites.Resize(count); + MString** spriteNamesPtr = MCore::Array::GetAddress(from->SpriteNames); + Rectangle* spriteAreasPtr = MCore::Array::GetAddress(from->SpriteAreas); for (int32 i = 0; i < count; i++) { - Sprite& sprite = to->Sprites.AddOne(); - sprite.Area = mono_array_get(from->SpriteAreas, Rectangle, i); - sprite.Name = MUtils::ToString(mono_array_get(from->SpriteNames, MonoString*, i)); + Sprite& sprite = to->Sprites[i]; + sprite.Area = spriteAreasPtr[i]; + sprite.Name = MUtils::ToString(spriteNamesPtr[i]); } } } @@ -131,16 +132,14 @@ struct InternalTextureOptions to->SizeY = from->SizeY; if (from->Sprites.HasItems()) { - const auto domain = mono_domain_get(); - int32 count = from->Sprites.Count(); - auto rectClass = Rectangle::TypeInitializer.GetType().ManagedClass; - ASSERT(rectClass != nullptr); - to->SpriteAreas = mono_array_new(domain, rectClass->GetNative(), count); - to->SpriteNames = mono_array_new(domain, mono_get_string_class(), count); + const int32 count = from->Sprites.Count(); + to->SpriteAreas = MCore::Array::New(Rectangle::TypeInitializer.GetClass(), count); + to->SpriteNames = MCore::Array::New( MCore::TypeCache::String, count); + Rectangle* spriteAreasPtr = MCore::Array::GetAddress(to->SpriteAreas); for (int32 i = 0; i < count; i++) { - mono_array_set(to->SpriteAreas, Rectangle, i, from->Sprites[i].Area); - mono_array_setref(to->SpriteNames, i, MUtils::ToString(from->Sprites[i].Name, domain)); + spriteAreasPtr[i] = from->Sprites[i].Area; + MCore::GC::WriteArrayRef(to->SpriteNames, (MObject*)MUtils::ToString(from->Sprites[i].Name), i); } } else @@ -167,7 +166,7 @@ struct InternalModelOptions byte ImportVertexColors; byte ImportBlendShapes; ModelLightmapUVsSource LightmapUVsSource; - MonoString* CollisionMeshesPrefix; + MString* CollisionMeshesPrefix; // Transform float Scale; @@ -185,7 +184,7 @@ struct InternalModelOptions byte OptimizeKeyframes; byte ImportScaleTracks; byte EnableRootMotion; - MonoString* RootNodeName; + MString* RootNodeName; // Level Of Detail byte GenerateLODs; @@ -371,7 +370,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_IsPlayMode() return Editor::IsPlayMode; } -DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MonoArray** outMessages, MonoArray** outLogTypes, MonoArray** outLogTimes, int outArraySize) +DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MArray** outMessages, MArray** outLogTypes, MArray** outLogTimes, int outArraySize) { ScopeLock lock(CachedLogDataLocker); if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr) @@ -382,6 +381,8 @@ DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MonoArray** outMessage byte* ptr = CachedLogData.Get(); byte* end = ptr + CachedLogData.Count(); + byte* outLogTypesPtr = MCore::Array::GetAddress(*outLogTypes); + int64* outLogTimesPtr = MCore::Array::GetAddress(*outLogTimes); while (count < maxCount && ptr != end) { auto type = (byte)*(int32*)ptr; @@ -398,9 +399,9 @@ DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MonoArray** outMessage auto msgObj = MUtils::ToString(StringView(msg, length)); - mono_array_setref(*outMessages, count, msgObj); - mono_array_set(*outLogTypes, byte, count, type); - mono_array_set(*outLogTimes, int64, count, time); + MCore::GC::WriteArrayRef(*outMessages, (MObject*)msgObj, count); + outLogTypesPtr[count] = type; + outLogTimesPtr[count] = time; count++; } @@ -417,7 +418,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_SetPlayMode(bool value) Editor::IsPlayMode = value; } -DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_GetProjectPath() +DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetProjectPath() { return MUtils::ToString(Editor::Project->ProjectPath); } @@ -427,7 +428,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_CloseSplashScreen() Editor::CloseSplashScreen(); } -DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MonoString* dstPathObj, MonoString* srcPathObj, Guid* dstId) +DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MString* dstPathObj, MString* srcPathObj, Guid* dstId) { // Get normalized paths String dstPath, srcPath; @@ -456,7 +457,7 @@ enum class NewAssetType Animation = 11, }; -DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateAsset(NewAssetType type, MonoString* outputPathObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateAsset(NewAssetType type, MString* outputPathObj) { String tag; switch (type) @@ -508,7 +509,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateAsset(NewAssetType type, MonoStr return AssetsImportingManager::Create(tag, outputPath); } -DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MonoString* outputPathObj, MonoString* baseTypenameObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MString* outputPathObj, MString* baseTypenameObj) { String outputPath; MUtils::ToString(outputPathObj, outputPath); @@ -518,7 +519,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MonoString* outputP return AssetsImportingManager::Create(AssetsImportingManager::CreateVisualScriptTag, outputPath, &baseTypename); } -DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_CanImport(MonoString* extensionObj) +DEFINE_INTERNAL_CALL(MString*) EditorInternal_CanImport(MString* extensionObj) { String extension; MUtils::ToString(extensionObj, extension); @@ -528,7 +529,7 @@ DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_CanImport(MonoString* extension return importer ? MUtils::ToString(importer->ResultExtension) : nullptr; } -DEFINE_INTERNAL_CALL(bool) EditorInternal_Import(MonoString* inputPathObj, MonoString* outputPathObj, void* arg) +DEFINE_INTERNAL_CALL(bool) EditorInternal_Import(MString* inputPathObj, MString* outputPathObj, void* arg) { String inputPath, outputPath; MUtils::ToString(inputPathObj, inputPath); @@ -538,21 +539,21 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_Import(MonoString* inputPathObj, MonoS return AssetsImportingManager::Import(inputPath, outputPath, arg); } -DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportTexture(MonoString* inputPathObj, MonoString* outputPathObj, InternalTextureOptions* optionsObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportTexture(MString* inputPathObj, MString* outputPathObj, InternalTextureOptions* optionsObj) { ImportTexture::Options options; InternalTextureOptions::Convert(optionsObj, &options); return EditorInternal_Import(inputPathObj, outputPathObj, &options); } -DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportModel(MonoString* inputPathObj, MonoString* outputPathObj, InternalModelOptions* optionsObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportModel(MString* inputPathObj, MString* outputPathObj, InternalModelOptions* optionsObj) { ImportModelFile::Options options; InternalModelOptions::Convert(optionsObj, &options); return EditorInternal_Import(inputPathObj, outputPathObj, &options); } -DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportAudio(MonoString* inputPathObj, MonoString* outputPathObj, InternalAudioOptions* optionsObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_ImportAudio(MString* inputPathObj, MString* outputPathObj, InternalAudioOptions* optionsObj) { ImportAudio::Options options; InternalAudioOptions::Convert(optionsObj, &options); @@ -566,27 +567,24 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_GetAudioClipMetadata(AudioClip* clip, *importedSize = clip->AudioHeader.ImportedSize; } -DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MonoString* outputPathObj, MonoString* dataObj, MonoString* dataTypeNameObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MString* outputPathObj, MString* dataObj, MString* dataTypeNameObj) { String outputPath; MUtils::ToString(outputPathObj, outputPath); FileSystem::NormalizePath(outputPath); - const auto dataObjPtr = mono_string_to_utf8(dataObj); - StringAnsiView data(dataObjPtr); + const StringView dataObjChars = MCore::String::GetChars(dataObj); + const StringAsANSI<> data(dataObjChars.Get(), dataObjChars.Length()); + const StringAnsiView dataAnsi(data.Get(), data.Length()); + + const StringView dataTypeNameObjChars = MCore::String::GetChars(dataTypeNameObj); + const StringAsANSI<> dataTypeName(dataTypeNameObjChars.Get(), dataTypeNameObjChars.Length()); + const StringAnsiView dataTypeNameAnsi(dataTypeName.Get(), dataTypeName.Length()); - const auto dataTypeNameObjPtr = mono_string_to_utf8(dataTypeNameObj); - StringAnsiView dataTypeName(dataTypeNameObjPtr); - - const bool result = CreateJson::Create(outputPath, data, dataTypeName); - - mono_free(dataObjPtr); - mono_free(dataTypeNameObjPtr); - - return result; + return CreateJson::Create(outputPath, dataAnsi, dataTypeNameAnsi); } -DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MonoString* pathObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MString* pathObj) { #if COMPILE_WITH_ASSETS_EXPORTER String path; @@ -599,7 +597,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MonoString* pathObj) #endif } -DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MonoString* inputPathObj, MonoString* outputFolderObj) +DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MString* inputPathObj, MString* outputFolderObj) { #if COMPILE_WITH_ASSETS_EXPORTER String inputPath; @@ -630,7 +628,7 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_BakeLightmaps(bool cancel) builder->Build(); } -DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_GetShaderAssetSourceCode(BinaryAsset* obj) +DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetShaderAssetSourceCode(BinaryAsset* obj) { INTERNAL_CALL_CHECK_RETURN(obj, nullptr); if (obj->WaitForLoaded()) @@ -655,7 +653,7 @@ DEFINE_INTERNAL_CALL(MonoString*) EditorInternal_GetShaderAssetSourceCode(Binary return str; } -DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MonoString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) +DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) { #if COMPILE_WITH_PHYSICS_COOKING CollisionCooking::Argument arg; @@ -675,7 +673,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MonoString* pathObj, #endif } -DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* collisionData, MonoArray** triangles, MonoArray** indices, int* trianglesCount, int* indicesCount) +DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* collisionData, MArray** triangles, MArray** indices, int* trianglesCount, int* indicesCount) { if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None) return; @@ -683,20 +681,18 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* colli const auto& debugLines = collisionData->GetDebugLines(); const int32 linesCount = debugLines.Count() / 2; - mono_gc_wbarrier_generic_store(triangles, (MonoObject*)mono_array_new(mono_domain_get(), Float3::TypeInitializer.GetMonoClass(), debugLines.Count())); - mono_gc_wbarrier_generic_store(indices, (MonoObject*)mono_array_new(mono_domain_get(), mono_get_int32_class(), linesCount * 3)); + MCore::GC::WriteRef(triangles, (MObject*)MCore::Array::New(Float3::TypeInitializer.GetClass(), debugLines.Count())); + MCore::GC::WriteRef(indices, (MObject*)MCore::Array::New( MCore::TypeCache::Int32, linesCount * 3)); // Use one triangle per debug line - for (int32 i = 0; i < debugLines.Count(); i++) - { - mono_array_set(*triangles, Float3, i, debugLines[i]); - } + Platform::MemoryCopy(MCore::Array::GetAddress(*triangles), debugLines.Get(), debugLines.Count() * sizeof(Float3)); int32 iI = 0; + int32* indicesPtr = MCore::Array::GetAddress(*indices); for (int32 i = 0; i < debugLines.Count(); i += 2) { - mono_array_set(*indices, int32, iI++, i); - mono_array_set(*indices, int32, iI++, i + 1); - mono_array_set(*indices, int32, iI++, i); + indicesPtr[iI++] = i; + indicesPtr[iI++] = i + 1; + indicesPtr[iI++] = i; } *trianglesCount = debugLines.Count(); *indicesCount = linesCount * 3; @@ -828,23 +824,23 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa struct VisualScriptLocalManaged { - MonoString* Value; - MonoString* ValueTypeName; + MString* Value; + MString* ValueTypeName; uint32 NodeId; int32 BoxId; }; -DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptLocals(int* localsCount) +DEFINE_INTERNAL_CALL(MArray*) EditorInternal_GetVisualScriptLocals(int* localsCount) { - MonoArray* result = nullptr; + MArray* result = nullptr; *localsCount = 0; const auto stack = VisualScripting::GetThreadStackTop(); if (stack && stack->Scope) { const int32 count = stack->Scope->Parameters.Length() + stack->Scope->ReturnedValues.Count(); - const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptLocal"); + const MClass* mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptLocal"); ASSERT(mclass); - result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); + result = MCore::Array::New( mclass, count); VisualScriptLocalManaged local; local.NodeId = MAX_uint32; if (stack->Scope->Parameters.Length() != 0) @@ -855,13 +851,14 @@ DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptLocals(int* local if (s) local.NodeId = s->Node->ID; } + VisualScriptLocalManaged* resultPtr = MCore::Array::GetAddress(result); for (int32 i = 0; i < stack->Scope->Parameters.Length(); i++) { auto& v = stack->Scope->Parameters[i]; local.BoxId = i + 1; local.Value = MUtils::ToString(v.ToString()); local.ValueTypeName = MUtils::ToString(v.Type.GetTypeName()); - mono_array_set(result, VisualScriptLocalManaged, i, local); + resultPtr[i] = local; } for (int32 i = 0; i < stack->Scope->ReturnedValues.Count(); i++) { @@ -870,7 +867,7 @@ DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptLocals(int* local local.BoxId = v.BoxId; local.Value = MUtils::ToString(v.Value.ToString()); local.ValueTypeName = MUtils::ToString(v.Value.Type.GetTypeName()); - mono_array_set(result, VisualScriptLocalManaged, stack->Scope->Parameters.Length() + i, local); + resultPtr[stack->Scope->Parameters.Length() + i] = local; } *localsCount = count; } @@ -879,14 +876,14 @@ DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptLocals(int* local struct VisualScriptStackFrameManaged { - MonoObject* Script; + MObject* Script; uint32 NodeId; int32 BoxId; }; -DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptStackFrames(int* stackFramesCount) +DEFINE_INTERNAL_CALL(MArray*) EditorInternal_GetVisualScriptStackFrames(int* stackFramesCount) { - MonoArray* result = nullptr; + MArray* result = nullptr; *stackFramesCount = 0; const auto stack = VisualScripting::GetThreadStackTop(); if (stack) @@ -898,9 +895,10 @@ DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptStackFrames(int* s = s->PreviousFrame; count++; } - const auto mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptStackFrame"); + const MClass* mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptStackFrame"); ASSERT(mclass); - result = mono_array_new(mono_domain_get(), mclass->GetNative(), count); + result = MCore::Array::New( mclass, count); + VisualScriptStackFrameManaged* resultPtr = MCore::Array::GetAddress(result); s = stack; count = 0; while (s) @@ -909,7 +907,7 @@ DEFINE_INTERNAL_CALL(MonoArray*) EditorInternal_GetVisualScriptStackFrames(int* frame.Script = s->Script->GetOrCreateManagedInstance(); frame.NodeId = s->Node->ID; frame.BoxId = s->Box ? s->Box->ID : MAX_uint32; - mono_array_set(result, VisualScriptStackFrameManaged, count, frame); + resultPtr[count] = frame; s = s->PreviousFrame; count++; } @@ -951,7 +949,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_EvaluateVisualScriptLocal(VisualScript return false; } -DEFINE_INTERNAL_CALL(void) EditorInternal_DeserializeSceneObject(SceneObject* sceneObject, MonoString* jsonObj) +DEFINE_INTERNAL_CALL(void) EditorInternal_DeserializeSceneObject(SceneObject* sceneObject, MString* jsonObj) { PROFILE_CPU_NAMED("DeserializeSceneObject"); @@ -1017,12 +1015,12 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_SetAnimationTime(AnimatedModel* animat animatedModel->GraphInstance.State[0].Animation.TimePosition = time; } -DEFINE_INTERNAL_CALL(MonoReflectionType*) CustomEditorsUtilInternal_GetCustomEditor(MonoReflectionType* targetType) +DEFINE_INTERNAL_CALL(MTypeObject*) CustomEditorsUtilInternal_GetCustomEditor(MTypeObject* targetType) { return CustomEditorsUtil::GetCustomEditor(targetType); } -DEFINE_INTERNAL_CALL(bool) TextureImportEntryInternal_GetTextureImportOptions(MonoString* pathObj, InternalTextureOptions* result) +DEFINE_INTERNAL_CALL(bool) TextureImportEntryInternal_GetTextureImportOptions(MString* pathObj, InternalTextureOptions* result) { String path; MUtils::ToString(pathObj, path); @@ -1037,7 +1035,7 @@ DEFINE_INTERNAL_CALL(bool) TextureImportEntryInternal_GetTextureImportOptions(Mo return false; } -DEFINE_INTERNAL_CALL(void) ModelImportEntryInternal_GetModelImportOptions(MonoString* pathObj, InternalModelOptions* result) +DEFINE_INTERNAL_CALL(void) ModelImportEntryInternal_GetModelImportOptions(MString* pathObj, InternalModelOptions* result) { // Initialize defaults ImportModelFile::Options options; @@ -1056,7 +1054,7 @@ DEFINE_INTERNAL_CALL(void) ModelImportEntryInternal_GetModelImportOptions(MonoSt InternalModelOptions::Convert(&options, result); } -DEFINE_INTERNAL_CALL(bool) AudioImportEntryInternal_GetAudioImportOptions(MonoString* pathObj, InternalAudioOptions* result) +DEFINE_INTERNAL_CALL(bool) AudioImportEntryInternal_GetAudioImportOptions(MString* pathObj, InternalAudioOptions* result) { String path; MUtils::ToString(pathObj, path); @@ -1074,7 +1072,7 @@ DEFINE_INTERNAL_CALL(bool) AudioImportEntryInternal_GetAudioImportOptions(MonoSt return false; } -DEFINE_INTERNAL_CALL(MonoArray*) LayersAndTagsSettingsInternal_GetCurrentLayers(int* layersCount) +DEFINE_INTERNAL_CALL(MArray*) LayersAndTagsSettingsInternal_GetCurrentLayers(int* layersCount) { *layersCount = Math::Max(1, Level::GetNonEmptyLayerNamesCount()); return MUtils::ToArray(Span(Level::Layers, *layersCount)); diff --git a/Source/Editor/Managed/ManagedEditor.cpp b/Source/Editor/Managed/ManagedEditor.cpp index da743866f..dd35a0760 100644 --- a/Source/Editor/Managed/ManagedEditor.cpp +++ b/Source/Editor/Managed/ManagedEditor.cpp @@ -3,20 +3,19 @@ #include "ManagedEditor.h" #include "Editor/Editor.h" #include "FlaxEngine.Gen.h" -#include "Engine/Scripting/MException.h" -#include "Engine/Scripting/Scripting.h" -#include "Engine/Scripting/MainThreadManagedInvokeAction.h" #include "Engine/ShadowsOfMordor/Builder.h" +#include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Scripting/ManagedCLR/MAssembly.h" #include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h" #include "Engine/Content/Assets/VisualScript.h" #include "Engine/CSG/CSGBuilder.h" #include "Engine/Engine/CommandLine.h" #include "Engine/Renderer/ProbesRenderer.h" #include "Engine/Animations/Graph/AnimGraph.h" -#include ManagedEditor::InternalOptions ManagedEditor::ManagedEditorOptions; @@ -79,7 +78,7 @@ void OnBakeEvent(bool started, const ProbesRenderer::Entry& e) ASSERT(Internal_EnvProbeBake); } - MonoObject* probeObj = e.Actor ? e.Actor->GetManagedInstance() : nullptr; + MObject* probeObj = e.Actor ? e.Actor->GetManagedInstance() : nullptr; MainThreadManagedInvokeAction::ParamsBuilder params; params.AddParam(started); @@ -107,8 +106,8 @@ void OnBrushModified(CSG::Brush* brush) struct VisualScriptingDebugFlowInfo { - MonoObject* Script; - MonoObject* ScriptInstance; + MObject* Script; + MObject* ScriptInstance; uint32 NodeId; int32 BoxId; }; @@ -187,7 +186,7 @@ void ManagedEditor::Init() { LOG(Fatal, "Invalid Editor assembly! Missing initialization method."); } - MonoObject* instance = GetOrCreateManagedInstance(); + MObject* instance = GetOrCreateManagedInstance(); if (instance == nullptr) { LOG(Fatal, "Failed to create editor instance."); @@ -325,7 +324,7 @@ bool ManagedEditor::CanReloadScripts() bool ManagedEditor::CanAutoBuildCSG() { // Skip calls from non-managed thread (eg. physics worker) - if (!mono_domain_get() || !mono_thread_current()) + if (!MCore::Thread::IsAttached()) return false; if (!HasManagedInstance()) @@ -343,7 +342,7 @@ bool ManagedEditor::CanAutoBuildCSG() bool ManagedEditor::CanAutoBuildNavMesh() { // Skip calls from non-managed thread (eg. physics worker) - if (!mono_domain_get() || !mono_thread_current()) + if (!MCore::Thread::IsAttached()) return false; if (!HasManagedInstance()) diff --git a/Source/Editor/Scripting/ScriptsBuilder.cpp b/Source/Editor/Scripting/ScriptsBuilder.cpp index 7a5d0b526..5bdd515d1 100644 --- a/Source/Editor/Scripting/ScriptsBuilder.cpp +++ b/Source/Editor/Scripting/ScriptsBuilder.cpp @@ -15,7 +15,7 @@ #include "Engine/Platform/FileSystemWatcher.h" #include "Engine/Platform/CreateProcessSettings.h" #include "Engine/Threading/Threading.h" -#include "Engine/Scripting/MainThreadManagedInvokeAction.h" +#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Scripting/ManagedCLR/MAssembly.h" @@ -77,7 +77,7 @@ namespace ScriptsBuilderImpl void onScriptsReloadEnd(); void onScriptsLoaded(); - void GetClassName(const MString& fullname, MString& className); + void GetClassName(const StringAnsi& fullname, StringAnsi& className); void onCodeEditorAsyncOpenBegin() { @@ -245,12 +245,12 @@ bool ScriptsBuilder::RunBuildTool(const StringView& args, const StringView& work cmdLine.Append(TEXT("\"")); cmdLine.Append(monoPath); cmdLine.Append(TEXT("\" ")); + // TODO: Set env var for the mono MONO_GC_PARAMS=nursery-size64m to boost build performance -> profile it #endif cmdLine.Append(TEXT("\"")); cmdLine.Append(buildToolPath); cmdLine.Append(TEXT("\" ")); cmdLine.Append(args.Get(), args.Length()); - // TODO: Set env var for the mono MONO_GC_PARAMS=nursery-size64m to boost build performance -> profile it // Call build tool CreateProcessSettings procSettings; @@ -270,7 +270,7 @@ bool ScriptsBuilder::GenerateProject(const StringView& customArgs) return RunBuildTool(args); } -void ScriptsBuilderImpl::GetClassName(const MString& fullname, MString& className) +void ScriptsBuilderImpl::GetClassName(const StringAnsi& fullname, StringAnsi& className) { const auto lastDotIndex = fullname.FindLast('.'); if (lastDotIndex != -1) @@ -287,7 +287,7 @@ void ScriptsBuilderImpl::GetClassName(const MString& fullname, MString& classNam MClass* ScriptsBuilder::FindScript(const StringView& scriptName) { PROFILE_CPU(); - const MString scriptNameStd = scriptName.ToStringAnsi(); + const StringAnsi scriptNameStd = scriptName.ToStringAnsi(); const ScriptingTypeHandle scriptingType = Scripting::FindScriptingType(scriptNameStd); if (scriptingType) @@ -301,7 +301,7 @@ MClass* ScriptsBuilder::FindScript(const StringView& scriptName) // Check all assemblies (ignoring the typename namespace) auto& modules = BinaryModule::GetModules(); - MString className; + StringAnsi className; GetClassName(scriptNameStd, className); MClass* scriptClass = Script::GetStaticClass(); for (int32 j = 0; j < modules.Count(); j++) @@ -318,7 +318,7 @@ MClass* ScriptsBuilder::FindScript(const StringView& scriptName) // Managed scripts if (mclass->IsSubClassOf(scriptClass) && !mclass->IsStatic() && !mclass->IsAbstract() && !mclass->IsInterface()) { - MString mclassName; + StringAnsi mclassName; GetClassName(mclass->GetFullName(), mclassName); if (className == mclassName) { diff --git a/Source/Editor/Windows/AboutDialog.cs b/Source/Editor/Windows/AboutDialog.cs index 6ef152e28..4b9595445 100644 --- a/Source/Editor/Windows/AboutDialog.cs +++ b/Source/Editor/Windows/AboutDialog.cs @@ -125,6 +125,9 @@ namespace FlaxEditor.Windows "Used third party software:", "", "Mono Project - www.mono-project.com", +#if USE_NETCORE + ".NET - www.dotnet.microsoft.com", +#endif "FreeType Project - www.freetype.org", "Assimp - www.assimp.sourceforge.net", "DirectXMesh - Copyright (c) Microsoft Corporation. All rights reserved.", diff --git a/Source/Engine/Animations/AnimEvent.cpp b/Source/Engine/Animations/AnimEvent.cpp index a3ec94861..e46a99c62 100644 --- a/Source/Engine/Animations/AnimEvent.cpp +++ b/Source/Engine/Animations/AnimEvent.cpp @@ -2,7 +2,7 @@ #include "AnimEvent.h" #include "Engine/Scripting/BinaryModule.h" -#include "Engine/Scripting/ManagedSerialization.h" +#include "Engine/Scripting/Internal/ManagedSerialization.h" #include "Engine/Serialization/SerializationFwd.h" #include "Engine/Serialization/Serialization.h" diff --git a/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp b/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp index 6e9156001..b1b49742f 100644 --- a/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp +++ b/Source/Engine/Animations/Graph/AnimGraph.Custom.cpp @@ -2,25 +2,23 @@ #include "AnimGraph.h" #include "Engine/Debug/DebugLog.h" -#include "Engine/Scripting/InternalCalls.h" +#include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/BinaryModule.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Scripting/ManagedCLR/MDomain.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" -#include "Engine/Scripting/Scripting.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/Internal/InternalCalls.h" #include "Engine/Content/Assets/SkinnedModel.h" -#if !COMPILE_WITHOUT_CSHARP -#if USE_MONO -#include -#endif +#if USE_CSHARP struct InternalInitData { - MonoArray* Values; - MonoObject* BaseModel; + MArray* Values; + MObject* BaseModel; }; struct InternalContext @@ -32,8 +30,8 @@ struct InternalContext int32 BoxId; float DeltaTime; uint64 CurrentFrameIndex; - MonoObject* BaseModel; - MonoObject* Instance; + MObject* BaseModel; + MObject* Instance; }; struct InternalImpulse @@ -57,7 +55,7 @@ DEFINE_INTERNAL_CALL(bool) AnimGraphInternal_HasConnection(InternalContext* cont return box->HasConnection(); } -DEFINE_INTERNAL_CALL(MonoObject*) AnimGraphInternal_GetInputValue(InternalContext* context, int32 boxId) +DEFINE_INTERNAL_CALL(MObject*) AnimGraphInternal_GetInputValue(InternalContext* context, int32 boxId) { const auto box = context->Node->TryGetBox(boxId); if (box == nullptr) @@ -85,16 +83,14 @@ DEFINE_INTERNAL_CALL(AnimGraphImpulse*) AnimGraphInternal_GetOutputImpulseData(I void AnimGraphExecutor::initRuntime() { -#if USE_MONO ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_HasConnection", &AnimGraphInternal_HasConnection); ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetInputValue", &AnimGraphInternal_GetInputValue); ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData", &AnimGraphInternal_GetOutputImpulseData); -#endif } void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value& value) { -#if USE_MONO +#if USE_CSHARP auto& context = Context.Get(); if (context.ValueCache.TryGet(boxBase, value)) return; @@ -120,7 +116,7 @@ void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value& internalContext.Instance = context.Data->Object ? context.Data->Object->GetOrCreateManagedInstance() : nullptr; // Peek managed object - const auto obj = MUtils::GetGCHandleTarget(data.Handle); + const auto obj = MCore::GCHandle::GetTarget(data.Handle); if (obj == nullptr) { LOG(Warning, "Custom node instance is null."); @@ -131,7 +127,7 @@ void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value& void* params[1]; params[0] = &internalContext; MObject* exception = nullptr; - MonoObject* result = data.Evaluate->Invoke(obj, params, &exception); + MObject* result = data.Evaluate->Invoke(obj, params, &exception); if (exception) { MException ex(exception); @@ -163,16 +159,14 @@ void AnimGraph::ClearCustomNode(Node* node) data.Evaluate = nullptr; if (data.Handle) { -#if USE_MONO - MUtils::FreeGCHandle(data.Handle); -#endif + MCore::GCHandle::Free(data.Handle); data.Handle = 0; } } bool AnimGraph::InitCustomNode(Node* node) { -#if USE_MONO +#if USE_CSHARP // Fetch the node logic controller type if (node->Values.Count() < 2 || node->Values[0].Type.Type != ValueType::String) { @@ -180,7 +174,7 @@ bool AnimGraph::InitCustomNode(Node* node) return false; } const StringView typeName(node->Values[0]); - const MString typeNameStd = typeName.ToStringAnsi(); + const StringAnsi typeNameStd = typeName.ToStringAnsi(); MClass* type = Scripting::FindClass(typeNameStd); if (type == nullptr) { @@ -203,18 +197,15 @@ bool AnimGraph::InitCustomNode(Node* node) } // Create node values managed array - if (mono_domain_get() == nullptr) - Scripting::GetScriptsDomain()->Dispatch(); - const auto values = mono_array_new(mono_domain_get(), mono_get_object_class(), node->Values.Count()); + MCore::Thread::Attach(); + MArray* values = MCore::Array::New( MCore::TypeCache::Object, node->Values.Count()); + MObject** valuesPtr = MCore::Array::GetAddress(values); for (int32 i = 0; i < node->Values.Count(); i++) - { - const auto v = MUtils::BoxVariant(node->Values[i]); - mono_array_set(values, MonoObject*, i, v); - } + valuesPtr[i] = MUtils::BoxVariant(node->Values[i]); // Allocate managed node object (create GC handle to prevent destruction) - const auto obj = type->CreateInstance(); - const auto handleGC = MUtils::NewGCHandle(obj, false); + MObject* obj = type->CreateInstance(); + const MGCHandle handleGC = MCore::GCHandle::New(obj, false); // Initialize node InternalInitData initData; @@ -226,7 +217,7 @@ bool AnimGraph::InitCustomNode(Node* node) load->Invoke(obj, params, &exception); if (exception) { - MUtils::FreeGCHandle(handleGC); + MCore::GCHandle::Free(handleGC); MException ex(exception); ex.Log(LogType::Warning, TEXT("AnimGraph")); diff --git a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp index dda6e6fcb..fa7999ce0 100644 --- a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp +++ b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.cpp @@ -13,12 +13,12 @@ #include "Engine/Renderer/RenderList.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/Script.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/ManagedCLR/MProperty.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" -#include "Engine/Scripting/ManagedCLR/MType.h" #include "Engine/Scripting/ManagedCLR/MField.h" #include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" // This could be Update, LateUpdate or FixedUpdate #define UPDATE_POINT Update @@ -260,7 +260,7 @@ void SceneAnimationPlayer::MapTrack(const StringView& from, const Guid& to) void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset) { -#if USE_MONO +#if USE_CSHARP // Restore all tracks for (int32 j = 0; j < anim->Tracks.Count(); j++) { @@ -364,7 +364,7 @@ void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset) bool SceneAnimationPlayer::TickPropertyTrack(int32 trackIndex, int32 stateIndexOffset, SceneAnimation* anim, float time, const SceneAnimation::Track& track, TrackInstance& state, void* target) { -#if USE_MONO +#if USE_CSHARP switch (track.Type) { case SceneAnimation::Track::Types::KeyframesProperty: @@ -511,7 +511,7 @@ bool SceneAnimationPlayer::TickPropertyTrack(int32 trackIndex, int32 stateIndexO // Return the value StringView str(keyframesValues[leftKey], keyframesLengths[leftKey]); - *(MonoString**)target = MUtils::ToString(str); + *(MString**)target = MUtils::ToString(str); break; } case SceneAnimation::Track::Types::StructProperty: @@ -528,10 +528,10 @@ bool SceneAnimationPlayer::TickPropertyTrack(int32 trackIndex, int32 stateIndexO // Cache field if (!childTrackState.Field) { - MType type = state.Property ? state.Property->GetType() : (state.Field ? state.Field->GetType() : MType()); + MType* type = state.Property ? state.Property->GetType() : (state.Field ? state.Field->GetType() : nullptr); if (!type) continue; - MClass* mclass = Scripting::FindClass(mono_type_get_class(type.GetNative())); + MClass* mclass = MCore::Type::GetClass(type); childTrackState.Field = mclass->GetField(childTrackRuntimeData->PropertyName); if (!childTrackState.Field) continue; @@ -556,7 +556,7 @@ bool SceneAnimationPlayer::TickPropertyTrack(int32 trackIndex, int32 stateIndexO void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int32 stateIndexOffset, CallStack& callStack) { -#if USE_MONO +#if USE_CSHARP const float fps = anim->FramesPerSecond; #if !BUILD_RELEASE || USE_EDITOR callStack.Add(anim); @@ -873,7 +873,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3 // Cache property or field if (!state.Property && !state.Field) { - MClass* mclass = Scripting::FindClass(mono_object_get_class(instance)); + MClass* mclass = MCore::Object::GetClass(instance); state.Property = mclass->GetProperty(runtimeData->PropertyName); if (!state.Property) { @@ -886,9 +886,8 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3 } // Get stack memory for data value - MType valueType = state.Property ? state.Property->GetType() : state.Field->GetType(); - int32 valueAlignment; - int32 valueSize = mono_type_stack_size(valueType.GetNative(), &valueAlignment); + MType* valueType = state.Property ? state.Property->GetType() : state.Field->GetType(); + int32 valueSize = MCore::Type::GetSize(valueType); _tracksDataStack.AddDefault(valueSize); void* value = &_tracksDataStack[_tracksDataStack.Count() - valueSize]; @@ -906,10 +905,10 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3 MException ex(exception); ex.Log(LogType::Error, TEXT("Property")); } - else if (!valueType.IsPointer()) + else if (!MCore::Type::IsPointer(valueType)) { if (boxed) - Platform::MemoryCopy(value, mono_object_unbox(boxed), valueSize); + Platform::MemoryCopy(value, MCore::Object::Unbox(boxed), valueSize); else Platform::MemoryClear(value, valueSize); } @@ -932,7 +931,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3 case SceneAnimation::Track::Types::StringProperty: { StringView str; - MUtils::ToString(*(MonoString**)value, str); + MUtils::ToString(*(MString**)value, str); _restoreData.Add((byte*)str.Get(), str.Length()); _restoreData.Add('\0'); break; @@ -957,7 +956,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3 if (TickPropertyTrack(j, stateIndexOffset, anim, time, track, state, value)) { // Set the value - if (valueType.IsPointer()) + if (MCore::Type::IsPointer(valueType)) value = (void*)*(intptr*)value; if (state.Property) { @@ -1027,7 +1026,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3 // Cache method if (!state.Method) { - state.Method = mono_class_get_method_from_name(mono_object_get_class(instance), runtimeData->EventName, runtimeData->EventParamsCount); + state.Method = MCore::Object::GetClass(instance)->FindMethod(runtimeData->EventName, runtimeData->EventParamsCount); if (!state.Method) break; } @@ -1035,7 +1034,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3 // Invoke the method Variant result; MObject* exception = nullptr; - mono_runtime_invoke((MonoMethod*)state.Method, instance, paramsData, &exception); + state.Method->Invoke(instance, paramsData, &exception); if (exception) { MException ex(exception); diff --git a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h index 46ebc918d..55cb35bb2 100644 --- a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h +++ b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h @@ -46,7 +46,7 @@ private: MObject* ManagedObject = nullptr; MProperty* Property = nullptr; MField* Field = nullptr; - void* Method = nullptr; + MMethod* Method = nullptr; int32 RestoreStateIndex = -1; bool Warn = true; diff --git a/Source/Engine/Content/Asset.cpp b/Source/Engine/Content/Asset.cpp index 88003725e..309a82e04 100644 --- a/Source/Engine/Content/Asset.cpp +++ b/Source/Engine/Content/Asset.cpp @@ -12,10 +12,7 @@ #include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Threading/MainThreadTask.h" #include "Engine/Threading/ConcurrentTaskQueue.h" -#if USE_MONO -#include "Engine/Scripting/ManagedCLR/MUtils.h" -#include -#endif +#include "Engine/Scripting/ManagedCLR/MCore.h" AssetReferenceBase::~AssetReferenceBase() { @@ -270,9 +267,7 @@ void Asset::OnManagedInstanceDeleted() // Cleanup if (_gcHandle) { -#if USE_MONO - MUtils::FreeGCHandle(_gcHandle); -#endif + MCore::GCHandle::Free(_gcHandle); _gcHandle = 0; } diff --git a/Source/Engine/Content/Assets/Texture.cpp b/Source/Engine/Content/Assets/Texture.cpp index 33154fae8..d796db914 100644 --- a/Source/Engine/Content/Assets/Texture.cpp +++ b/Source/Engine/Content/Assets/Texture.cpp @@ -7,7 +7,7 @@ #include "Engine/Platform/FileSystem.h" #include "Engine/Graphics/RenderTools.h" #include "Engine/Graphics/Textures/TextureData.h" -#include "Engine/Scripting/MainThreadManagedInvokeAction.h" +#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h" #include "Engine/Tools/TextureTool/TextureTool.h" REGISTER_BINARY_ASSET_WITH_UPGRADER(Texture, "FlaxEngine.Texture", TextureAssetUpgrader, true); diff --git a/Source/Engine/Content/Assets/VisualScript.cpp b/Source/Engine/Content/Assets/VisualScript.cpp index 932a611da..b11a2af96 100644 --- a/Source/Engine/Content/Assets/VisualScript.cpp +++ b/Source/Engine/Content/Assets/VisualScript.cpp @@ -5,14 +5,13 @@ #include "Engine/Core/Types/DataContainer.h" #include "Engine/Content/Content.h" #include "Engine/Content/Factories/BinaryAssetFactory.h" -#include "Engine/Scripting/MException.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/Events.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" #include "Engine/Scripting/ManagedCLR/MField.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" -#include "Engine/Scripting/ManagedCLR/MType.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Serialization/MemoryWriteStream.h" #include "Engine/Serialization/Serialization.h" @@ -310,15 +309,15 @@ void VisualScriptExecutor::ProcessGroupTools(Box* box, Node* node, Value& value) const StringAsANSI<100> typeNameAnsi(typeName.Get(), typeName.Length()); if (StringUtils::Compare(typeNameAnsi.Get(), obj.Type.GetTypeName()) != 0) { -#if USE_MONO - MonoClass* klass = Scripting::FindClassNative(StringAnsiView(typeNameAnsi.Get(), typeName.Length())); - MonoClass* objKlass = MUtils::GetClass(obj); - if (!klass || !objKlass || mono_class_is_subclass_of(objKlass, klass, false) == 0) +#if USE_CSHARP + MClass* klass = Scripting::FindClass(StringAnsiView(typeNameAnsi.Get(), typeName.Length())); + MClass* objKlass = MUtils::GetClass(obj); + if (!klass || !objKlass || !objKlass->IsSubClassOf(klass)) obj = Value::Null; #else const ScriptingTypeHandle type = Scripting::FindScriptingType(StringAnsiView(typeNameAnsi.Get(), typeName.Length())); const ScriptingTypeHandle objType = Scripting::FindScriptingType(obj.Type.GetTypeName()); - if (!type || !objType || objType.IsSubclassOf(type)) + if (!type || !objType || !objType.IsSubclassOf(type)) obj = Value::Null; #endif } diff --git a/Source/Engine/ContentImporters/CreateJson.cpp b/Source/Engine/ContentImporters/CreateJson.cpp index ed4926505..3ca21601c 100644 --- a/Source/Engine/ContentImporters/CreateJson.cpp +++ b/Source/Engine/ContentImporters/CreateJson.cpp @@ -30,7 +30,7 @@ bool CreateJson::Create(const StringView& path, rapidjson_flax::StringBuffer& da return Create(path, data1, data2); } -bool CreateJson::Create(const StringView& path, StringAnsiView& data, StringAnsiView& dataTypename) +bool CreateJson::Create(const StringView& path, const StringAnsiView& data, const StringAnsiView& dataTypename) { Guid id = Guid::New(); diff --git a/Source/Engine/ContentImporters/CreateJson.h b/Source/Engine/ContentImporters/CreateJson.h index c3a3da58d..abe119dd7 100644 --- a/Source/Engine/ContentImporters/CreateJson.h +++ b/Source/Engine/ContentImporters/CreateJson.h @@ -16,7 +16,7 @@ class CreateJson public: static bool Create(const StringView& path, rapidjson_flax::StringBuffer& data, const String& dataTypename); static bool Create(const StringView& path, rapidjson_flax::StringBuffer& data, const char* dataTypename); - static bool Create(const StringView& path, StringAnsiView& data, StringAnsiView& dataTypename); + static bool Create(const StringView& path, const StringAnsiView& data, const StringAnsiView& dataTypename); static CreateAssetResult ImportPo(CreateAssetContext& context); }; diff --git a/Source/Engine/Core/Types/String.h b/Source/Engine/Core/Types/String.h index a58dbf454..58d1dac68 100644 --- a/Source/Engine/Core/Types/String.h +++ b/Source/Engine/Core/Types/String.h @@ -17,6 +17,8 @@ protected: int32 _length = 0; public: + typedef T CharType; + /// /// Finalizes an instance of the class. /// diff --git a/Source/Engine/Core/Types/StringView.h b/Source/Engine/Core/Types/StringView.h index 1c841070e..8d2e1df9f 100644 --- a/Source/Engine/Core/Types/StringView.h +++ b/Source/Engine/Core/Types/StringView.h @@ -29,6 +29,8 @@ protected: } public: + typedef T CharType; + /// /// Gets the specific const character from this string. /// diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index 371fd1e99..6692aef6e 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -23,12 +23,10 @@ #include "Engine/Scripting/ScriptingObject.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MCore.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Utilities/Crc.h" #include "Engine/Utilities/StringConverter.h" -#if USE_MONO -#include -#endif namespace { @@ -108,15 +106,14 @@ VariantType::VariantType(Types type, const StringAnsiView& typeName) } } -VariantType::VariantType(Types type, _MonoClass* klass) +VariantType::VariantType(Types type, MClass* klass) { Type = type; TypeName = nullptr; -#if USE_MONO +#if USE_CSHARP if (klass) { - MString typeName; - MUtils::GetClassFullname(klass, typeName); + const StringAnsi& typeName = klass->GetFullName(); const int32 length = typeName.Length(); TypeName = static_cast(Allocator::Allocate(length + 1)); Platform::MemoryCopy(TypeName, typeName.Get(), length); @@ -166,7 +163,7 @@ VariantType::VariantType(const StringAnsiView& typeName) } // Try using managed class -#if USE_MONO +#if USE_CSHARP if (const auto mclass = Scripting::FindClass(typeName)) { new(this) VariantType(ManagedObject, typeName); @@ -615,21 +612,21 @@ Variant::Variant(Asset* v) } } -#if USE_MONO +#if USE_CSHARP -Variant::Variant(_MonoObject* v) - : Type(VariantType::ManagedObject, v ? mono_object_get_class(v) : nullptr) +Variant::Variant(MObject* v) + : Type(VariantType::ManagedObject, v ? MCore::Object::GetClass(v) : nullptr) { #if USE_NETCORE - AsUint64 = v ? MUtils::NewGCHandle(v, true) : 0; + AsUint64 = v ? MCore::GCHandle::New(v, true) : 0; #else - AsUint = v ? MUtils::NewGCHandle(v, true) : 0; + AsUint = v ? MCore::GCHandle::New(v, true) : 0; #endif } #else -Variant::Variant(_MonoObject* v) +Variant::Variant(MObject* v) : Type(VariantType::ManagedObject, nullptr) { AsUint = 0; @@ -964,13 +961,12 @@ Variant::~Variant() case VariantType::ManagedObject: #if USE_NETCORE if (AsUint64) - MUtils::FreeGCHandle(AsUint64); - break; + MCore::GCHandle::Free(AsUint64); #elif USE_MONO if (AsUint) - MUtils::FreeGCHandle(AsUint); - break; + MCore::GCHandle::Free(AsUint); #endif + break; default: ; } } @@ -1098,9 +1094,9 @@ Variant& Variant::operator=(const Variant& other) break; case VariantType::ManagedObject: #if USE_NETCORE - AsUint64 = other.AsUint64 ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint64), true) : 0; + AsUint64 = other.AsUint64 ? MCore::GCHandle::New(MCore::GCHandle::GetTarget(other.AsUint64), true) : 0; #elif USE_MONO - AsUint = other.AsUint ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint), true) : 0; + AsUint = other.AsUint ? MCore::GCHandle::New(MCore::GCHandle::GetTarget(other.AsUint), true) : 0; #endif break; case VariantType::Null: @@ -1226,9 +1222,13 @@ bool Variant::operator==(const Variant& other) const return false; return AsBlob.Length == other.AsBlob.Length && StringUtils::Compare(static_cast(AsBlob.Data), static_cast(other.AsBlob.Data), AsBlob.Length - 1) == 0; case VariantType::ManagedObject: -#if USE_MONO +#if USE_NETCORE // TODO: invoke C# Equality logic? - return AsUint == other.AsUint || MUtils::GetGCHandleTarget(AsUint) == MUtils::GetGCHandleTarget(other.AsUint); + return AsUint64 == other.AsUint64 || MCore::GCHandle::GetTarget(AsUint64) == MCore::GCHandle::GetTarget(other.AsUint64); +#elif USE_MONO + return AsUint == other.AsUint || MCore::GCHandle::GetTarget(AsUint) == MCore::GCHandle::GetTarget(other.AsUint); +#else + return nullptr; #endif default: return false; @@ -1320,9 +1320,11 @@ Variant::operator bool() const return AsAsset != nullptr; case VariantType::ManagedObject: #if USE_NETCORE - return AsUint64 != 0 && MUtils::GetGCHandleTarget(AsUint64) != nullptr; + return AsUint64 != 0 && MCore::GCHandle::GetTarget(AsUint64) != nullptr; #elif USE_MONO - return AsUint != 0 && MUtils::GetGCHandleTarget(AsUint) != nullptr; + return AsUint != 0 && MCore::GCHandle::GetTarget(AsUint) != nullptr; +#else + return nullptr; #endif default: return false; @@ -1592,9 +1594,11 @@ Variant::operator void*() const return AsBlob.Data; case VariantType::ManagedObject: #if USE_NETCORE - return AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr; + return AsUint64 ? MCore::GCHandle::GetTarget(AsUint64) : nullptr; #elif USE_MONO - return AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr; + return AsUint ? MCore::GCHandle::GetTarget(AsUint) : nullptr; +#else + return nullptr; #endif default: return nullptr; @@ -1636,12 +1640,12 @@ Variant::operator ScriptingObject*() const } } -Variant::operator _MonoObject*() const +Variant::operator MObject*() const { #if USE_NETCORE - return Type.Type == VariantType::ManagedObject && AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr; + return Type.Type == VariantType::ManagedObject && AsUint64 ? MCore::GCHandle::GetTarget(AsUint64) : nullptr; #elif USE_MONO - return Type.Type == VariantType::ManagedObject && AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr; + return Type.Type == VariantType::ManagedObject && AsUint ? MCore::GCHandle::GetTarget(AsUint) : nullptr; #else return nullptr; #endif @@ -2356,12 +2360,10 @@ void Variant::SetType(const VariantType& type) case VariantType::ManagedObject: #if USE_NETCORE if (AsUint64) - MUtils::FreeGCHandle(AsUint64); - break; + MCore::GCHandle::Free(AsUint64); #elif USE_MONO if (AsUint) - MUtils::FreeGCHandle(AsUint); - break; + MCore::GCHandle::Free(AsUint); #endif break; default: ; @@ -2471,12 +2473,10 @@ void Variant::SetType(VariantType&& type) case VariantType::ManagedObject: #if USE_NETCORE if (AsUint64) - MUtils::FreeGCHandle(AsUint64); - break; + MCore::GCHandle::Free(AsUint64); #elif USE_MONO if (AsUint) - MUtils::FreeGCHandle(AsUint); - break; + MCore::GCHandle::Free(AsUint); #endif break; default: ; @@ -2652,17 +2652,17 @@ void Variant::SetObject(ScriptingObject* object) object->Deleted.Bind(this); } -void Variant::SetManagedObject(_MonoObject* object) +void Variant::SetManagedObject(MObject* object) { -#if USE_MONO +#if USE_CSHARP if (object) { if (Type.Type != VariantType::ManagedObject) - SetType(VariantType(VariantType::ManagedObject, mono_object_get_class(object))); + SetType(VariantType(VariantType::ManagedObject, MCore::Object::GetClass(object))); #if USE_NETCORE - AsUint64 = MUtils::NewGCHandle(object, true); + AsUint64 = MCore::GCHandle::New(object, true); #else - AsUint = MUtils::NewGCHandle(object, true); + AsUint = MCore::GCHandle::New(object, true); #endif } else @@ -2783,9 +2783,11 @@ String Variant::ToString() const return String((const char*)AsBlob.Data, AsBlob.Length ? AsBlob.Length - 1 : 0); case VariantType::ManagedObject: #if USE_NETCORE - return AsUint64 ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint64), nullptr))) : TEXT("null"); + return AsUint64 ? String(MUtils::ToString(MCore::Object::ToString(MCore::GCHandle::GetTarget(AsUint64)))) : TEXT("null"); #elif USE_MONO - return AsUint ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint), nullptr))) : TEXT("null"); + return AsUint ? String(MUtils::ToString(MCore::Object::ToString(MCore::GCHandle::GetTarget(AsUint)))) : TEXT("null"); +#else + return String::Empty; #endif default: return String::Empty; @@ -3688,17 +3690,17 @@ void Variant::AllocStructure() AsBlob.Data = Allocator::Allocate(AsBlob.Length); *((int16*)AsBlob.Data) = 0; } -#if USE_MONO +#if USE_CSHARP else if (const auto mclass = Scripting::FindClass(typeName)) { // Fallback to C#-only types - MCore::AttachThread(); - auto instance = mclass->CreateInstance(); + MCore::Thread::Attach(); + MObject* instance = mclass->CreateInstance(); if (instance) { #if 0 - void* data = mono_object_unbox(instance); - int32 instanceSize = mono_class_instance_size(mclass->GetNative()); + void* data = MCore::Object::Unbox(instance); + int32 instanceSize = mclass->GetInstanceSize(); AsBlob.Length = instanceSize - (int32)((uintptr)data - (uintptr)instance); AsBlob.Data = Allocator::Allocate(AsBlob.Length); Platform::MemoryCopy(AsBlob.Data, data, AsBlob.Length); @@ -3706,9 +3708,9 @@ void Variant::AllocStructure() Type.Type = VariantType::ManagedObject; #if USE_NETCORE - AsUint64 = MUtils::NewGCHandle(instance, true); + AsUint64 = MCore::GCHandle::New(instance, true); #else - AsUint = MUtils::NewGCHandle(instance, true); + AsUint = MCore::GCHandle::New(instance, true); #endif #endif } @@ -3802,9 +3804,11 @@ uint32 GetHash(const Variant& key) return GetHash((const char*)key.AsBlob.Data); case VariantType::ManagedObject: #if USE_NETCORE - return key.AsUint64 ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint64)) : 0; + return key.AsUint64 ? (uint32)MCore::Object::GetHashCode(MCore::GCHandle::GetTarget(key.AsUint64)) : 0; #elif USE_MONO - return key.AsUint ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint)) : 0; + return key.AsUint ? (uint32)MCore::Object::GetHashCode(MCore::GCHandle::GetTarget(key.AsUint)) : 0; +#else + return 0; #endif default: return 0; diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index c50854707..7745307c3 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -3,10 +3,9 @@ #pragma once #include "Engine/Core/Types/String.h" +#include "Engine/Scripting/Types.h" class Asset; -class ScriptingObject; -struct ScriptingType; struct Transform; struct CommonValue; template @@ -105,7 +104,7 @@ public: explicit VariantType(Types type, const StringView& typeName); explicit VariantType(Types type, const StringAnsiView& typeName); - explicit VariantType(Types type, struct _MonoClass* klass); + explicit VariantType(Types type, MClass* klass); explicit VariantType(const StringAnsiView& typeName); VariantType(const VariantType& other); VariantType(VariantType&& other) noexcept; @@ -215,7 +214,7 @@ public: Variant(void* v); Variant(ScriptingObject* v); Variant(Asset* v); - Variant(struct _MonoObject* v); + Variant(MObject* v); Variant(const StringView& v); Variant(const StringAnsiView& v); Variant(const Char* v); @@ -296,7 +295,7 @@ public: explicit operator StringView() const; // Returned StringView, if not empty, is guaranteed to point to a null terminated buffer. explicit operator StringAnsiView() const; // Returned StringView, if not empty, is guaranteed to point to a null terminated buffer. explicit operator ScriptingObject*() const; - explicit operator struct _MonoObject*() const; + explicit operator MObject*() const; explicit operator Asset*() const; explicit operator Float2() const; explicit operator Float3() const; @@ -356,7 +355,7 @@ public: void SetBlob(int32 length); void SetBlob(const void* data, int32 length); void SetObject(ScriptingObject* object); - void SetManagedObject(struct _MonoObject* object); + void SetManagedObject(MObject* object); void SetAsset(Asset* asset); String ToString() const; diff --git a/Source/Engine/Debug/DebugLog.cpp b/Source/Engine/Debug/DebugLog.cpp index a250a7fe3..da867f0a1 100644 --- a/Source/Engine/Debug/DebugLog.cpp +++ b/Source/Engine/Debug/DebugLog.cpp @@ -3,17 +3,15 @@ #include "DebugLog.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/BinaryModule.h" -#include "Engine/Scripting/MainThreadManagedInvokeAction.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Scripting/ManagedCLR/MDomain.h" #include "Engine/Scripting/ManagedCLR/MAssembly.h" #include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h" #include "Engine/Threading/Threading.h" #include "FlaxEngine.Gen.h" -#if USE_MONO - -#include -#include +#if USE_CSHARP namespace Impl { @@ -68,19 +66,19 @@ bool CacheMethods() void DebugLog::Log(LogType type, const StringView& message) { -#if USE_MONO +#if USE_CSHARP if (CacheMethods()) return; auto scriptsDomain = Scripting::GetScriptsDomain(); MainThreadManagedInvokeAction::ParamsBuilder params; params.AddParam(type); - params.AddParam(message, scriptsDomain->GetNative()); + params.AddParam(message, scriptsDomain); #if BUILD_RELEASE - params.AddParam(StringView::Empty, scriptsDomain->GetNative()); + params.AddParam(StringView::Empty, scriptsDomain); #else const String stackTrace = Platform::GetStackTrace(1); - params.AddParam(stackTrace, scriptsDomain->GetNative()); + params.AddParam(stackTrace, scriptsDomain); #endif MainThreadManagedInvokeAction::Invoke(Internal_SendLog, params); #endif @@ -88,7 +86,7 @@ void DebugLog::Log(LogType type, const StringView& message) void DebugLog::LogException(MObject* exceptionObject) { -#if USE_MONO +#if USE_CSHARP if (exceptionObject == nullptr || CacheMethods()) return; @@ -101,11 +99,11 @@ void DebugLog::LogException(MObject* exceptionObject) String DebugLog::GetStackTrace() { String result; -#if USE_MONO +#if USE_CSHARP if (!CacheMethods()) { auto stackTraceObj = Internal_GetStackTrace->Invoke(nullptr, nullptr, nullptr); - MUtils::ToString((MonoString*)stackTraceObj, result); + MUtils::ToString((MString*)stackTraceObj, result); } #endif return result; @@ -113,10 +111,9 @@ String DebugLog::GetStackTrace() void DebugLog::ThrowException(const char* msg) { -#if USE_MONO - // Throw exception to the C# world - auto ex = mono_exception_from_name_msg(mono_get_corlib(), "System", "Exception", msg); - mono_raise_exception(ex); +#if USE_CSHARP + auto ex = MCore::Exception::Get(msg); + MCore::Exception::Throw(ex); #endif } @@ -125,45 +122,40 @@ void DebugLog::ThrowNullReference() //LOG(Warning, "Invalid null reference."); //LOG_STR(Warning, DebugLog::GetStackTrace()); -#if USE_MONO - // Throw exception to the C# world - auto ex = mono_get_exception_null_reference(); - mono_raise_exception(ex); +#if USE_CSHARP + auto ex = MCore::Exception::GetNullReference(); + MCore::Exception::Throw(ex); #endif } void DebugLog::ThrowArgument(const char* arg, const char* msg) { -#if USE_MONO - // Throw exception to the C# world - auto ex = mono_get_exception_argument(arg, msg); - mono_raise_exception(ex); +#if USE_CSHARP + auto ex = MCore::Exception::GetArgument(arg, msg); + MCore::Exception::Throw(ex); #endif } void DebugLog::ThrowArgumentNull(const char* arg) { -#if USE_MONO - // Throw exception to the C# world - auto ex = mono_get_exception_argument_null(arg); - mono_raise_exception(ex); +#if USE_CSHARP + auto ex = MCore::Exception::GetArgumentNull(arg); + MCore::Exception::Throw(ex); #endif } void DebugLog::ThrowArgumentOutOfRange(const char* arg) { -#if USE_MONO - // Throw exception to the C# world - auto ex = mono_get_exception_argument_out_of_range(arg); - mono_raise_exception(ex); +#if USE_CSHARP + auto ex = MCore::Exception::GetArgumentOutOfRange(arg); + MCore::Exception::Throw(ex); #endif } void DebugLog::ThrowNotSupported(const char* msg) { -#if USE_MONO - // Throw exception to the C# world - auto ex = mono_get_exception_not_supported(msg); - mono_raise_exception(ex); +#if USE_CSHARP + auto ex = MCore::Exception::GetNotSupported(msg); + MCore::Exception::Throw(ex); #endif } diff --git a/Source/Engine/Debug/Exceptions/CLRInnerException.h b/Source/Engine/Debug/Exceptions/CLRInnerException.h index 919739d57..a46f289f0 100644 --- a/Source/Engine/Debug/Exceptions/CLRInnerException.h +++ b/Source/Engine/Debug/Exceptions/CLRInnerException.h @@ -24,15 +24,15 @@ namespace Log /// /// Creates default exception with additional data /// - /// Additional information that help describe error + /// Additional information that help describe error CLRInnerException(const String& additionalInfo) : Exception(String::Format(TEXT("Current {0} CLR method has thrown an inner exception"), #if USE_MONO - TEXT("Mono") + TEXT("Mono") #elif USE_CORECLR - TEXT(".NET Core") + TEXT(".NET Core") #else - TEXT("Unknown engine") + TEXT("Unknown engine") #endif ), additionalInfo) { diff --git a/Source/Engine/Engine/Engine.cpp b/Source/Engine/Engine/Engine.cpp index 467e3fa36..07038f146 100644 --- a/Source/Engine/Engine/Engine.cpp +++ b/Source/Engine/Engine/Engine.cpp @@ -39,7 +39,7 @@ #include "Engine/Scripting/ManagedCLR/MAssembly.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Core/Config/PlatformSettings.h" #endif @@ -547,7 +547,7 @@ void EngineImpl::InitPaths() #endif #if USE_EDITOR Globals::EngineContentFolder = Globals::StartupFolder / TEXT("Content"); -#if USE_MONO && !USE_NETCORE +#if USE_MONO #if PLATFORM_WINDOWS Globals::MonoPath = Globals::StartupFolder / TEXT("Source/Platforms/Editor/Windows/Mono"); #elif PLATFORM_LINUX @@ -559,7 +559,7 @@ void EngineImpl::InitPaths() #endif #endif #else -#if USE_MONO && !USE_NETCORE +#if USE_MONO Globals::MonoPath = Globals::StartupFolder / TEXT("Mono"); #endif #endif diff --git a/Source/Engine/Engine/Globals.cpp b/Source/Engine/Engine/Globals.cpp index 6c2b9c2fe..d08aa5b5b 100644 --- a/Source/Engine/Engine/Globals.cpp +++ b/Source/Engine/Engine/Globals.cpp @@ -15,7 +15,7 @@ String Globals::EngineContentFolder; String Globals::ProjectSourceFolder; #endif String Globals::ProjectContentFolder; -#if USE_MONO && !USE_NETCORE +#if USE_MONO String Globals::MonoPath; #endif bool Globals::FatalErrorOccurred; diff --git a/Source/Engine/Engine/Globals.h b/Source/Engine/Engine/Globals.h index 2af714158..a303590de 100644 --- a/Source/Engine/Engine/Globals.h +++ b/Source/Engine/Engine/Globals.h @@ -49,7 +49,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Globals); // Project content directory path API_FIELD(ReadOnly) static String ProjectContentFolder; -#if USE_MONO && !USE_NETCORE +#if USE_MONO // Mono library folder path API_FIELD(ReadOnly) static String MonoPath; #endif diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index f5a0100aa..c97848ed9 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -64,14 +64,6 @@ namespace FlaxEngine internal uint setterAttributes; } - [StructLayout(LayoutKind.Sequential)] - internal struct NativeAttributeDefinitions - { - internal IntPtr name; - internal ManagedHandle attributeHandle; - internal ManagedHandle attributeTypeHandle; - } - [StructLayout(LayoutKind.Explicit)] public struct VariantNative { @@ -245,7 +237,9 @@ namespace FlaxEngine elementSize = Marshal.SizeOf(elementType); } - private ManagedArray() { } + private ManagedArray() + { + } private ManagedArray(IntPtr ptr, int length, Type elementType) => Allocate(ptr, length, elementType); @@ -294,7 +288,9 @@ namespace FlaxEngine private static class ArrayCast { delegate Array GetDelegate(Span span); - [ThreadStatic] private static Dictionary delegates; + + [ThreadStatic] + private static Dictionary delegates; internal static Array ToArray(Span span, Type type) { @@ -322,7 +318,8 @@ namespace FlaxEngine /// private static class ManagedArrayPool { - [ThreadStatic] private static List> pool; + [ThreadStatic] + private static List> pool; internal static ManagedArray Get() { @@ -374,7 +371,7 @@ namespace FlaxEngine else if (str == string.Empty) return ManagedHandle.ToIntPtr(EmptyStringHandle); Assert.IsTrue(str.Length > 0); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(str)); + return ManagedHandle.ToIntPtr(str); } [System.Diagnostics.DebuggerStepThrough] @@ -385,7 +382,7 @@ namespace FlaxEngine else if (str == string.Empty) return ManagedHandle.ToIntPtr(EmptyStringHandle); Assert.IsTrue(str.Length > 0); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(str, GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(str, GCHandleType.Weak); } [System.Diagnostics.DebuggerStepThrough] @@ -459,6 +456,12 @@ namespace FlaxEngine [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator IntPtr(ManagedHandle value) => ToIntPtr(value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IntPtr ToIntPtr(object value) => ManagedHandlePool.AllocateHandle(value, GCHandleType.Normal); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IntPtr ToIntPtr(object value, GCHandleType type) => ManagedHandlePool.AllocateHandle(value, type); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr ToIntPtr(ManagedHandle value) => value.handle; @@ -624,14 +627,17 @@ namespace FlaxEngine public static class NativeToManaged { public static object ConvertToManaged(IntPtr unmanaged) => unmanaged == IntPtr.Zero ? null : ManagedHandle.FromIntPtr(unmanaged).Target; + public static void Free(IntPtr unmanaged) { // This is a permanent handle, do not release it } } + public static class ManagedToNative { - public static IntPtr ConvertToUnmanaged(object managed) => managed != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed)) : IntPtr.Zero; + public static IntPtr ConvertToUnmanaged(object managed) => managed != null ? ManagedHandle.ToIntPtr(managed) : IntPtr.Zero; + public static void Free(IntPtr unmanaged) { if (unmanaged == IntPtr.Zero) @@ -639,14 +645,35 @@ namespace FlaxEngine ManagedHandle.FromIntPtr(unmanaged).Free(); } } + public struct Bidirectional { object managed; IntPtr unmanaged; - public void FromManaged(object managed) { this.managed = managed; } - public IntPtr ToUnmanaged() { unmanaged = ManagedHandleMarshaller.ToNative(managed); return unmanaged; } - public void FromUnmanaged(IntPtr unmanaged) { this.unmanaged = unmanaged; } - public object ToManaged() { managed = ManagedHandleMarshaller.ToManaged(unmanaged); unmanaged = IntPtr.Zero; return managed; } + + public void FromManaged(object managed) + { + this.managed = managed; + } + + public IntPtr ToUnmanaged() + { + unmanaged = ManagedHandleMarshaller.ToNative(managed); + return unmanaged; + } + + public void FromUnmanaged(IntPtr unmanaged) + { + this.unmanaged = unmanaged; + } + + public object ToManaged() + { + managed = ManagedHandleMarshaller.ToManaged(unmanaged); + unmanaged = IntPtr.Zero; + return managed; + } + public void Free() { // FIXME, might be a permanent handle or a temporary one @@ -656,10 +683,12 @@ namespace FlaxEngine unmanaged.Free();*/ } } + public static object ConvertToManaged(IntPtr unmanaged) => ToManaged(unmanaged); public static IntPtr ConvertToUnmanaged(object managed) => ToNative(managed); public static object ToManaged(IntPtr managed) => managed != IntPtr.Zero ? ManagedHandle.FromIntPtr(managed).Target : null; - public static IntPtr ToNative(object managed) => managed != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed)) : IntPtr.Zero; + public static IntPtr ToNative(object managed) => managed != null ? ManagedHandle.ToIntPtr(managed) : IntPtr.Zero; + public static void Free(IntPtr unmanaged) { if (unmanaged == IntPtr.Zero) @@ -707,9 +736,10 @@ namespace FlaxEngine { public static FlaxEngine.Object ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As(ManagedHandle.FromIntPtr(unmanaged).Target) : null; } + public static class ManagedToNative { - public static IntPtr ConvertToUnmanaged(FlaxEngine.Object managed) => managed != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed)) : IntPtr.Zero; + public static IntPtr ConvertToUnmanaged(FlaxEngine.Object managed) => managed != null ? ManagedHandle.ToIntPtr(managed) : IntPtr.Zero; } } @@ -801,6 +831,7 @@ namespace FlaxEngine public static Dictionary ConvertToManaged(IntPtr unmanaged) => DictionaryMarshaller.ToManaged(unmanaged); public static void Free(IntPtr unmanaged) => DictionaryMarshaller.Free(unmanaged); } + public static class ManagedToNative { public static IntPtr ConvertToUnmanaged(Dictionary managed) => DictionaryMarshaller.ToNative(managed); @@ -833,10 +864,11 @@ namespace FlaxEngine } public static Dictionary ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As>(ManagedHandle.FromIntPtr(unmanaged).Target) : null; - public static IntPtr ConvertToUnmanaged(Dictionary managed) => managed != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed)) : IntPtr.Zero; + public static IntPtr ConvertToUnmanaged(Dictionary managed) => managed != null ? ManagedHandle.ToIntPtr(managed) : IntPtr.Zero; public static Dictionary ToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As>(ManagedHandle.FromIntPtr(unmanaged).Target) : null; - public static IntPtr ToNative(Dictionary managed) => managed != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed)) : IntPtr.Zero; + public static IntPtr ToNative(Dictionary managed) => managed != null ? ManagedHandle.ToIntPtr(managed) : IntPtr.Zero; + public static void Free(IntPtr unmanaged) { if (unmanaged != IntPtr.Zero) @@ -904,7 +936,7 @@ namespace FlaxEngine } numElements = managed.Length; ManagedArray managedArray = ManagedArray.AllocatePooledArray(managed.Length); - var ptr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managedArray)); + var ptr = ManagedHandle.ToIntPtr(managedArray); return (TUnmanagedElement*)ptr; } @@ -988,7 +1020,7 @@ namespace FlaxEngine } numElements = managed.Length; ManagedArray managedArray = ManagedArray.AllocatePooledArray(managed.Length); - IntPtr handle = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managedArray)); + IntPtr handle = ManagedHandle.ToIntPtr(managedArray); return (TUnmanagedElement*)handle; } @@ -1045,9 +1077,7 @@ namespace FlaxEngine { public static unsafe IntPtr ConvertToUnmanaged(string managed) { - if (managed == null) - return IntPtr.Zero; - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed)); + return managed == null ? IntPtr.Zero : ManagedHandle.ToIntPtr(managed); } public static void Free(IntPtr unmanaged) => ManagedString.Free(unmanaged); @@ -1091,7 +1121,7 @@ namespace FlaxEngine /// /// Provides a Mono-like API for native code to access managed runtime. /// - internal unsafe static partial class NativeInterop + internal static unsafe partial class NativeInterop { internal static Dictionary AssemblyLocations = new(); @@ -1164,15 +1194,21 @@ namespace FlaxEngine } [UnmanagedCallersOnly] - internal static void* AllocMemory(int size) + internal static void* AllocMemory(int size, bool coTaskMem) { - return NativeMemory.AlignedAlloc((UIntPtr)size, 16); + if (coTaskMem) + return Marshal.AllocCoTaskMem(size).ToPointer(); + else + return NativeMemory.AlignedAlloc((UIntPtr)size, 16); } [UnmanagedCallersOnly] - internal static void FreeMemory(void* ptr) + internal static void FreeMemory(void* ptr, bool coTaskMem) { - NativeMemory.AlignedFree(ptr); + if (coTaskMem) + Marshal.FreeCoTaskMem(new IntPtr(ptr)); + else + NativeMemory.AlignedFree(ptr); } internal static void* NativeAlloc(int byteCount) @@ -1220,7 +1256,7 @@ namespace FlaxEngine { var obj = array.GetValue(i); if (obj != null) - pointerArray.SetValue(ManagedHandle.ToIntPtr(ManagedHandle.Alloc(obj)), i); + pointerArray.SetValue(ManagedHandle.ToIntPtr(obj), i); } return pointerArray; } @@ -1320,11 +1356,18 @@ namespace FlaxEngine return FindType(internalAssemblyQualifiedName); } - internal class ReferenceTypePlaceholder { } - internal struct ValueTypePlaceholder { } + internal class ReferenceTypePlaceholder + { + } + + internal struct ValueTypePlaceholder + { + } internal delegate object MarshalToManagedDelegate(IntPtr nativePtr, bool byRef); + internal delegate void MarshalToNativeDelegate(object managedObject, IntPtr nativePtr); + internal delegate void MarshalToNativeFieldDelegate(FieldInfo field, object fieldOwner, IntPtr nativePtr, out int fieldOffset); internal static ConcurrentDictionary toManagedMarshallers = new ConcurrentDictionary(1, 3); @@ -1395,7 +1438,9 @@ namespace FlaxEngine internal static class MarshalHelper { private delegate void MarshalToNativeTypedDelegate(ref T managedValue, IntPtr nativePtr); + private delegate void MarshalToManagedTypedDelegate(ref T managedValue, IntPtr nativePtr, bool byRef); + internal delegate void MarshalFieldTypedDelegate(FieldInfo field, ref T fieldOwner, IntPtr fieldPtr, out int fieldOffset); internal static FieldInfo[] marshallableFields; @@ -1604,7 +1649,8 @@ namespace FlaxEngine fieldType = typeof(byte); if (fieldType.IsValueType && !fieldType.IsEnum && !fieldType.IsPrimitive) // Is it a structure? - { } + { + } else if (fieldType.IsClass || fieldType.IsPointer) fieldAlignment = IntPtr.Size; else @@ -1816,7 +1862,7 @@ namespace FlaxEngine else if (managedValue is FlaxEngine.Object flaxObj) managedPtr = FlaxEngine.Object.GetUnmanagedPtr(flaxObj); else - managedPtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managedValue, GCHandleType.Weak)); + managedPtr = ManagedHandle.ToIntPtr(managedValue, GCHandleType.Weak); } else if (type == typeof(Type)) managedPtr = managedValue != null ? ManagedHandle.ToIntPtr(GetTypeGCHandle((Type)(object)managedValue)) : IntPtr.Zero; @@ -1845,11 +1891,11 @@ namespace FlaxEngine } else managedArray = ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(arr)); - managedPtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managedArray, GCHandleType.Weak)); + managedPtr = ManagedHandle.ToIntPtr(managedArray, GCHandleType.Weak); } } else - managedPtr = managedValue != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managedValue, GCHandleType.Weak)) : IntPtr.Zero; + managedPtr = managedValue != null ? ManagedHandle.ToIntPtr(managedValue, GCHandleType.Weak) : IntPtr.Zero; Unsafe.Write(nativePtr.ToPointer(), managedPtr); } @@ -1859,12 +1905,14 @@ namespace FlaxEngine { internal Type[] parameterTypes; internal MethodInfo method; + internal Type returnType; private Invoker.MarshalAndInvokeDelegate invokeDelegate; private object delegInvoke; internal MethodHolder(MethodInfo method) { this.method = method; + returnType = method.ReturnType; parameterTypes = method.GetParameterTypes(); } @@ -1875,8 +1923,8 @@ namespace FlaxEngine List methodTypes = new List(); if (!method.IsStatic) methodTypes.Add(method.DeclaringType); - if (method.ReturnType != typeof(void)) - methodTypes.Add(method.ReturnType); + if (returnType != typeof(void)) + methodTypes.Add(returnType); methodTypes.AddRange(parameterTypes); List genericParamTypes = new List(); @@ -1890,7 +1938,7 @@ namespace FlaxEngine genericParamTypes.Add(type); } - string invokerTypeName = $"FlaxEngine.NativeInterop+Invoker+Invoker{(method.IsStatic ? "Static" : "")}{(method.ReturnType != typeof(void) ? "Ret" : "NoRet")}{parameterTypes.Length}{(genericParamTypes.Count > 0 ? "`" + genericParamTypes.Count : "")}"; + string invokerTypeName = $"FlaxEngine.NativeInterop+Invoker+Invoker{(method.IsStatic ? "Static" : "")}{(returnType != typeof(void) ? "Ret" : "NoRet")}{parameterTypes.Length}{(genericParamTypes.Count > 0 ? "`" + genericParamTypes.Count : "")}"; Type invokerType = Type.GetType(invokerTypeName); if (invokerType != null) { @@ -1903,7 +1951,6 @@ namespace FlaxEngine outDeleg = invokeDelegate; outDelegInvoke = delegInvoke; - return outDeleg != null; } } @@ -1986,10 +2033,8 @@ namespace FlaxEngine var methods = new List(); var staticMethods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); var instanceMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); - foreach (MethodInfo method in staticMethods) - methods.Add(method); - foreach (MethodInfo method in instanceMethods) - methods.Add(method); + methods.AddRange(staticMethods); + methods.AddRange(instanceMethods); var arr = (NativeMethodDefinitions*)NativeAlloc(methods.Count, Unsafe.SizeOf()); for (int i = 0; i < methods.Count; i++) @@ -2085,42 +2130,42 @@ namespace FlaxEngine } [UnmanagedCallersOnly] - internal static void GetClassAttributes(ManagedHandle typeHandle, NativeAttributeDefinitions** classAttributes, int* classAttributesCount) + internal static void GetClassAttributes(ManagedHandle typeHandle, ManagedHandle** classAttributes, int* classAttributesCount) { Type type = Unsafe.As(typeHandle.Target); object[] attributeValues = type.GetCustomAttributes(false); - Type[] attributeTypes = type.GetCustomAttributes(false).Select(x => x.GetType()).ToArray(); - NativeAttributeDefinitions* arr = (NativeAttributeDefinitions*)NativeAlloc(attributeTypes.Length, Unsafe.SizeOf()); - for (int i = 0; i < attributeTypes.Length; i++) + ManagedHandle* arr = (ManagedHandle*)NativeAlloc(attributeValues.Length, Unsafe.SizeOf()); + for (int i = 0; i < attributeValues.Length; i++) { - IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf() * i); - if (!classAttributesCacheCollectible.TryGetValue(attributeValues[i], out ManagedHandle attributeHandle)) { attributeHandle = ManagedHandle.Alloc(attributeValues[i]); classAttributesCacheCollectible.Add(attributeValues[i], attributeHandle); } - ManagedHandle attributeTypeHandle = GetTypeGCHandle(attributeTypes[i]); - - NativeAttributeDefinitions classAttribute = new NativeAttributeDefinitions() - { - name = NativeAllocStringAnsi(attributeTypes[i].Name), - attributeTypeHandle = attributeTypeHandle, - attributeHandle = attributeHandle, - }; - Unsafe.Write(ptr.ToPointer(), classAttribute); + arr[i] = attributeHandle; } *classAttributes = arr; - *classAttributesCount = attributeTypes.Length; + *classAttributesCount = attributeValues.Length; } [UnmanagedCallersOnly] - internal static ManagedHandle GetCustomAttribute(ManagedHandle typeHandle, ManagedHandle attribHandle) + internal static ManagedHandle GetCustomAttribute(ManagedHandle typeHandle, ManagedHandle attributeHandle) { Type type = Unsafe.As(typeHandle.Target); - Type attribType = Unsafe.As(attribHandle.Target); - object attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x.GetType() == attribType); + var attributes = type.GetCustomAttributes(false); + object attrib; + if (attributeHandle.IsAllocated) + { + // Check for certain attribute type + Type attributeType = Unsafe.As(attributeHandle.Target); + attrib = attributes.FirstOrDefault(x => x.GetType() == attributeType); + } + else + { + // Check if has any attribute + attrib = attributes.FirstOrDefault(); + } if (attrib != null) return ManagedHandle.Alloc(attrib, GCHandleType.Weak); return new ManagedHandle(); @@ -2192,7 +2237,7 @@ namespace FlaxEngine internal static ManagedHandle GetMethodReturnType(ManagedHandle methodHandle) { MethodHolder methodHolder = Unsafe.As(methodHandle.Target); - Type returnType = methodHolder.method.ReturnType; + Type returnType = methodHolder.returnType; return GetTypeGCHandle(returnType); } @@ -2201,7 +2246,7 @@ namespace FlaxEngine internal static void GetMethodParameterTypes(ManagedHandle methodHandle, IntPtr* typeHandles) { MethodHolder methodHolder = Unsafe.As(methodHandle.Target); - Type returnType = methodHolder.method.ReturnType; + Type returnType = methodHolder.returnType; IntPtr arr = (IntPtr)NativeAlloc(methodHolder.parameterTypes.Length, IntPtr.Size); for (int i = 0; i < methodHolder.parameterTypes.Length; i++) { @@ -2292,26 +2337,25 @@ namespace FlaxEngine if (marshalledType.IsValueType) { ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, marshalledType); - return ManagedHandle.Alloc(managedArray/*, GCHandleType.Weak*/); + return ManagedHandle.Alloc(managedArray); } else { Array arr = ArrayFactory.CreateArray(type, size); ManagedArray managedArray = ManagedArray.WrapNewArray(arr); - return ManagedHandle.Alloc(managedArray/*, GCHandleType.Weak*/); + return ManagedHandle.Alloc(managedArray); } } [UnmanagedCallersOnly] - internal static unsafe IntPtr GetArrayPointerToElement(ManagedHandle arrayHandle, int size, int index) + internal static unsafe IntPtr GetArrayPointer(ManagedHandle arrayHandle) { if (!arrayHandle.IsAllocated) return IntPtr.Zero; ManagedArray managedArray = Unsafe.As(arrayHandle.Target); if (managedArray.Length == 0) return IntPtr.Zero; - Assert.IsTrue(index >= 0 && index < managedArray.Length); - return IntPtr.Add(managedArray.Pointer, size * index); + return managedArray.Pointer; } [UnmanagedCallersOnly] @@ -2335,12 +2379,6 @@ namespace FlaxEngine return ManagedString.ToNativeWeak(new string(new ReadOnlySpan(text, length))); } - [UnmanagedCallersOnly] - internal static IntPtr NewString(sbyte* text) - { - return ManagedString.ToNativeWeak(new string(text)); - } - [UnmanagedCallersOnly] internal static IntPtr NewStringLength(sbyte* text, int length) { @@ -2370,6 +2408,7 @@ namespace FlaxEngine { private static ConcurrentDictionary unboxers = new ConcurrentDictionary(1, 3); private static MethodInfo unboxerMethod = typeof(ValueTypeUnboxer).GetMethod(nameof(ValueTypeUnboxer.UnboxPointer), BindingFlags.Static | BindingFlags.NonPublic); + private delegate IntPtr UnboxerDelegate(object value); private static UnboxerDelegate UnboxerDelegateFactory(Type type) @@ -2395,7 +2434,7 @@ namespace FlaxEngine /// Returns the address of the boxed value type. /// [UnmanagedCallersOnly] - internal unsafe static IntPtr UnboxValue(ManagedHandle handle) + internal static unsafe IntPtr UnboxValue(ManagedHandle handle) { object value = handle.Target; Type type = value.GetType(); @@ -2418,7 +2457,6 @@ namespace FlaxEngine { object obj = objectHandle.Target; Type type = obj.GetType(); - ConstructorInfo ctor = type.GetMember(".ctor", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).First() as ConstructorInfo; ctor.Invoke(obj, null); } @@ -2438,7 +2476,7 @@ namespace FlaxEngine catch (Exception exception) { if (exceptionPtr != IntPtr.Zero) - Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(ManagedHandle.Alloc(exception, GCHandleType.Weak))); + Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(exception, GCHandleType.Weak)); return IntPtr.Zero; } return returnValue; @@ -2468,7 +2506,7 @@ namespace FlaxEngine realException = exception.InnerException; if (exceptionPtr != IntPtr.Zero) - Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(ManagedHandle.Alloc(realException, GCHandleType.Weak))); + Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(realException, GCHandleType.Weak)); else throw realException; return IntPtr.Zero; @@ -2486,7 +2524,7 @@ namespace FlaxEngine } // Return value - return Invoker.MarshalReturnValueGeneric(methodHolder.method.ReturnType, returnObject); + return Invoker.MarshalReturnValueGeneric(methodHolder.returnType, returnObject); } } @@ -2498,7 +2536,7 @@ namespace FlaxEngine MethodHolder methodHolder = Unsafe.As(methodHandle.Target); // Wrap the method call, this is needed to get the object instance from ManagedHandle and to pass the exception back to native side - ThunkContext context = new ThunkContext(methodHolder.method); + ThunkContext context = new ThunkContext((MethodInfo)methodHolder.method); Delegate methodDelegate = typeof(ThunkContext).GetMethod(nameof(ThunkContext.InvokeThunk)).CreateDelegate(context); IntPtr functionPtr = Marshal.GetFunctionPointerForDelegate(methodDelegate); @@ -2533,36 +2571,12 @@ namespace FlaxEngine } [UnmanagedCallersOnly] - internal static void SetArrayValueReference(ManagedHandle arrayHandle, IntPtr elementPtr, IntPtr valueHandle) + internal static void SetArrayValueReference(ManagedHandle arrayHandle, IntPtr valueHandle, int index) { ManagedArray managedArray = Unsafe.As(arrayHandle.Target); - int index = (int)(elementPtr.ToInt64() - managedArray.Pointer.ToInt64()) / managedArray.ElementSize; managedArray.ToSpan()[index] = valueHandle; } - [UnmanagedCallersOnly] - internal static ManagedHandle LoadAssemblyFromPath(IntPtr assemblyPath_, IntPtr* assemblyName, IntPtr* assemblyFullName) - { - if (!firstAssemblyLoaded) - { - // This assembly was already loaded when initializing the host context - firstAssemblyLoaded = true; - - Assembly flaxEngineAssembly = AssemblyLoadContext.Default.Assemblies.First(x => x.GetName().Name == "FlaxEngine.CSharp"); - *assemblyName = NativeAllocStringAnsi(flaxEngineAssembly.GetName().Name); - *assemblyFullName = NativeAllocStringAnsi(flaxEngineAssembly.FullName); - return GetAssemblyHandle(flaxEngineAssembly); - } - string assemblyPath = Marshal.PtrToStringAnsi(assemblyPath_); - - Assembly assembly = scriptingAssemblyLoadContext.LoadFromAssemblyPath(assemblyPath); - NativeLibrary.SetDllImportResolver(assembly, NativeLibraryImportResolver); - - *assemblyName = NativeAllocStringAnsi(assembly.GetName().Name); - *assemblyFullName = NativeAllocStringAnsi(assembly.FullName); - return GetAssemblyHandle(assembly); - } - [UnmanagedCallersOnly] internal static ManagedHandle LoadAssemblyImage(IntPtr data, int len, IntPtr assemblyPath_, IntPtr* assemblyName, IntPtr* assemblyFullName) { @@ -2680,16 +2694,6 @@ namespace FlaxEngine DelegateHelpers.InitMethods(); } - [UnmanagedCallersOnly] - internal static ManagedHandle GetAssemblyObject(IntPtr assemblyName_) - { - string assemblyName = Marshal.PtrToStringAnsi(assemblyName_); - Assembly assembly = Utils.GetAssemblies().FirstOrDefault(x => x.FullName == assemblyName); - if (assembly == null) - return new ManagedHandle(); - return ManagedHandle.Alloc(assembly); - } - [UnmanagedCallersOnly] internal static unsafe int NativeSizeOf(ManagedHandle typeHandle, uint* align) { @@ -2753,6 +2757,13 @@ namespace FlaxEngine return GetTypeGCHandle(type.BaseType); } + [UnmanagedCallersOnly] + internal static ManagedHandle GetElementClass(ManagedHandle typeHandle) + { + Type type = Unsafe.As(typeHandle.Target); + return GetTypeGCHandle(type.GetElementType()); + } + [UnmanagedCallersOnly] internal static byte GetMethodParameterIsOut(ManagedHandle methodHandle, int parameterNum) { @@ -2805,10 +2816,10 @@ namespace FlaxEngine } [UnmanagedCallersOnly] - internal static ManagedHandle NewGCHandleWeakref(ManagedHandle valueHandle, byte track_resurrection) + internal static ManagedHandle NewGCHandleWeak(ManagedHandle valueHandle, byte trackResurrection) { object value = valueHandle.Target; - ManagedHandle handle = ManagedHandle.Alloc(value, track_resurrection != 0 ? GCHandleType.WeakTrackResurrection : GCHandleType.Weak); + ManagedHandle handle = ManagedHandle.Alloc(value, trackResurrection != 0 ? GCHandleType.WeakTrackResurrection : GCHandleType.Weak); return handle; } @@ -2818,122 +2829,125 @@ namespace FlaxEngine valueHandle.Free(); } - internal enum MonoType + internal enum MTypes : uint { - MONO_TYPE_END = 0x00, - MONO_TYPE_VOID = 0x01, - MONO_TYPE_BOOLEAN = 0x02, - MONO_TYPE_CHAR = 0x03, - MONO_TYPE_I1 = 0x04, - MONO_TYPE_U1 = 0x05, - MONO_TYPE_I2 = 0x06, - MONO_TYPE_U2 = 0x07, - MONO_TYPE_I4 = 0x08, - MONO_TYPE_U4 = 0x09, - MONO_TYPE_I8 = 0x0a, - MONO_TYPE_U8 = 0x0b, - MONO_TYPE_R4 = 0x0c, - MONO_TYPE_R8 = 0x0d, - MONO_TYPE_STRING = 0x0e, - MONO_TYPE_PTR = 0x0f, - MONO_TYPE_BYREF = 0x10, - MONO_TYPE_VALUETYPE = 0x11, - MONO_TYPE_CLASS = 0x12, - MONO_TYPE_VAR = 0x13, - MONO_TYPE_ARRAY = 0x14, - MONO_TYPE_GENERICINST = 0x15, - MONO_TYPE_TYPEDBYREF = 0x16, - MONO_TYPE_I = 0x18, - MONO_TYPE_U = 0x19, - MONO_TYPE_FNPTR = 0x1b, - MONO_TYPE_OBJECT = 0x1c, - MONO_TYPE_SZARRAY = 0x1d, - MONO_TYPE_MVAR = 0x1e, - MONO_TYPE_CMOD_REQD = 0x1f, - MONO_TYPE_CMOD_OPT = 0x20, - MONO_TYPE_INTERNAL = 0x21, - MONO_TYPE_MODIFIER = 0x40, - MONO_TYPE_SENTINEL = 0x41, - MONO_TYPE_PINNED = 0x45, - MONO_TYPE_ENUM = 0x55, + End = 0x00, + Void = 0x01, + Boolean = 0x02, + Char = 0x03, + I1 = 0x04, + U1 = 0x05, + I2 = 0x06, + U2 = 0x07, + I4 = 0x08, + U4 = 0x09, + I8 = 0x0a, + U8 = 0x0b, + R4 = 0x0c, + R8 = 0x0d, + String = 0x0e, + Ptr = 0x0f, + ByRef = 0x10, + ValueType = 0x11, + Class = 0x12, + Var = 0x13, + Array = 0x14, + GenericInst = 0x15, + TypeByRef = 0x16, + I = 0x18, + U = 0x19, + Fnptr = 0x1b, + Object = 0x1c, + SzArray = 0x1d, + MVar = 0x1e, + CmodReqd = 0x1f, + CmodOpt = 0x20, + Internal = 0x21, + Modifier = 0x40, + Sentinel = 0x41, + Pinned = 0x45, + Enum = 0x55, }; [UnmanagedCallersOnly] - internal static int GetTypeMonoTypeEnum(ManagedHandle typeHandle) + internal static uint GetTypeMTypesEnum(ManagedHandle typeHandle) { Type type = Unsafe.As(typeHandle.Target); - - MonoType monoType; + MTypes monoType; switch (type) { - case Type _ when type == typeof(bool): - monoType = MonoType.MONO_TYPE_BOOLEAN; - break; - case Type _ when type == typeof(sbyte): - case Type _ when type == typeof(short): - monoType = MonoType.MONO_TYPE_I2; - break; - case Type _ when type == typeof(byte): - case Type _ when type == typeof(ushort): - monoType = MonoType.MONO_TYPE_U2; - break; - case Type _ when type == typeof(int): - monoType = MonoType.MONO_TYPE_I4; - break; - case Type _ when type == typeof(uint): - monoType = MonoType.MONO_TYPE_U4; - break; - case Type _ when type == typeof(long): - monoType = MonoType.MONO_TYPE_I8; - break; - case Type _ when type == typeof(ulong): - monoType = MonoType.MONO_TYPE_U8; - break; - case Type _ when type == typeof(float): - monoType = MonoType.MONO_TYPE_R4; - break; - case Type _ when type == typeof(double): - monoType = MonoType.MONO_TYPE_R8; - break; - case Type _ when type == typeof(string): - monoType = MonoType.MONO_TYPE_STRING; - break; - case Type _ when type == typeof(IntPtr): - monoType = MonoType.MONO_TYPE_PTR; - break; - case Type _ when type.IsEnum: - { - var elementType = type.GetEnumUnderlyingType(); - if (elementType == typeof(sbyte) || elementType == typeof(short)) - monoType = MonoType.MONO_TYPE_I2; - else if (elementType == typeof(byte) || elementType == typeof(ushort)) - monoType = MonoType.MONO_TYPE_U2; - else if (elementType == typeof(int)) - monoType = MonoType.MONO_TYPE_I4; - else if (elementType == typeof(uint)) - monoType = MonoType.MONO_TYPE_U4; - else if (elementType == typeof(long)) - monoType = MonoType.MONO_TYPE_I8; - else if (elementType == typeof(ulong)) - monoType = MonoType.MONO_TYPE_U8; - else - throw new Exception($"GetTypeMonoTypeEnum: Unsupported type '{type.FullName}'"); - break; - } - case Type _ when type.IsValueType && !type.IsEnum && !type.IsPrimitive: - monoType = MonoType.MONO_TYPE_VALUETYPE; - break; - case Type _ when type.IsClass: - monoType = MonoType.MONO_TYPE_OBJECT; - break; - case Type _ when type.IsGenericType: - monoType = MonoType.MONO_TYPE_GENERICINST; - break; - - default: throw new Exception($"GetTypeMonoTypeEnum: Unsupported type '{type.FullName}'"); + case Type _ when type == typeof(void): + monoType = MTypes.Void; + break; + case Type _ when type == typeof(bool): + monoType = MTypes.Boolean; + break; + case Type _ when type == typeof(sbyte): + case Type _ when type == typeof(short): + monoType = MTypes.I2; + break; + case Type _ when type == typeof(byte): + case Type _ when type == typeof(ushort): + monoType = MTypes.U2; + break; + case Type _ when type == typeof(int): + monoType = MTypes.I4; + break; + case Type _ when type == typeof(uint): + monoType = MTypes.U4; + break; + case Type _ when type == typeof(long): + monoType = MTypes.I8; + break; + case Type _ when type == typeof(ulong): + monoType = MTypes.U8; + break; + case Type _ when type == typeof(float): + monoType = MTypes.R4; + break; + case Type _ when type == typeof(double): + monoType = MTypes.R8; + break; + case Type _ when type == typeof(string): + monoType = MTypes.String; + break; + case Type _ when type == typeof(IntPtr): + monoType = MTypes.Ptr; + break; + case Type _ when type.IsEnum: + { + var elementType = type.GetEnumUnderlyingType(); + if (elementType == typeof(sbyte) || elementType == typeof(short)) + monoType = MTypes.I2; + else if (elementType == typeof(byte) || elementType == typeof(ushort)) + monoType = MTypes.U2; + else if (elementType == typeof(int)) + monoType = MTypes.I4; + else if (elementType == typeof(uint)) + monoType = MTypes.U4; + else if (elementType == typeof(long)) + monoType = MTypes.I8; + else if (elementType == typeof(ulong)) + monoType = MTypes.U8; + else + throw new Exception($"Unsupported type '{type.FullName}'"); + break; } - - return (int)monoType; + case Type _ when type.IsArray: + monoType = MTypes.Array; + break; + case Type _ when type.IsValueType && !type.IsEnum && !type.IsPrimitive: + monoType = MTypes.ValueType; + break; + case Type _ when type.IsGenericType: + monoType = MTypes.GenericInst; + break; + case Type _ when type.IsClass: + monoType = MTypes.Object; + break; + default: throw new Exception($"Unsupported type '{type.FullName}'"); + } + return (uint)monoType; } /// @@ -2958,7 +2972,7 @@ namespace FlaxEngine // We need private types of this assembly too, DefinedTypes contains a lot of types from other assemblies... var types = referencedTypes.Any() ? assembly.DefinedTypes.Where(x => !referencedTypes.Contains(x.FullName)).ToArray() : assembly.DefinedTypes.ToArray(); - Assert.IsTrue(Utils.GetAssemblies().Where(x => x.GetName().Name == "FlaxEngine.CSharp").Count() == 1); + Assert.IsTrue(Utils.GetAssemblies().Count(x => x.GetName().Name == "FlaxEngine.CSharp") == 1); return types; } @@ -3086,7 +3100,7 @@ namespace FlaxEngine // Returned exception is the last parameter IntPtr exceptionPtr = nativePtrs[parameterTypes.Length]; if (exceptionPtr != IntPtr.Zero) - Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(ManagedHandle.Alloc(exception, GCHandleType.Weak))); + Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(exception, GCHandleType.Weak)); return IntPtr.Zero; } return returnValue; @@ -3127,7 +3141,7 @@ namespace FlaxEngine // Returned exception is the last parameter IntPtr exceptionPtr = nativePtrs[numParams]; if (exceptionPtr != IntPtr.Zero) - Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(ManagedHandle.Alloc(exception, GCHandleType.Weak))); + Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(exception, GCHandleType.Weak)); return IntPtr.Zero; } diff --git a/Source/Engine/Engine/NativeInterop_Invoker.cs b/Source/Engine/Engine/NativeInterop_Invoker.cs index 56b225767..b9b793cd5 100644 --- a/Source/Engine/Engine/NativeInterop_Invoker.cs +++ b/Source/Engine/Engine/NativeInterop_Invoker.cs @@ -19,6 +19,7 @@ namespace FlaxEngine internal static class Invoker { internal delegate IntPtr MarshalAndInvokeDelegate(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr); + internal delegate IntPtr InvokeThunkDelegate(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs); /// @@ -29,6 +30,7 @@ namespace FlaxEngine { return (T*)ptr.ToPointer(); } + internal static MethodInfo ToPointerMethod = typeof(Invoker).GetMethod(nameof(Invoker.ToPointer), BindingFlags.Static | BindingFlags.NonPublic); /// @@ -43,22 +45,18 @@ namespace FlaxEngine methodParameters = method.GetParameters().Select(x => x.ParameterType).Prepend(method.DeclaringType).ToArray(); // Pass delegate parameters by reference - Type[] delegateParameters = methodParameters.Select(x => x.IsPointer ? typeof(IntPtr) : x) - .Select(x => passParametersByRef && !x.IsByRef ? x.MakeByRefType() : x).ToArray(); + Type[] delegateParameters = methodParameters.Select(x => x.IsPointer ? typeof(IntPtr) : x).Select(x => passParametersByRef && !x.IsByRef ? x.MakeByRefType() : x).ToArray(); if (!method.IsStatic && passParametersByRef) delegateParameters[0] = method.DeclaringType; // Convert unmanaged pointer parameters to IntPtr - ParameterExpression[] parameterExpressions = delegateParameters.Select(x => Expression.Parameter(x)).ToArray(); + ParameterExpression[] parameterExpressions = delegateParameters.Select(Expression.Parameter).ToArray(); Expression[] callExpressions = new Expression[methodParameters.Length]; for (int i = 0; i < methodParameters.Length; i++) { Type parameterType = methodParameters[i]; if (parameterType.IsPointer) - { - callExpressions[i] = - Expression.Call(null, ToPointerMethod.MakeGenericMethod(parameterType.GetElementType()), parameterExpressions[i]); - } + callExpressions[i] = Expression.Call(null, ToPointerMethod.MakeGenericMethod(parameterType.GetElementType()), parameterExpressions[i]); else callExpressions[i] = parameterExpressions[i]; } @@ -70,7 +68,7 @@ namespace FlaxEngine else callDelegExp = Expression.Call(parameterExpressions[0], method, callExpressions.Skip(1).ToArray()); Type delegateType = DelegateHelpers.MakeNewCustomDelegate(delegateParameters.Append(method.ReturnType).ToArray()); - return Expression.Lambda(delegateType, callDelegExp, parameterExpressions.ToArray()).Compile(); + return Expression.Lambda(delegateType, callDelegExp, parameterExpressions).Compile(); } internal static IntPtr MarshalReturnValue(ref TRet returnValue) @@ -79,8 +77,6 @@ namespace FlaxEngine return IntPtr.Zero; if (typeof(TRet) == typeof(string)) return ManagedString.ToNativeWeak(Unsafe.As(returnValue)); - if (typeof(TRet) == typeof(IntPtr)) - return (IntPtr)(object)returnValue; if (typeof(TRet) == typeof(ManagedHandle)) return ManagedHandle.ToIntPtr((ManagedHandle)(object)returnValue); if (typeof(TRet) == typeof(bool)) @@ -91,10 +87,10 @@ namespace FlaxEngine { var elementType = typeof(TRet).GetElementType(); if (ArrayFactory.GetMarshalledType(elementType) == elementType) - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As(returnValue)), GCHandleType.Weak)); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnValue))), GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As(returnValue)), GCHandleType.Weak); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnValue))), GCHandleType.Weak); } - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(returnValue, GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(returnValue, GCHandleType.Weak); } internal static IntPtr MarshalReturnValueGeneric(Type returnType, object returnObject) @@ -103,8 +99,6 @@ namespace FlaxEngine return IntPtr.Zero; if (returnType == typeof(string)) return ManagedString.ToNativeWeak(Unsafe.As(returnObject)); - if (returnType == typeof(IntPtr)) - return (IntPtr)returnObject; if (returnType == typeof(ManagedHandle)) return ManagedHandle.ToIntPtr((ManagedHandle)(object)returnObject); if (returnType == typeof(bool)) @@ -112,10 +106,10 @@ namespace FlaxEngine if (returnType == typeof(Type)) return ManagedHandle.ToIntPtr(GetTypeGCHandle(Unsafe.As(returnObject))); if (returnType.IsArray && ArrayFactory.GetMarshalledType(returnType.GetElementType()) == returnType.GetElementType()) - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As(returnObject)), GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As(returnObject)), GCHandleType.Weak); if (returnType.IsArray) - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnObject))), GCHandleType.Weak)); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(returnObject, GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnObject))), GCHandleType.Weak); + return ManagedHandle.ToIntPtr(returnObject, GCHandleType.Weak); } internal static IntPtr MarshalReturnValueThunk(ref TRet returnValue) @@ -134,8 +128,8 @@ namespace FlaxEngine { var elementType = typeof(TRet).GetElementType(); if (ArrayFactory.GetMarshalledType(elementType) == elementType) - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As(returnValue)), GCHandleType.Weak)); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnValue))), GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As(returnValue)), GCHandleType.Weak); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnValue))), GCHandleType.Weak); } // Match Mono bindings and pass value as pointer to prevent boxing it if (typeof(TRet) == typeof(System.Boolean)) @@ -152,7 +146,7 @@ namespace FlaxEngine return (IntPtr)new UIntPtr((ulong)(System.UInt32)(object)returnValue); if (typeof(TRet) == typeof(System.UInt64)) return (IntPtr)new UIntPtr((ulong)(System.UInt64)(object)returnValue); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(returnValue, GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(returnValue, GCHandleType.Weak); } internal static IntPtr MarshalReturnValueThunkGeneric(Type returnType, object returnObject) @@ -171,8 +165,8 @@ namespace FlaxEngine { var elementType = returnType.GetElementType(); if (ArrayFactory.GetMarshalledType(elementType) == elementType) - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As(returnObject)), GCHandleType.Weak)); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnObject))), GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As(returnObject)), GCHandleType.Weak); + return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnObject))), GCHandleType.Weak); } // Match Mono bindings and pass value as pointer to prevent boxing it if (returnType == typeof(System.Boolean)) @@ -189,7 +183,7 @@ namespace FlaxEngine return (IntPtr)new UIntPtr((ulong)(System.UInt32)(object)returnObject); if (returnType == typeof(System.UInt64)) return (IntPtr)new UIntPtr((ulong)(System.UInt64)(object)returnObject); - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(returnObject, GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(returnObject, GCHandleType.Weak); } internal static class InvokerNoRet0 diff --git a/Source/Engine/Graphics/Models/Mesh.cpp b/Source/Engine/Graphics/Models/Mesh.cpp index 42b4316c9..e5ba5488d 100644 --- a/Source/Engine/Graphics/Models/Mesh.cpp +++ b/Source/Engine/Graphics/Models/Mesh.cpp @@ -11,15 +11,13 @@ #include "Engine/Graphics/RenderTask.h" #include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Renderer/RenderList.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Threading/Task.h" #include "Engine/Threading/Threading.h" #if USE_EDITOR #include "Engine/Renderer/GBufferPass.h" #endif -#if USE_MONO -#include -#endif namespace { @@ -117,28 +115,28 @@ namespace #if !COMPILE_WITHOUT_CSHARP template - bool UpdateMesh(Mesh* mesh, uint32 vertexCount, uint32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj) + bool UpdateMesh(Mesh* mesh, uint32 vertexCount, uint32 triangleCount, MArray* verticesObj, MArray* trianglesObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj, MArray* colorsObj) { - ASSERT((uint32)mono_array_length(verticesObj) >= vertexCount); - ASSERT((uint32)mono_array_length(trianglesObj) / 3 >= triangleCount); - auto vertices = (Float3*)(void*)mono_array_addr_with_size(verticesObj, sizeof(Float3), 0); - auto triangles = (IndexType*)(void*)mono_array_addr_with_size(trianglesObj, sizeof(IndexType), 0); - const auto normals = normalsObj ? (Float3*)(void*)mono_array_addr_with_size(normalsObj, sizeof(Float3), 0) : nullptr; - const auto tangents = tangentsObj ? (Float3*)(void*)mono_array_addr_with_size(tangentsObj, sizeof(Float3), 0) : nullptr; - const auto uvs = uvObj ? (Float2*)(void*)mono_array_addr_with_size(uvObj, sizeof(Float2), 0) : nullptr; - const auto colors = colorsObj ? (Color32*)(void*)mono_array_addr_with_size(colorsObj, sizeof(Color32), 0) : nullptr; + ASSERT((uint32)MCore::Array::GetLength(verticesObj) >= vertexCount); + ASSERT((uint32)MCore::Array::GetLength(trianglesObj) / 3 >= triangleCount); + auto vertices = MCore::Array::GetAddress(verticesObj); + auto triangles = MCore::Array::GetAddress(trianglesObj); + const auto normals = normalsObj ? MCore::Array::GetAddress(normalsObj) : nullptr; + const auto tangents = tangentsObj ? MCore::Array::GetAddress(tangentsObj) : nullptr; + const auto uvs = uvObj ? MCore::Array::GetAddress(uvObj) : nullptr; + const auto colors = colorsObj ? MCore::Array::GetAddress(colorsObj) : nullptr; return UpdateMesh(mesh, vertexCount, triangleCount, vertices, triangles, normals, tangents, uvs, colors); } template - bool UpdateTriangles(Mesh* mesh, int32 triangleCount, MonoArray* trianglesObj) + bool UpdateTriangles(Mesh* mesh, int32 triangleCount, MArray* trianglesObj) { const auto model = mesh->GetModel(); ASSERT(model && model->IsVirtual() && trianglesObj); // Get buffer data - ASSERT((int32)mono_array_length(trianglesObj) / 3 >= triangleCount); - auto ib = (IndexType*)(void*)mono_array_addr_with_size(trianglesObj, sizeof(IndexType), 0); + ASSERT(MCore::Array::GetLength(trianglesObj) / 3 >= triangleCount); + auto ib = MCore::Array::GetAddress(trianglesObj); return mesh->UpdateTriangles(triangleCount, ib); } @@ -717,22 +715,22 @@ ScriptingObject* Mesh::GetParentModel() #if !COMPILE_WITHOUT_CSHARP -bool Mesh::UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj) +bool Mesh::UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MArray* verticesObj, MArray* trianglesObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj, MArray* colorsObj) { return ::UpdateMesh(this, (uint32)vertexCount, (uint32)triangleCount, verticesObj, trianglesObj, normalsObj, tangentsObj, uvObj, colorsObj); } -bool Mesh::UpdateMeshUShort(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj) +bool Mesh::UpdateMeshUShort(int32 vertexCount, int32 triangleCount, MArray* verticesObj, MArray* trianglesObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj, MArray* colorsObj) { return ::UpdateMesh(this, (uint32)vertexCount, (uint32)triangleCount, verticesObj, trianglesObj, normalsObj, tangentsObj, uvObj, colorsObj); } -bool Mesh::UpdateTrianglesUInt(int32 triangleCount, MonoArray* trianglesObj) +bool Mesh::UpdateTrianglesUInt(int32 triangleCount, MArray* trianglesObj) { return ::UpdateTriangles(this, triangleCount, trianglesObj); } -bool Mesh::UpdateTrianglesUShort(int32 triangleCount, MonoArray* trianglesObj) +bool Mesh::UpdateTrianglesUShort(int32 triangleCount, MArray* trianglesObj) { return ::UpdateTriangles(this, triangleCount, trianglesObj); } @@ -746,7 +744,7 @@ enum class InternalBufferType IB32 = 4, }; -MonoArray* Mesh::DownloadBuffer(bool forceGpu, MonoReflectionType* resultType, int32 typeI) +MArray* Mesh::DownloadBuffer(bool forceGpu, MTypeObject* resultType, int32 typeI) { auto mesh = this; auto type = (InternalBufferType)typeI; @@ -824,8 +822,8 @@ MonoArray* Mesh::DownloadBuffer(bool forceGpu, MonoReflectionType* resultType, i } // Convert into managed array - MonoArray* result = mono_array_new(mono_domain_get(), mono_type_get_class(mono_reflection_type_get_type(resultType)), dataCount); - void* managedArrayPtr = mono_array_addr_with_size(result, 0, 0); + MArray* result = MCore::Array::New(MCore::Type::GetClass(INTERNAL_TYPE_OBJECT_GET(resultType)), dataCount); + void* managedArrayPtr = MCore::Array::GetAddress(result); const int32 elementSize = data.Length() / dataCount; switch (type) { diff --git a/Source/Engine/Graphics/Models/Mesh.h b/Source/Engine/Graphics/Models/Mesh.h index 9b1ab4846..aea093004 100644 --- a/Source/Engine/Graphics/Models/Mesh.h +++ b/Source/Engine/Graphics/Models/Mesh.h @@ -317,10 +317,10 @@ private: // Internal bindings API_FUNCTION(NoProxy) ScriptingObject* GetParentModel(); #if !COMPILE_WITHOUT_CSHARP - API_FUNCTION(NoProxy) bool UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj); - API_FUNCTION(NoProxy) bool UpdateMeshUShort(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj); - API_FUNCTION(NoProxy) bool UpdateTrianglesUInt(int32 triangleCount, MonoArray* trianglesObj); - API_FUNCTION(NoProxy) bool UpdateTrianglesUShort(int32 triangleCount, MonoArray* trianglesObj); - API_FUNCTION(NoProxy) MonoArray* DownloadBuffer(bool forceGpu, MonoReflectionType* resultType, int32 typeI); + API_FUNCTION(NoProxy) bool UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MArray* verticesObj, MArray* trianglesObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj, MArray* colorsObj); + API_FUNCTION(NoProxy) bool UpdateMeshUShort(int32 vertexCount, int32 triangleCount, MArray* verticesObj, MArray* trianglesObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj, MArray* colorsObj); + API_FUNCTION(NoProxy) bool UpdateTrianglesUInt(int32 triangleCount, MArray* trianglesObj); + API_FUNCTION(NoProxy) bool UpdateTrianglesUShort(int32 triangleCount, MArray* trianglesObj); + API_FUNCTION(NoProxy) MArray* DownloadBuffer(bool forceGpu, MTypeObject* resultType, int32 typeI); #endif }; diff --git a/Source/Engine/Graphics/Models/SkinnedMesh.cpp b/Source/Engine/Graphics/Models/SkinnedMesh.cpp index a47ef2302..2b8cf5c3a 100644 --- a/Source/Engine/Graphics/Models/SkinnedMesh.cpp +++ b/Source/Engine/Graphics/Models/SkinnedMesh.cpp @@ -12,11 +12,9 @@ #include "Engine/Renderer/RenderList.h" #include "Engine/Serialization/MemoryReadStream.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Threading/Task.h" #include "Engine/Threading/Threading.h" -#if USE_MONO -#include -#endif void SkinnedMesh::Init(SkinnedModel* model, int32 lodIndex, int32 index, int32 materialSlotIndex, const BoundingBox& box, const BoundingSphere& sphere) { @@ -398,18 +396,18 @@ ScriptingObject* SkinnedMesh::GetParentModel() #if !COMPILE_WITHOUT_CSHARP template -bool UpdateMesh(SkinnedMesh* mesh, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj) +bool UpdateMesh(SkinnedMesh* mesh, MArray* verticesObj, MArray* trianglesObj, MArray* blendIndicesObj, MArray* blendWeightsObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj) { auto model = mesh->GetSkinnedModel(); ASSERT(model && model->IsVirtual() && verticesObj && trianglesObj && blendIndicesObj && blendWeightsObj); // Get buffers data - const auto vertexCount = (uint32)mono_array_length(verticesObj); - const auto triangleCount = (uint32)mono_array_length(trianglesObj) / 3; - auto vertices = (Float3*)(void*)mono_array_addr_with_size(verticesObj, sizeof(Float3), 0); - auto ib = (IndexType*)(void*)mono_array_addr_with_size(trianglesObj, sizeof(int32), 0); - auto blendIndices = (Int4*)(void*)mono_array_addr_with_size(blendIndicesObj, sizeof(Int4), 0); - auto blendWeights = (Float4*)(void*)mono_array_addr_with_size(blendWeightsObj, sizeof(Float4), 0); + const auto vertexCount = (uint32)MCore::Array::GetLength(verticesObj); + const auto triangleCount = (uint32)MCore::Array::GetLength(trianglesObj) / 3; + auto vertices = MCore::Array::GetAddress(verticesObj); + auto ib = MCore::Array::GetAddress(trianglesObj); + auto blendIndices = MCore::Array::GetAddress(blendIndicesObj); + auto blendWeights = MCore::Array::GetAddress(blendWeightsObj); Array vb; vb.Resize(vertexCount); for (uint32 i = 0; i < vertexCount; i++) @@ -418,10 +416,10 @@ bool UpdateMesh(SkinnedMesh* mesh, MonoArray* verticesObj, MonoArray* trianglesO } if (normalsObj) { - const auto normals = (Float3*)(void*)mono_array_addr_with_size(normalsObj, sizeof(Float3), 0); + const auto normals = MCore::Array::GetAddress(normalsObj); if (tangentsObj) { - const auto tangents = (Float3*)(void*)mono_array_addr_with_size(tangentsObj, sizeof(Float3), 0); + const auto tangents = MCore::Array::GetAddress(tangentsObj); for (uint32 i = 0; i < vertexCount; i++) { // Peek normal and tangent @@ -475,7 +473,7 @@ bool UpdateMesh(SkinnedMesh* mesh, MonoArray* verticesObj, MonoArray* trianglesO } if (uvObj) { - const auto uvs = (Float2*)(void*)mono_array_addr_with_size(uvObj, sizeof(Float2), 0); + const auto uvs = MCore::Array::GetAddress(uvObj); for (uint32 i = 0; i < vertexCount; i++) vb[i].TexCoord = Half2(uvs[i]); } @@ -499,12 +497,12 @@ bool UpdateMesh(SkinnedMesh* mesh, MonoArray* verticesObj, MonoArray* trianglesO return mesh->UpdateMesh(vertexCount, triangleCount, vb.Get(), ib); } -bool SkinnedMesh::UpdateMeshUInt(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj) +bool SkinnedMesh::UpdateMeshUInt(MArray* verticesObj, MArray* trianglesObj, MArray* blendIndicesObj, MArray* blendWeightsObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj) { return ::UpdateMesh(this, verticesObj, trianglesObj, blendIndicesObj, blendWeightsObj, normalsObj, tangentsObj, uvObj); } -bool SkinnedMesh::UpdateMeshUShort(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj) +bool SkinnedMesh::UpdateMeshUShort(MArray* verticesObj, MArray* trianglesObj, MArray* blendIndicesObj, MArray* blendWeightsObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj) { return ::UpdateMesh(this, verticesObj, trianglesObj, blendIndicesObj, blendWeightsObj, normalsObj, tangentsObj, uvObj); } @@ -516,7 +514,7 @@ enum class InternalBufferType IB32 = 4, }; -MonoArray* SkinnedMesh::DownloadBuffer(bool forceGpu, MonoReflectionType* resultType, int32 typeI) +MArray* SkinnedMesh::DownloadBuffer(bool forceGpu, MTypeObject* resultType, int32 typeI) { SkinnedMesh* mesh = this; InternalBufferType type = (InternalBufferType)typeI; @@ -582,8 +580,8 @@ MonoArray* SkinnedMesh::DownloadBuffer(bool forceGpu, MonoReflectionType* result } // Convert into managed array - MonoArray* result = mono_array_new(mono_domain_get(), mono_type_get_class(mono_reflection_type_get_type(resultType)), dataCount); - void* managedArrayPtr = mono_array_addr_with_size(result, 0, 0); + MArray* result = MCore::Array::New(MCore::Type::GetClass(INTERNAL_TYPE_OBJECT_GET(resultType)), dataCount); + void* managedArrayPtr = MCore::Array::GetAddress(result); const int32 elementSize = data.Length() / dataCount; switch (type) { diff --git a/Source/Engine/Graphics/Models/SkinnedMesh.h b/Source/Engine/Graphics/Models/SkinnedMesh.h index 57a382cff..9c95ff4b2 100644 --- a/Source/Engine/Graphics/Models/SkinnedMesh.h +++ b/Source/Engine/Graphics/Models/SkinnedMesh.h @@ -197,8 +197,8 @@ private: // Internal bindings API_FUNCTION(NoProxy) ScriptingObject* GetParentModel(); #if !COMPILE_WITHOUT_CSHARP - API_FUNCTION(NoProxy) bool UpdateMeshUInt(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj); - API_FUNCTION(NoProxy) bool UpdateMeshUShort(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj); - API_FUNCTION(NoProxy) MonoArray* DownloadBuffer(bool forceGpu, MonoReflectionType* resultType, int32 typeI); + API_FUNCTION(NoProxy) bool UpdateMeshUInt(MArray* verticesObj, MArray* trianglesObj, MArray* blendIndicesObj, MArray* blendWeightsObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj); + API_FUNCTION(NoProxy) bool UpdateMeshUShort(MArray* verticesObj, MArray* trianglesObj, MArray* blendIndicesObj, MArray* blendWeightsObj, MArray* normalsObj, MArray* tangentsObj, MArray* uvObj); + API_FUNCTION(NoProxy) MArray* DownloadBuffer(bool forceGpu, MTypeObject* resultType, int32 typeI); #endif }; diff --git a/Source/Engine/Level/Actors/Spline.cpp b/Source/Engine/Level/Actors/Spline.cpp index 52861c210..dbd7ef045 100644 --- a/Source/Engine/Level/Actors/Spline.cpp +++ b/Source/Engine/Level/Actors/Spline.cpp @@ -4,9 +4,7 @@ #include "Engine/Serialization/Serialization.h" #include "Engine/Animations/CurveSerialization.h" #include "Engine/Core/Math/Matrix.h" -#if USE_MONO -#include -#endif +#include "Engine/Scripting/ManagedCLR/MCore.h" Spline::Spline(const SpawnParams& params) : Actor(params) @@ -441,16 +439,17 @@ void Spline::UpdateSpline() #if !COMPILE_WITHOUT_CSHARP -void Spline::GetKeyframes(MonoArray* data) +void Spline::GetKeyframes(MArray* data) { - Platform::MemoryCopy(mono_array_addr_with_size(data, sizeof(Keyframe), 0), Curve.GetKeyframes().Get(), sizeof(Keyframe) * Curve.GetKeyframes().Count()); + ASSERT(MCore::Array::GetLength(data) >= Curve.GetKeyframes().Count()); + Platform::MemoryCopy(MCore::Array::GetAddress(data), Curve.GetKeyframes().Get(), sizeof(Keyframe) * Curve.GetKeyframes().Count()); } -void Spline::SetKeyframes(MonoArray* data) +void Spline::SetKeyframes(MArray* data) { - const auto count = (int32)mono_array_length(data); + const int32 count = MCore::Array::GetLength(data); Curve.GetKeyframes().Resize(count, false); - Platform::MemoryCopy(Curve.GetKeyframes().Get(), mono_array_addr_with_size(data, sizeof(Keyframe), 0), sizeof(Keyframe) * count); + Platform::MemoryCopy(Curve.GetKeyframes().Get(), MCore::Array::GetAddress(data), sizeof(Keyframe) * count); UpdateSpline(); } diff --git a/Source/Engine/Level/Actors/Spline.h b/Source/Engine/Level/Actors/Spline.h index 2cf0be7f9..ea3cf8569 100644 --- a/Source/Engine/Level/Actors/Spline.h +++ b/Source/Engine/Level/Actors/Spline.h @@ -363,8 +363,8 @@ protected: private: // Internal bindings #if !COMPILE_WITHOUT_CSHARP - API_FUNCTION(NoProxy) void GetKeyframes(MonoArray* data); - API_FUNCTION(NoProxy) void SetKeyframes(MonoArray* data); + API_FUNCTION(NoProxy) void GetKeyframes(MArray* data); + API_FUNCTION(NoProxy) void SetKeyframes(MArray* data); #endif public: diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 4d81886a8..a408bc41a 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -26,7 +26,7 @@ #include "Engine/Scripting/ManagedCLR/MAssembly.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MDomain.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Serialization/JsonTools.h" diff --git a/Source/Engine/Level/SceneObject.cpp b/Source/Engine/Level/SceneObject.cpp index 989cd2c09..64a88be8d 100644 --- a/Source/Engine/Level/SceneObject.cpp +++ b/Source/Engine/Level/SceneObject.cpp @@ -6,7 +6,7 @@ #include "Engine/Content/Content.h" #include "Engine/Level/Prefabs/Prefab.h" #include "Engine/Scripting/BinaryModule.h" -#include "Engine/Scripting/ManagedSerialization.h" +#include "Engine/Scripting/Internal/ManagedSerialization.h" #include "Engine/Serialization/ISerializeModifier.h" #include "Engine/Serialization/Serialization.h" diff --git a/Source/Engine/Localization/CultureInfo.Tables.h b/Source/Engine/Localization/CultureInfo.Tables.h new file mode 100644 index 000000000..17000321e --- /dev/null +++ b/Source/Engine/Localization/CultureInfo.Tables.h @@ -0,0 +1,8634 @@ +/* +https://github.com/mono/mono/blob/main/mono/culture/culture-info-tables.h +### MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef MONO_METADATA_CULTURE_INFO_TABLES +#define MONO_METADATA_CULTURE_INFO_TABLES 1 + +#define NUM_DAYS 7 +#define NUM_MONTHS 13 +#define GROUP_SIZE 2 +#define NUM_CALENDARS 4 + +#define NUM_SHORT_DATE_PATTERNS 14 +#define NUM_LONG_DATE_PATTERNS 10 +#define NUM_SHORT_TIME_PATTERNS 12 +#define NUM_LONG_TIME_PATTERNS 9 +#define NUM_YEAR_MONTH_PATTERNS 8 + +#define idx2string(idx) (locale_strings + (idx)) +#define pattern2string(idx) (patterns + (idx)) +#define dtidx2string(idx) (datetime_strings + (idx)) + +typedef int gint; +typedef int8_t gint8; +typedef int16_t gint16; +typedef uint16_t guint16; +typedef int32_t mono_bool; +typedef uint8_t mono_byte; +typedef mono_byte MonoBoolean; + +/* need to change this if the string data ends up to not fit in a 64KB array. */ +typedef guint16 stridx_t; + +typedef struct { + const stridx_t month_day_pattern; + const stridx_t am_designator; + const stridx_t pm_designator; + + const stridx_t day_names [NUM_DAYS]; + const stridx_t abbreviated_day_names [NUM_DAYS]; + const stridx_t shortest_day_names [NUM_DAYS]; + const stridx_t month_names [NUM_MONTHS]; + const stridx_t month_genitive_names [NUM_MONTHS]; + const stridx_t abbreviated_month_names [NUM_MONTHS]; + const stridx_t abbreviated_month_genitive_names [NUM_MONTHS]; + + const gint8 calendar_week_rule; + const gint8 first_day_of_week; + + const stridx_t date_separator; + const stridx_t time_separator; + + const stridx_t short_date_patterns [NUM_SHORT_DATE_PATTERNS]; + const stridx_t long_date_patterns [NUM_LONG_DATE_PATTERNS]; + const stridx_t short_time_patterns [NUM_SHORT_TIME_PATTERNS]; + const stridx_t long_time_patterns [NUM_LONG_TIME_PATTERNS]; + const stridx_t year_month_patterns [NUM_YEAR_MONTH_PATTERNS]; +} DateTimeFormatEntry; + +typedef struct { + const stridx_t currency_decimal_separator; + const stridx_t currency_group_separator; + const stridx_t number_decimal_separator; + const stridx_t number_group_separator; + + const stridx_t currency_symbol; + const stridx_t percent_symbol; + const stridx_t nan_symbol; + const stridx_t per_mille_symbol; + const stridx_t negative_infinity_symbol; + const stridx_t positive_infinity_symbol; + + const stridx_t negative_sign; + const stridx_t positive_sign; + + const gint8 currency_negative_pattern; + const gint8 currency_positive_pattern; + const gint8 percent_negative_pattern; + const gint8 percent_positive_pattern; + const gint8 number_negative_pattern; + + const gint8 currency_decimal_digits; + const gint8 number_decimal_digits; + + const gint currency_group_sizes [GROUP_SIZE]; + const gint number_group_sizes [GROUP_SIZE]; +} NumberFormatEntry; + +typedef struct { + const gint ansi; + const gint ebcdic; + const gint mac; + const gint oem; + const MonoBoolean is_right_to_left; + const char list_sep; +} TextInfoEntry; + +typedef struct { + const gint16 lcid; + const gint16 parent_lcid; + const gint16 calendar_type; + const gint16 region_entry_index; + const stridx_t name; + const stridx_t englishname; + const stridx_t nativename; + const stridx_t win3lang; + const stridx_t iso3lang; + const stridx_t iso2lang; + const stridx_t territory; + const stridx_t native_calendar_names [NUM_CALENDARS]; + + const gint16 datetime_format_index; + const gint16 number_format_index; + + const TextInfoEntry text_info; +} CultureInfoEntry; + +typedef struct { + const stridx_t name; + const gint16 culture_entry_index; +} CultureInfoNameEntry; + +typedef struct { + const gint16 geo_id; + const stridx_t iso2name; + const stridx_t iso3name; + const stridx_t win3name; + const stridx_t english_name; + const stridx_t native_name; + const stridx_t currency_symbol; + const stridx_t iso_currency_symbol; + const stridx_t currency_english_name; + const stridx_t currency_native_name; +} RegionInfoEntry; + +typedef struct { + const stridx_t name; + const gint16 region_entry_index; +} RegionInfoNameEntry; + +#define NUM_CULTURE_ENTRIES 339 +#define NUM_REGION_ENTRIES 136 + + +static const DateTimeFormatEntry datetime_format_entries [] = { + {1, 0, 0, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, 0, 6, 1, 3, {9,18,0,0,0,0,0,0,0,0,0,0,0,0},{29,42,0,0,0,0,0,0,0,0},{62,71,0,0,0,0,0,0,0,0,0,0},{77,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 5, 8, {177, 190, 211, 226, 237, 256, 267}, {280, 285, 290, 295, 300, 305, 310}, {315, 318, 321, 324, 327, 318, 324}, {330, 343, 360, 369, 380, 387, 394, 401, 414, 433, 450, 465, 0}, {330, 343, 360, 369, 380, 387, 394, 401, 414, 433, 450, 465, 0}, {482, 489, 360, 496, 380, 387, 394, 503, 510, 517, 524, 531, 0}, {482, 489, 360, 496, 380, 387, 394, 503, 510, 517, 524, 531, 0}, 2, 1, 11, 3, {116,131,147,163,0,0,0,0,0,0,0,0,0,0},{180,199,217,242,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{279,0,0,0,0,0,0,0}}, + {109, 13, 19, {538, 547, 555, 563, 572, 579, 589}, {598, 602, 606, 610, 614, 618, 622}, {626, 629, 632, 635, 638, 641, 644}, {647, 653, 660, 666, 672, 677, 682, 689, 695, 704, 712, 721, 0}, {730, 739, 749, 758, 768, 776, 784, 794, 804, 816, 828, 840, 0}, {852, 857, 660, 863, 672, 677, 868, 873, 877, 882, 887, 892, 0}, {852, 857, 660, 863, 672, 677, 868, 873, 877, 882, 887, 892, 0}, 2, 1, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{315,338,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {967, 974, 981, 988, 995, 1002, 1009}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {379,388,397,406,417,428,439,446,453,460,0,0,0,0},{469,491,519,547,562,0,0,0,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {967, 974, 981, 988, 995, 1002, 1009}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {379,388,397,406,417,428,439,446,453,460,0,0,0,0},{469,491,519,547,562,0,0,0,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {673, 39, 44, {1197, 1205, 1215, 1223, 1231, 1240, 1247}, {1254, 1257, 1260, 1264, 1267, 1271, 1275}, {1278, 1280, 1282, 1285, 1287, 1280, 1285}, {1290, 1296, 1302, 1310, 1316, 1324, 1332, 1342, 1348, 1356, 1364, 1373, 0}, {1382, 1388, 1395, 1403, 1409, 1417, 1425, 1435, 1348, 1441, 1449, 1459, 0}, {1468, 1472, 1477, 1482, 1486, 1491, 1496, 1501, 1505, 1511, 1517, 1521, 0}, {1468, 1472, 1477, 1482, 1486, 1491, 1496, 1501, 1505, 1511, 1517, 1521, 0}, 2, 1, 11, 3, {681,692,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 49, 52, {1525, 1533, 1540, 1548, 1555, 1563, 1570}, {1578, 1583, 1587, 1591, 1595, 1599, 1603}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {1618, 1625, 1633, 1639, 1645, 1649, 1654, 1659, 1666, 1676, 1684, 1693, 0}, {1618, 1625, 1633, 1639, 1645, 1649, 1654, 1659, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 55, 3, {744,755,417,764,0,0,0,0,0,0,0,0,0,0},{721,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 57, 63, {1747, 1755, 1762, 1771, 1780, 1791, 1799}, {1807, 1810, 1813, 1816, 1819, 1822, 1825}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {681,775,417,784,0,0,0,0,0,0,0,0,0,0},{798,721,817,0,0,0,0,0,0,0},{71,830,0,0,0,0,0,0,0,0,0,0},{89,842,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 70, 77, {1959, 1974, 1989, 2000, 2015, 2028, 2047}, {2062, 2069, 2076, 2083, 2090, 2097, 2104}, {2111, 2114, 2117, 2117, 2120, 2120, 2123}, {2126, 2147, 2170, 2185, 2202, 2213, 2228, 2243, 2262, 2285, 2304, 2323, 0}, {2344, 2365, 2388, 2403, 2420, 2431, 2446, 2461, 2480, 2503, 2522, 2541, 0}, {2562, 2569, 2576, 2583, 2590, 2597, 2606, 2615, 2622, 2629, 2636, 2643, 0}, {2562, 2569, 2576, 2583, 2590, 2597, 2606, 2615, 2622, 2629, 2636, 2643, 0}, 2, 1, 1, 3, {295,18,857,9,864,417,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {932,941,948,957,460,417,968,0,0,0,0,0,0,0},{978,997,1010,1029,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1042, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 2890, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, 0, 1, 1, 3, {18,9,1054,857,1062,755,775,417,0,0,0,0,0,0},{1069,1097,1124,0,0,0,0,0,0,0},{266,71,1146,1151,1157,0,0,0,0,0,0,0},{271,89,1165,1173,1182,0,0,0,0},{1193,0,0,0,0,0,0,0}}, + {673, 84, 88, {2997, 3009, 3021, 3031, 3045, 3055, 3067}, {3078, 3081, 3084, 3087, 3090, 3093, 3096}, {1285, 1608, 1610, 3099, 1610, 1280, 1616}, {3101, 3110, 3119, 3129, 3138, 3147, 3156, 3166, 3173, 3181, 3189, 3199, 0}, {3208, 3219, 3230, 3242, 3253, 3264, 3275, 3287, 3296, 3306, 3316, 3328, 0}, {3339, 3345, 3351, 3358, 3364, 3370, 3376, 3383, 3387, 3392, 3397, 3404, 0}, {3339, 3345, 3351, 3358, 3364, 3370, 3376, 3383, 3387, 3392, 3397, 3404, 0}, 2, 1, 11, 11, {1208,0,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{1146,0,0,0,0,0,0,0,0,0,0,0},{1165,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 1, 1, 3, {18,9,775,755,417,0,0,0,0,0,0,0,0,0},{1217,894,1234,0,0,0,0,0,0,0},{71,266,1151,1243,1253,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 92, 105, {3596, 3614, 3628, 3646, 3664, 3682, 3698}, {3712, 3724, 3736, 3748, 3760, 3772, 3784}, {3791, 3796, 3801, 3806, 3811, 3816, 3821}, {3826, 3837, 3850, 3857, 3868, 3875, 3884, 3893, 3906, 3919, 3934, 3947, 0}, {3826, 3837, 3850, 3857, 3868, 3875, 3884, 3893, 3906, 3919, 3934, 3947, 0}, {3958, 3967, 3850, 3976, 3868, 3875, 3884, 3985, 3994, 4003, 4012, 4021, 0}, {3958, 3967, 3850, 3976, 3868, 3875, 3884, 3985, 3994, 4003, 4012, 4021, 0}, 0, 0, 1, 3, {18,1261,9,29,755,744,1274,417,1287,1304,0,0,0,0},{1314,1261,1332,1354,1287,0,0,0,0,0},{71,62,0,0,0,0,0,0,0,0,0,0},{89,77,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1375, 116, 120, {4030, 4040, 4048, 4053, 4060, 4073, 4081}, {2894, 4089, 3099, 4091, 4095, 1280, 4098}, {2894, 4089, 3099, 4102, 4095, 1280, 4102}, {4105, 4113, 4122, 4131, 4140, 4147, 4155, 4163, 4173, 4184, 1684, 1693, 0}, {4105, 4113, 4122, 4131, 4140, 4147, 4155, 4163, 4173, 4184, 1684, 1693, 0}, {1702, 857, 4193, 4200, 4206, 4212, 4218, 1727, 4224, 1737, 887, 1742, 0}, {1702, 857, 4193, 4200, 4206, 4212, 4218, 1727, 4224, 1737, 887, 1742, 0}, 2, 1, 124, 3, {1383,1397,0,0,0,0,0,0,0,0,0,0,0,0},{1410,1430,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{1444,0,0,0,0,0,0,0}}, + {673, 127, 132, {4231, 4242, 4253, 4267, 4281, 4293, 4305}, {4317, 4322, 4328, 4334, 4340, 4345, 4351}, {1285, 1608, 4356, 1608, 1614, 1614, 1616}, {4359, 4367, 3504, 4376, 4383, 4388, 4395, 4402, 1666, 4184, 4410, 4420, 0}, {4359, 4367, 3504, 4376, 4383, 4388, 4395, 4402, 1666, 4184, 4410, 4420, 0}, {1702, 1707, 1712, 1717, 4383, 4212, 4218, 4429, 1732, 1737, 4436, 892, 0}, {1702, 1707, 1712, 1717, 4383, 4212, 4218, 4429, 1732, 1737, 4436, 892, 0}, 2, 1, 11, 3, {1208,1455,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {4442, 4451, 4459, 4468, 4479, 4488, 4497}, {4504, 4508, 4512, 4516, 4520, 4524, 4528}, {1828, 1616, 1608, 1608, 4532, 2894, 1285}, {4534, 4542, 2910, 4551, 4558, 4565, 4572, 2933, 4579, 4589, 712, 4597, 0}, {4534, 4542, 2910, 4551, 4558, 4565, 4572, 2933, 4579, 4589, 712, 4597, 0}, {4606, 4610, 4512, 4614, 4618, 4622, 4626, 4630, 4634, 4638, 4642, 4646, 0}, {4606, 4610, 4512, 4614, 4618, 4622, 4626, 4630, 4634, 4638, 4642, 4646, 0}, 2, 1, 1, 3, {18,864,9,1467,857,0,0,0,0,0,0,0,0,0},{1217,1475,894,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {370, 137, 144, {4650, 4660, 4670, 4680, 4690, 4700, 4710}, {1016, 4720, 4724, 4728, 4732, 4736, 4740}, {1016, 4720, 4724, 4728, 4732, 4736, 4740}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, 0, 0, 1, 3, {406,460,439,379,417,0,0,0,0,0,0,0,0,0},{469,1484,1508,1535,1564,1588,1617,1637,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{623,1662,652,0,0,0,0,0}}, + {1680, 151, 158, {4771, 4781, 4791, 4801, 4811, 4821, 4831}, {4841, 4845, 4849, 4853, 4857, 4861, 4865}, {4841, 4845, 4849, 4853, 4857, 4861, 4865}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, 0, 0, 55, 3, {417,1690,446,388,0,0,0,0,0,0,0,0,0,0},{1699,1728,1752,1779,1801,1832,1858,1889,1915,1942},{583,591,266,71,0,0,0,0,0,0,0,0},{600,611,271,89,0,0,0,0,0},{1964,1981,2000,0,0,0,0,0}}, + {109, 165, 170, {4932, 4939, 4947, 4955, 4964, 4974, 4982}, {4991, 3081, 4994, 4997, 5000, 5003, 5006}, {5009, 1608, 1828, 2735, 1828, 2894, 5009}, {5011, 5019, 5028, 1639, 5034, 1649, 1654, 5038, 1666, 1676, 1684, 1693, 0}, {5011, 5019, 5028, 1639, 5034, 1649, 1654, 5038, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 5047, 1717, 5034, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 5047, 1717, 5034, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 55, 3, {2015,1062,755,9,775,2024,417,0,0,0,0,0,0,0},{1217,1475,894,1234,0,0,0,0,0,0},{71,266,1146,2036,2048,0,0,0,0,0,0,0},{89,271,2060,2075,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {2090, 165, 170, {1525, 1533, 1540, 1548, 1555, 1563, 1570}, {5052, 5058, 5063, 5068, 5073, 5078, 5083}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, 0, 0, 11, 11, {681,1455,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {5117, 5127, 5141, 5148, 5155, 5164, 1247}, {5172, 5179, 5184, 5188, 5193, 5198, 5202}, {1278, 1280, 2735, 5207, 5210, 1280, 1285}, {5212, 5221, 5226, 5233, 1645, 5243, 5252, 5259, 5269, 5279, 1364, 5292, 0}, {5302, 5311, 5318, 5324, 5333, 5338, 5346, 5352, 5361, 5371, 5385, 5395, 0}, {5403, 5407, 4512, 5411, 1645, 5415, 5419, 5423, 5427, 5431, 1517, 5436, 0}, {5403, 5407, 4512, 5411, 1645, 5415, 5419, 5423, 5427, 5431, 1517, 5436, 0}, 2, 1, 11, 3, {681,0,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1042, 49, 52, {2803, 5440, 5454, 5467, 5480, 5493, 2850}, {4504, 5505, 5509, 5513, 5517, 5521, 5525}, {1828, 1285, 1610, 5530, 5530, 1285, 1285}, {5532, 5540, 5550, 666, 5557, 5562, 5568, 2933, 5574, 5583, 5591, 5600, 0}, {5532, 5540, 5550, 666, 5557, 5562, 5568, 2933, 5574, 5583, 5591, 5600, 0}, {5089, 5609, 4512, 5613, 3515, 5093, 5097, 4630, 4634, 5617, 4642, 5621, 0}, {5089, 5609, 4512, 5613, 3515, 5093, 5097, 4630, 4634, 5617, 4642, 5621, 0}, 0, 0, 1, 3, {18,9,295,857,755,744,1062,2015,775,681,2024,2098,1208,417},{1069,1124,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{1193,0,0,0,0,0,0,0}}, + {673, 49, 52, {5625, 5634, 3425, 5644, 5652, 5660, 5669}, {5675, 5678, 3081, 5682, 5685, 5689, 1275}, {1828, 4532, 1608, 1608, 4532, 2894, 1285}, {5692, 5700, 3504, 5707, 5714, 5719, 5729, 5737, 5743, 5753, 1684, 1693, 0}, {5692, 5700, 3504, 5707, 5714, 5719, 5729, 5737, 5743, 5753, 1684, 1693, 0}, {5761, 5768, 3504, 3579, 5714, 5774, 5781, 5737, 5786, 882, 887, 1742, 0}, {5761, 5768, 3504, 3579, 5714, 5774, 5781, 5737, 5786, 882, 887, 1742, 0}, 2, 1, 55, 3, {744,0,0,0,0,0,0,0,0,0,0,0,0,0},{2105,2134,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 165, 170, {5792, 5802, 5807, 5814, 5823, 5827, 5834}, {5845, 2863, 1712, 5850, 5823, 5855, 5860}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {5866, 5875, 5885, 5892, 3515, 5900, 5906, 1659, 5912, 5923, 5933, 5943, 0}, {5866, 5875, 5885, 5892, 3515, 5900, 5906, 1659, 5912, 5923, 5933, 5943, 0}, {5953, 1707, 1712, 1717, 3515, 5958, 5963, 1727, 2986, 882, 887, 1742, 0}, {5953, 1707, 1712, 1717, 3515, 5958, 5963, 1727, 2986, 882, 887, 1742, 0}, 0, 1, 11, 3, {681,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 175, 180, {5968, 5991, 211, 6014, 6025, 6040, 6055}, {6070, 285, 290, 295, 300, 305, 310}, {6075, 6078, 6075, 6081, 6084, 6078, 6081}, {6087, 6100, 360, 6115, 380, 6128, 6137, 401, 6146, 6163, 6178, 6191, 0}, {6206, 6219, 6234, 6245, 6258, 6265, 6274, 6283, 6298, 6315, 6330, 6343, 0}, {6358, 6366, 360, 6376, 380, 6128, 6137, 6384, 6392, 6402, 6410, 6420, 0}, {6358, 6366, 360, 6376, 380, 6128, 6137, 6384, 6392, 6402, 6410, 6420, 0}, 0, 1, 11, 3, {681,775,2098,744,9,0,0,0,0,0,0,0,0,0},{199,180,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 49, 52, {6428, 6437, 6449, 6456, 6464, 6474, 6480}, {6487, 6491, 6495, 6499, 6503, 6508, 6512}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {6527, 6537, 6546, 6554, 6562, 6570, 6577, 6584, 6592, 1364, 6598, 6606, 0}, {6615, 6625, 6634, 6642, 6650, 6658, 6665, 6672, 6681, 5385, 6687, 6697, 0}, {6706, 6710, 6715, 6720, 6724, 5419, 1501, 6728, 6732, 1517, 6736, 1521, 0}, {6706, 6710, 6715, 6720, 6724, 5419, 1501, 6728, 6732, 1517, 6736, 1521, 0}, 0, 1, 11, 3, {2151,2161,2169,2181,2193,2203,2213,417,0,0,0,0,0,0},{2225,2239,2254,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {673, 49, 52, {6740, 6748, 6757, 6764, 6771, 6780, 1247}, {1254, 1257, 6787, 1264, 6790, 6794, 1275}, {6516, 6518, 6520, 6522, 6797, 6518, 6522}, {4105, 4113, 6800, 4376, 6806, 6811, 6816, 1659, 1666, 4184, 1684, 1693, 0}, {6821, 6830, 5318, 6840, 6848, 6854, 6860, 6866, 6874, 6884, 6893, 6902, 0}, {5089, 4610, 4512, 4614, 6806, 6811, 6816, 5101, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 6806, 6811, 6816, 5101, 5105, 5109, 4642, 6911, 0}, 2, 1, 11, 3, {681,692,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 185, 197, {6915, 6922, 6931, 6940, 6952, 6960, 6969}, {6979, 6983, 2791, 6988, 6993, 6997, 7001}, {1828, 4089, 1608, 1608, 7005, 1280, 1285}, {7007, 7013, 7020, 7025, 7031, 7035, 7043, 7050, 7056, 7064, 7070, 7078, 0}, {7086, 7092, 3504, 7099, 1645, 7105, 7113, 7120, 7126, 7134, 7140, 7148, 0}, {1914, 7156, 2791, 7160, 7031, 7164, 7168, 7172, 7001, 7176, 7180, 7185, 0}, {1914, 7156, 2791, 7160, 7031, 7164, 7168, 7172, 7001, 7176, 7180, 7185, 0}, 0, 1, 11, 3, {1208,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {2274, 208, 211, {7189, 7197, 7205, 1548, 1555, 1563, 7212}, {7220, 7225, 7230, 1591, 7234, 1599, 7239}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {5011, 5019, 3504, 1639, 1645, 1649, 1654, 7244, 1666, 1676, 1684, 1693, 0}, {5011, 5019, 3504, 1639, 1645, 1649, 1654, 7244, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 3504, 1717, 1645, 1649, 1654, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 3504, 1717, 1645, 1649, 1654, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 55, 3, {417,1690,0,0,0,0,0,0,0,0,0,0,0,0},{2287,2305,0,0,0,0,0,0,0,0},{71,266,2328,0,0,0,0,0,0,0,0,0},{89,271,2338,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 0, 0, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, 0, 0, 1, 3, {295,857,9,18,304,2351,417,0,0,0,0,0,0,0},{894,2363,2379,0,0,0,0,0,0,0},{266,71,906,62,0,0,0,0,0,0,0,0},{271,89,914,77,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 214, 219, {7252, 7258, 7268, 7274, 7285, 7295, 7300}, {7310, 7314, 7318, 7322, 7327, 7331, 7335}, {1280, 1280, 1285, 7339, 1280, 5210, 5210}, {7342, 7347, 7354, 7359, 7365, 7372, 7380, 7387, 7396, 7403, 7408, 7415, 0}, {7342, 7347, 7354, 7359, 7365, 7372, 7380, 7387, 7396, 7403, 7408, 7415, 0}, {7423, 7427, 2791, 7432, 2760, 7436, 7440, 7444, 7449, 7453, 7457, 7461, 0}, {7423, 7427, 2791, 7432, 2760, 7436, 7440, 7444, 7449, 7453, 7457, 7461, 0}, 0, 1, 11, 3, {2421,304,0,0,0,0,0,0,0,0,0,0,0,0},{2431,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 49, 52, {7465, 7476, 7489, 7498, 7505, 7518, 7527}, {7465, 7476, 7489, 7498, 7505, 7518, 7527}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, 0, 0, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 49, 52, {7660, 7667, 7673, 7680, 7685, 7691, 7697}, {7703, 7707, 7711, 7715, 7719, 7723, 7727}, {1608, 1285, 1285, 7731, 3099, 2892, 1285}, {7733, 7741, 7750, 1851, 7756, 1861, 1866, 7760, 1878, 1888, 1896, 7768, 0}, {7733, 7741, 7750, 1851, 7756, 1861, 1866, 7760, 1878, 1888, 1896, 7768, 0}, {1914, 1918, 2791, 1927, 7756, 1931, 1935, 7777, 1943, 1947, 1951, 7781, 0}, {1914, 1918, 2791, 1927, 7756, 1931, 1935, 7777, 1943, 1947, 1951, 7781, 0}, 0, 0, 1, 11, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{2462,894,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 223, 228, {7785, 7798, 7817, 7834, 7847, 7860, 7877}, {280, 285, 290, 295, 300, 305, 310}, {7890, 6078, 6075, 6081, 6084, 6078, 6081}, {7893, 7906, 7917, 7934, 7949, 7964, 7979, 7992, 8007, 8024, 8039, 8056, 0}, {8071, 8082, 8095, 8110, 8123, 8136, 8149, 8160, 8173, 8188, 8201, 8220, 0}, {8233, 8240, 8247, 8254, 8261, 8268, 8275, 8282, 8289, 8296, 8303, 8310, 0}, {8233, 8240, 8247, 8254, 8261, 8268, 8275, 8282, 8289, 8296, 8303, 8310, 0}, 0, 1, 11, 3, {681,775,417,0,0,0,0,0,0,0,0,0,0,0},{2481,0,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{2499,0,0,0,0,0,0,0}}, + {109, 49, 52, {8317, 8332, 8353, 8368, 8381, 8394, 7877}, {280, 285, 8409, 295, 8414, 305, 310}, {315, 318, 8419, 324, 327, 318, 324}, {8422, 8439, 8448, 8463, 380, 8480, 8495, 8508, 8523, 8540, 8561, 8578, 0}, {8593, 8610, 8623, 8640, 6258, 8659, 8674, 8687, 8700, 8715, 8738, 8757, 0}, {8770, 8240, 8777, 8784, 380, 8791, 8798, 8805, 8289, 8812, 8819, 8826, 0}, {8770, 8240, 8777, 8784, 380, 8791, 8798, 8805, 8289, 8812, 8819, 8826, 0}, 0, 1, 11, 3, {775,0,0,0,0,0,0,0,0,0,0,0,0,0},{894,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{2515,0,0,0,0,0,0,0}}, + {673, 39, 233, {8833, 8841, 8852, 8858, 8864, 8873, 1247}, {8879, 5179, 5073, 8884, 8889, 8895, 5202}, {6516, 6518, 8900, 6522, 6524, 6518, 6522}, {1618, 1625, 6800, 1639, 1645, 8902, 8908, 8914, 1666, 1676, 1684, 1693, 0}, {1618, 1625, 6800, 1639, 1645, 8902, 8908, 8914, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 8921, 1732, 1737, 887, 1742, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 8921, 1732, 1737, 887, 1742, 0}, 0, 1, 124, 3, {2529,1455,0,0,0,0,0,0,0,0,0,0,0,0},{2541,2561,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 49, 52, {8926, 8937, 8948, 8959, 8970, 8981, 8987}, {1280, 7005, 1610, 3099, 1278, 7731, 1616}, {1280, 7005, 1610, 3099, 1278, 7731, 1616}, {8996, 9004, 9013, 9020, 3515, 9027, 9033, 1659, 1666, 9039, 1684, 9048, 0}, {8996, 9004, 9013, 9020, 3515, 9027, 9033, 1659, 1666, 9039, 1684, 9048, 0}, {9058, 9063, 9013, 4614, 3515, 9027, 9033, 5101, 9069, 5109, 4642, 9074, 0}, {9058, 9063, 9013, 4614, 3515, 9027, 9033, 5101, 9069, 5109, 4642, 9074, 0}, 2, 1, 11, 3, {681,1455,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{2575,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 238, 248, {9079, 9090, 9100, 9109, 9120, 9132, 9143}, {9153, 9161, 9168, 9174, 9182, 9191, 9199}, {1285, 1280, 1612, 1610, 5210, 1280, 1285}, {9206, 9216, 1633, 9227, 9236, 9242, 9250, 9258, 9266, 9277, 9286, 9296, 0}, {9206, 9216, 1633, 9227, 9236, 9242, 9250, 9258, 9266, 9277, 9286, 9296, 0}, {3566, 857, 1633, 1717, 9236, 9306, 9312, 1727, 2986, 1737, 887, 1742, 0}, {3566, 857, 1633, 1717, 9236, 9306, 9312, 1727, 2986, 1737, 887, 1742, 0}, 0, 1, 11, 3, {681,2583,0,0,0,0,0,0,0,0,0,0,0,0},{2603,2630,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2651,0,0,0,0,0,0,0}}, + {925, 255, 266, {9318, 9330, 9342, 9354, 9368, 9383, 9396}, {9410, 9413, 9416, 9419, 9422, 9425, 6790}, {1285, 1280, 9428, 1610, 3099, 1280, 9430}, {9433, 9440, 9448, 9454, 9463, 9472, 9482, 9488, 9499, 9509, 9516, 9526, 0}, {9534, 9541, 9549, 9554, 9565, 9575, 9585, 9592, 9604, 9613, 9620, 9631, 0}, {9641, 9647, 9652, 9657, 9662, 9667, 9674, 9680, 9686, 9692, 9698, 9705, 0}, {9641, 9647, 9652, 9657, 9662, 9667, 9674, 9680, 9686, 9692, 9698, 9705, 0}, 2, 1, 55, 3, {417,0,0,0,0,0,0,0,0,0,0,0,0,0},{2667,2695,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {1, 273, 285, {9712, 9727, 9742, 9757, 9774, 9793, 9804}, {9815, 9822, 9829, 9836, 9843, 9850, 9857}, {0, 0, 0, 0, 0, 0, 0}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, 0, 0, 11, 3, {681,775,2098,744,9,0,0,0,0,0,0,0,0,0},{2727,2745,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 297, 304, {10057, 10070, 10083, 10099, 10116, 10131, 10140}, {10057, 10070, 10083, 10099, 10116, 10131, 10140}, {10149, 10152, 10155, 10158, 10161, 10164, 10167}, {10170, 10183, 10194, 10203, 10214, 10219, 10228, 10239, 10246, 10261, 10272, 10285, 0}, {10298, 10313, 10194, 10203, 10326, 10219, 10333, 10239, 10246, 10261, 10272, 10285, 0}, {10170, 10183, 10194, 10203, 10214, 10219, 10228, 10239, 10246, 10261, 10272, 10285, 0}, {10170, 10183, 10194, 10203, 10214, 10219, 10228, 10239, 10246, 10261, 10272, 10285, 0}, 0, 6, 1, 3, {18,9,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{62,71,0,0,0,0,0,0,0,0,0,0},{77,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 311, 314, {10346, 10359, 10369, 10378, 10388, 10399, 10410}, {10422, 10425, 10430, 10435, 10440, 10445, 10450}, {10422, 10455, 10458, 10461, 10464, 10467, 10470}, {10473, 10482, 10491, 10500, 10509, 10518, 10527, 10536, 10545, 10554, 10564, 10574, 0}, {10584, 10593, 10602, 10611, 10620, 10629, 10638, 10647, 10656, 10665, 10675, 10685, 0}, {10695, 10701, 10707, 10713, 10719, 10725, 10731, 10737, 10743, 10749, 10756, 10763, 0}, {10695, 10701, 10707, 10713, 10719, 10725, 10731, 10737, 10743, 10749, 10756, 10763, 0}, 0, 1, 1, 3, {18,9,755,744,417,0,0,0,0,0,0,0,0,0},{1261,0,0,0,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 317, 322, {10770, 10783, 10804, 10823, 10844, 10863, 10876}, {10887, 10894, 10901, 10908, 10915, 10922, 10929}, {10936, 10939, 10939, 10942, 10945, 10948, 10951}, {10954, 10969, 10984, 10993, 11004, 11015, 11028, 11041, 11056, 11075, 11094, 11111, 0}, {11130, 11147, 11164, 11175, 11188, 11201, 11216, 11231, 11248, 11269, 11290, 11309, 0}, {11330, 11337, 11344, 11351, 11358, 11365, 11372, 11379, 11386, 11393, 11400, 11407, 0}, {11330, 11337, 11344, 11351, 11358, 11365, 11372, 11379, 11386, 11393, 11400, 11407, 0}, 0, 1, 11, 3, {681,775,2764,18,2774,864,417,0,0,0,0,0,0,0},{1029,876,2462,1261,2785,2796,2808,2825,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 49, 52, {11414, 11420, 11434, 11457, 11471, 11487, 11494}, {11503, 11506, 11511, 11517, 11521, 11526, 11529}, {4756, 4744, 4746, 4748, 4750, 4752, 4754}, {11533, 11540, 7354, 11547, 2760, 11553, 11559, 11565, 11572, 11581, 11589, 11596, 0}, {11603, 11610, 11617, 11622, 11628, 11632, 11637, 11642, 11649, 11658, 11666, 11673, 0}, {11680, 5609, 4512, 4614, 11628, 11684, 11688, 11692, 11696, 5109, 11700, 11704, 0}, {11680, 5609, 4512, 4614, 11628, 11684, 11688, 11692, 11696, 5109, 11700, 11704, 0}, 0, 0, 11, 3, {681,304,0,0,0,0,0,0,0,0,0,0,0,0},{2843,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {11708, 11716, 11727, 11737, 11748, 11757, 11766}, {11776, 11780, 11784, 11788, 11792, 11796, 11800}, {11804, 9428, 9428, 9428, 1612, 1612, 1616}, {11806, 11816, 11824, 11832, 11840, 11848, 11855, 11863, 11871, 11878, 11884, 11891, 0}, {11806, 11899, 11907, 11915, 11923, 11931, 11938, 11946, 11954, 11961, 11967, 11974, 0}, {11982, 11987, 1712, 11992, 11997, 12002, 12007, 12012, 12017, 12022, 12027, 12032, 0}, {11982, 11987, 1712, 11992, 11997, 12002, 12007, 12012, 12017, 12022, 12027, 12032, 0}, 2, 1, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2872,2899,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2920,0,0,0,0,0,0,0}}, + {673, 327, 338, {12037, 12047, 12058, 12065, 12072, 12082, 1247}, {12088, 12092, 12097, 12101, 12105, 12110, 12114}, {6516, 6518, 12118, 6522, 6797, 6518, 6522}, {1618, 1625, 12120, 12126, 12132, 8902, 8908, 12137, 1666, 1676, 12144, 1693, 0}, {12153, 12161, 12170, 12177, 12184, 12189, 12196, 12203, 6874, 12211, 12219, 6902, 0}, {5089, 4610, 12228, 4614, 12233, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, {5089, 4610, 12228, 4614, 12233, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, 2, 1, 11, 3, {1208,0,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{2939,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 349, 363, {12245, 190, 211, 6014, 12258, 12275, 12286}, {12299, 12307, 12315, 12323, 12331, 12339, 12347}, {315, 318, 321, 324, 327, 318, 324}, {12355, 343, 360, 369, 12370, 12377, 12386, 401, 414, 433, 450, 465, 0}, {12355, 343, 360, 369, 12370, 12377, 12386, 401, 414, 433, 450, 465, 0}, {12395, 12403, 12411, 6376, 12370, 12419, 12427, 6384, 12435, 6402, 12445, 6420, 0}, {12395, 12403, 12411, 6376, 12370, 12419, 12427, 6384, 12435, 6402, 12445, 6420, 0}, 0, 1, 11, 3, {2953,0,0,0,0,0,0,0,0,0,0,0,0,0},{2462,1261,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2963,0,0,0,0,0,0,0}}, + {925, 0, 0, {12455, 12463, 12472, 12481, 12490, 12497, 12507}, {12516, 12520, 12524, 12528, 12532, 12535, 12539}, {0, 0, 0, 0, 0, 0, 0}, {12543, 12554, 12562, 12572, 12578, 12590, 12599, 12605, 12611, 12619, 12628, 12640, 0}, {12543, 12554, 12562, 12572, 12578, 12590, 12599, 12605, 12611, 12619, 12628, 12640, 0}, {12648, 12652, 12656, 12660, 12664, 1914, 12668, 12672, 12676, 12680, 12684, 12688, 0}, {12648, 12652, 12656, 12660, 12664, 1914, 12668, 12672, 12676, 12680, 12684, 12688, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 0, 0, {12692, 12698, 12711, 12722, 12733, 12742, 12754}, {12516, 12764, 12768, 12772, 12532, 12776, 12780}, {0, 0, 0, 0, 0, 0, 0}, {12784, 12792, 12804, 12816, 12828, 12838, 12850, 12859, 12867, 12875, 12885, 12892, 0}, {12784, 12792, 12804, 12816, 12828, 12838, 12850, 12859, 12867, 12875, 12885, 12892, 0}, {2707, 12906, 12910, 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12942, 12946, 0}, {2707, 12906, 12910, 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12942, 12946, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 0, 0, {12950, 12957, 12472, 12968, 12490, 12977, 12988}, {12688, 12998, 12524, 12528, 12532, 13002, 13006}, {0, 0, 0, 0, 0, 0, 0}, {13010, 13020, 13029, 13037, 13046, 13059, 13071, 13078, 13085, 13092, 13102, 13114, 0}, {13010, 13020, 13029, 13037, 13046, 13059, 13071, 13078, 13085, 13092, 13102, 13114, 0}, {13127, 12776, 13131, 13135, 12664, 13139, 13143, 12672, 13147, 13151, 13155, 13159, 0}, {13127, 12776, 13131, 13135, 12664, 13139, 13143, 12672, 13147, 13151, 13155, 13159, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 0, 0, {13163, 13168, 13174, 13184, 13196, 13204, 13215}, {13224, 13228, 13232, 13236, 13240, 12535, 13244}, {0, 0, 0, 0, 0, 0, 0}, {13248, 13258, 13268, 13275, 13282, 1861, 13287, 13294, 13301, 13310, 13318, 13326, 0}, {13248, 13258, 13268, 13275, 13282, 1861, 13287, 13294, 13301, 13310, 13318, 13326, 0}, {1914, 1918, 13006, 13334, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, {1914, 1918, 13006, 13334, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 49, 52, {13350, 13357, 13369, 13380, 13393, 13402, 13414}, {12516, 13424, 13428, 13236, 13240, 12535, 13244}, {1285, 1608, 13432, 1610, 1285, 4089, 1608}, {13434, 13258, 13443, 13449, 13282, 1861, 13287, 13294, 13457, 13310, 13318, 13326, 0}, {13467, 13258, 13443, 13449, 13282, 1861, 13287, 13294, 13457, 13310, 13318, 13326, 0}, {1914, 1918, 13478, 13482, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, {1914, 1918, 13478, 13482, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, 0, 0, 1, 3, {932,3009,0,0,0,0,0,0,0,0,0,0,0,0},{978,997,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 373, 377, {13486, 13493, 13501, 13509, 13518, 13528, 13535}, {13544, 13548, 13552, 13556, 13560, 13564, 13568}, {1285, 1608, 1828, 2735, 1828, 2894, 1285}, {13572, 13581, 13591, 1851, 7756, 13597, 13603, 13609, 1878, 1888, 1896, 7768, 0}, {13572, 13581, 13591, 1851, 7756, 13597, 13603, 13609, 1878, 1888, 1896, 7768, 0}, {13618, 13623, 13628, 13633, 7756, 13638, 13643, 13648, 13653, 13658, 13663, 13668, 0}, {13618, 13623, 13628, 13633, 7756, 13638, 13643, 13648, 13653, 13658, 13663, 13668, 0}, 0, 0, 55, 3, {417,2351,0,0,0,0,0,0,0,0,0,0,0,0},{2462,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {13673, 13689, 13714, 13742, 13770, 13798, 13826}, {13845, 13855, 13865, 13875, 13885, 13895, 13905}, {13915, 13919, 13923, 13919, 13927, 13931, 13935}, {13939, 13961, 13989, 14005, 14024, 14040, 14059, 14078, 14100, 14131, 14159, 14184, 0}, {13939, 13961, 13989, 14005, 14024, 14040, 14059, 14078, 14100, 14131, 14159, 14184, 0}, {14212, 14222, 14232, 14242, 14252, 14262, 14272, 14282, 14292, 14302, 14312, 14322, 0}, {14212, 14222, 14232, 14242, 14252, 14262, 14272, 14282, 14292, 14302, 14312, 14322, 0}, 0, 1, 11, 3, {681,3021,0,0,0,0,0,0,0,0,0,0,0,0},{42,1029,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 49, 52, {4231, 14332, 14343, 14353, 14363, 14373, 14387}, {14399, 14403, 14408, 14413, 14417, 14422, 14427}, {1285, 1608, 1610, 1608, 4089, 1614, 1616}, {1618, 1625, 3504, 4376, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {1618, 1625, 3504, 4376, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, 2, 1, 55, 3, {744,0,0,0,0,0,0,0,0,0,0,0,0,0},{1314,1455,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {1, 381, 409, {14431, 14450, 14469, 14491, 14510, 14532, 14557}, {14576, 14586, 14596, 14609, 14619, 14632, 14648}, {14658, 14662, 14669, 14676, 14683, 14690, 14697}, {14701, 14717, 14736, 14752, 14771, 14778, 14788, 14804, 14820, 14839, 14861, 14877, 0}, {14701, 14717, 14736, 14752, 14771, 14778, 14788, 14804, 14820, 14839, 14861, 14877, 0}, {14896, 14906, 14736, 14752, 14771, 14778, 14919, 14932, 14942, 14955, 14974, 14984, 0}, {14896, 14906, 14736, 14752, 14771, 14778, 14919, 14932, 14942, 14955, 14974, 14984, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {3033, 49, 52, {14997, 15006, 15015, 15025, 15035, 15045, 15057}, {15065, 15070, 15074, 15078, 15082, 15087, 15092}, {15096, 15100, 15103, 15106, 15109, 15113, 15117}, {15120, 15127, 15132, 1851, 15138, 15144, 15151, 15157, 15165, 15175, 15183, 15192, 0}, {15120, 15127, 15132, 1851, 15138, 15144, 15151, 15157, 15165, 15175, 15183, 15192, 0}, {1914, 15202, 2791, 1927, 15206, 15210, 15215, 15219, 15223, 15227, 1951, 15231, 0}, {1914, 15202, 2791, 1927, 15206, 15210, 15215, 15219, 15223, 15227, 1951, 15231, 0}, 0, 0, 1, 3, {18,2351,0,0,0,0,0,0,0,0,0,0,0,0},{3048,3074,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{3094,0,0,0,0,0,0,0}}, + {925, 431, 436, {15236, 15248, 15259, 15273, 15285, 15295, 15305}, {15316, 15321, 15326, 15331, 15336, 15341, 15346}, {1285, 2894, 1608, 4532, 1828, 13432, 1616}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, 2, 1, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {109, 165, 170, {15579, 15593, 15603, 15614, 15628, 15639, 15650}, {15663, 15668, 15673, 15680, 15686, 15692, 15698}, {1828, 1616, 1608, 5210, 1828, 9428, 1285}, {15703, 15711, 15719, 15726, 15735, 15745, 15755, 15761, 15769, 15784, 15802, 15810, 0}, {15703, 15711, 15719, 15726, 15735, 15745, 15755, 15761, 15769, 15784, 15802, 15810, 0}, {15818, 15822, 15719, 15828, 15832, 15837, 15755, 15843, 15848, 15855, 15862, 15867, 0}, {15818, 15822, 15719, 15828, 15832, 15837, 15755, 15843, 15848, 15855, 15862, 15867, 0}, 2, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 441, 444, {15872, 15877, 7673, 7680, 15883, 15890, 7697}, {15897, 15901, 7711, 7715, 15905, 7723, 7727}, {9428, 11804, 1285, 7731, 3099, 2892, 1285}, {7733, 7741, 15909, 1851, 7756, 1931, 15913, 15919, 1878, 1888, 1896, 15924, 0}, {7733, 7741, 15909, 1851, 7756, 1931, 15913, 15919, 1878, 1888, 1896, 15924, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 15933, 1943, 1947, 1951, 13346, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 15933, 1943, 1947, 1951, 13346, 0}, 0, 1, 1, 3, {2764,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {15937, 15954, 15971, 15988, 16005, 16022, 16031}, {16042, 16047, 16052, 16057, 16062, 16067, 16072}, {16077, 16080, 6081, 6081, 16083, 16077, 6081}, {16086, 16099, 16110, 16123, 16134, 16145, 16158, 16169, 16180, 16197, 16208, 16221, 0}, {16240, 16253, 16264, 16277, 16288, 16299, 16312, 16323, 16334, 16351, 16362, 16375, 0}, {16394, 16402, 16410, 16418, 16426, 16434, 16442, 16450, 16458, 16466, 16474, 16482, 0}, {16394, 16402, 16410, 16418, 16426, 16434, 16442, 16450, 16458, 16466, 16474, 16482, 0}, 0, 1, 1, 3, {18,3112,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3125, 448, 453, {16490, 16507, 16524, 16541, 16558, 16575, 16584}, {16597, 16605, 16613, 16623, 16633, 16575, 16643}, {16077, 16080, 16651, 16651, 16083, 16077, 16654}, {16657, 16670, 9888, 16685, 9908, 16698, 16707, 9929, 16716, 16733, 16748, 16761, 0}, {6087, 6100, 360, 6115, 380, 6128, 6137, 401, 6146, 6163, 6178, 6191, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, 0, 1, 55, 3, {3132,0,0,0,0,0,0,0,0,0,0,0,0,0},{3141,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{3160,0,0,0,0,0,0,0}}, + {109, 49, 52, {16776, 16785, 16794, 16802, 16811, 16820, 16827}, {16776, 16785, 16794, 16802, 16811, 16820, 16827}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {7733, 7741, 16836, 16842, 7756, 1861, 15913, 16849, 13301, 16856, 13318, 16863, 0}, {7733, 7741, 16836, 16842, 7756, 1861, 15913, 16849, 13301, 16856, 13318, 16863, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 16871, 1943, 1947, 1951, 7781, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 16871, 1943, 1947, 1951, 7781, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 0, 0, {16875, 16886, 16895, 16904, 16915, 16925, 16930}, {16937, 16941, 16944, 16947, 16951, 9416, 16954}, {16958, 1828, 1285, 7339, 1280, 9428, 16961}, {16964, 16972, 11617, 11622, 16979, 16984, 16990, 12137, 16996, 17006, 17015, 11673, 0}, {16964, 16972, 11617, 11622, 16979, 16984, 16990, 12137, 16996, 17006, 17015, 11673, 0}, {17023, 17028, 11617, 4614, 16979, 16984, 16990, 12237, 11696, 5109, 17032, 11704, 0}, {17023, 17028, 11617, 4614, 16979, 16984, 16990, 12237, 11696, 5109, 17032, 11704, 0}, 0, 1, 11, 3, {3176,681,0,0,0,0,0,0,0,0,0,0,0,0},{3191,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{3223,0,0,0,0,0,0,0}}, + {925, 458, 461, {17037, 17047, 17056, 17065, 17076, 17086, 17091}, {17098, 17102, 17107, 17112, 17117, 7723, 17121}, {17126, 1828, 1285, 5210, 1280, 2892, 1285}, {11533, 11540, 7354, 11547, 2760, 17128, 17133, 17138, 17145, 17153, 11589, 11596, 0}, {11603, 11610, 11617, 11622, 11628, 11632, 11637, 8914, 17160, 17168, 11666, 11673, 0}, {12906, 17175, 2791, 1927, 2760, 17179, 17183, 17187, 7707, 1947, 17191, 17195, 0}, {12906, 17175, 2791, 1927, 2760, 17179, 17183, 17187, 7707, 1947, 17191, 17195, 0}, 0, 0, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3239,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {109, 49, 52, {17199, 17218, 17237, 17262, 17281, 17315, 17340}, {17359, 17369, 17379, 17395, 17405, 17430, 17446}, {17456, 17460, 17467, 17471, 17478, 17485, 17492}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, 0, 1, 55, 11, {755,1062,744,755,744,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{1151,1146,3258,3267,0,0,0,0,0,0,0,0},{1173,1165,3275,3287,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 464, 479, {17742, 17758, 17777, 17799, 17821, 17840, 17868}, {17899, 17906, 17916, 17929, 17942, 17952, 17971}, {17993, 17997, 18004, 18011, 18021, 18028, 18041}, {18048, 18064, 18083, 18096, 18115, 18122, 18132, 18148, 18161, 18177, 18196, 18212, 0}, {18048, 18064, 18083, 18096, 18115, 18122, 18132, 18148, 18161, 18177, 18196, 18212, 0}, {18228, 18235, 18083, 18245, 18115, 18122, 18261, 18274, 18281, 18291, 18304, 18314, 0}, {18228, 18235, 18083, 18245, 18115, 18122, 18261, 18274, 18281, 18291, 18304, 18314, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{3298,894,0,0,0,0,0,0,0,0},{591,583,266,71,0,0,0,0,0,0,0,0},{611,600,271,89,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 49, 52, {18324, 18343, 18362, 18384, 18403, 18425, 18450}, {18469, 18479, 18489, 18502, 18512, 18525, 18541}, {18551, 18555, 18562, 18569, 18576, 18583, 18590}, {18594, 18622, 18650, 18666, 18685, 18692, 18702, 18718, 18734, 18762, 18784, 18806, 0}, {18594, 18622, 18650, 18666, 18685, 18692, 18702, 18718, 18734, 18762, 18784, 18806, 0}, {18831, 18850, 18650, 18666, 18685, 18692, 18702, 18718, 18869, 18885, 18901, 18911, 0}, {18831, 18850, 18650, 18666, 18685, 18692, 18702, 18718, 18869, 18885, 18901, 18911, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 5, 8, {18924, 18943, 18962, 18987, 19006, 19028, 19053}, {19072, 19082, 19092, 19108, 19118, 19131, 19147}, {19157, 19161, 19168, 19172, 19179, 19186, 19193}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 494, 519, {19431, 19450, 19472, 19497, 19513, 19535, 19554}, {19564, 19578, 19592, 19606, 19617, 19631, 19554}, {19645, 19652, 19659, 19666, 19673, 19680, 19687}, {19691, 19707, 19732, 19751, 19770, 19777, 19790, 19803, 19822, 19853, 19878, 19900, 0}, {19691, 19707, 19732, 19751, 19770, 19777, 19790, 19803, 19822, 19853, 19878, 19900, 0}, {19925, 19933, 19947, 19961, 19770, 19777, 19790, 19972, 19980, 19994, 20005, 20013, 0}, {19925, 19933, 19947, 19961, 19770, 19777, 19790, 19972, 19980, 19994, 20005, 20013, 0}, 0, 1, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {20024, 20046, 20068, 20093, 20115, 20140, 20168}, {20190, 20200, 20210, 20223, 20233, 20246, 20262}, {20272, 20276, 20283, 20287, 20294, 20301, 20308}, {20312, 20328, 20353, 20372, 20394, 20401, 20414, 20427, 20446, 20477, 20502, 20521, 0}, {20312, 20328, 20353, 20372, 20394, 20401, 20414, 20427, 20446, 20477, 20502, 20521, 0}, {20546, 20553, 20353, 20569, 20394, 20401, 20414, 20427, 20585, 20607, 20623, 20633, 0}, {20546, 20553, 20353, 20569, 20394, 20401, 20414, 20427, 20585, 20607, 20623, 20633, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 544, 572, {20649, 20671, 20690, 20712, 20731, 20753, 20778}, {20797, 20810, 20820, 20833, 20843, 20856, 20872}, {20882, 20889, 20896, 20903, 20910, 20917, 20924}, {20928, 20944, 20969, 20988, 21010, 21017, 21030, 21043, 21062, 21093, 21118, 21140, 0}, {20928, 20944, 20969, 20988, 21010, 21017, 21030, 21043, 21062, 21093, 21118, 21140, 0}, {21165, 21172, 20969, 21188, 21010, 21017, 21030, 21204, 21211, 21233, 21249, 21262, 0}, {21165, 21172, 20969, 21188, 21010, 21017, 21030, 21204, 21211, 21233, 21249, 21262, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {3316, 49, 52, {21278, 21306, 21340, 21368, 21396, 21427, 21464}, {21492, 21505, 21524, 21540, 21553, 21572, 21591}, {21601, 21608, 21615, 21622, 21629, 21642, 21649}, {21653, 21672, 21700, 21722, 21741, 21754, 21764, 21777, 21802, 21833, 21858, 21874, 0}, {21653, 21672, 21700, 21722, 21741, 21754, 21764, 21777, 21802, 21833, 21858, 21874, 0}, {21893, 21903, 21922, 21932, 21741, 21754, 21764, 21948, 21955, 21980, 21996, 22006, 0}, {21893, 21903, 21922, 21932, 21741, 21754, 21764, 21948, 21955, 21980, 21996, 22006, 0}, 0, 0, 55, 11, {755,1062,775,2098,0,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{1151,1146,3258,3267,0,0,0,0,0,0,0,0},{1173,1165,3275,3287,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 594, 622, {22019, 22038, 22057, 22082, 22101, 22135, 22160}, {22179, 17369, 17379, 17395, 22189, 22214, 17446}, {0, 0, 0, 0, 0, 0, 0}, {22230, 22255, 22286, 22302, 17593, 17600, 17610, 22321, 22337, 22368, 22390, 22412, 0}, {22230, 22255, 22286, 22302, 17593, 17600, 17610, 22321, 22337, 22368, 22390, 22412, 0}, {22437, 22450, 22286, 22302, 17593, 17600, 17610, 22469, 22476, 22492, 22508, 22518, 0}, {22437, 22450, 22286, 22302, 17593, 17600, 17610, 22469, 22476, 22492, 22508, 22518, 0}, 0, 0, 55, 3, {744,0,0,0,0,0,0,0,0,0,0,0,0,0},{3324,0,0,0,0,0,0,0,0,0},{583,591,266,0,0,0,0,0,0,0,0,0},{600,611,271,0,0,0,0,0,0},{3343,3351,0,0,0,0,0,0}}, + {1, 644, 656, {14431, 14450, 22531, 14491, 14510, 14532, 14557}, {14576, 14586, 22553, 14609, 14619, 14632, 14648}, {14658, 14662, 14669, 14676, 14683, 14690, 14697}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 22661, 22677, 22702, 22724, 22752, 0}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 22661, 22677, 22702, 22724, 22752, 0}, {22774, 22787, 14736, 22806, 22641, 14778, 22648, 22822, 22829, 22848, 22864, 22886, 0}, {22774, 22787, 14736, 22806, 22641, 14778, 22648, 22822, 22829, 22848, 22864, 22886, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 665, 670, {22902, 22909, 22920, 22933, 22946, 22957, 22970}, {22981, 22986, 22991, 22996, 23001, 23006, 23011}, {22981, 22986, 22991, 22996, 23001, 23006, 23011}, {23016, 23042, 23070, 23100, 23130, 23156, 23186, 23212, 23240, 23264, 23292, 23329, 0}, {23016, 23042, 23070, 23100, 23130, 23156, 23186, 23212, 23240, 23264, 23292, 23329, 0}, {23368, 23380, 23392, 23404, 23416, 23428, 23440, 23452, 23464, 23476, 23489, 23502, 0}, {23368, 23380, 23392, 23404, 23416, 23428, 23440, 23452, 23464, 23476, 23489, 23502, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3361,3399,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {3431, 675, 697, {23515, 23543, 23571, 23608, 23639, 23673, 23704}, {23738, 23754, 23770, 23795, 23814, 23836, 23855}, {23877, 23884, 23891, 23901, 23911, 23921, 23931}, {23944, 23978, 24015, 24052, 24086, 24117, 24154, 24191, 24231, 24265, 24299, 24348, 0}, {24397, 24428, 24462, 24496, 24527, 24555, 24589, 24623, 24660, 24691, 24722, 24768, 0}, {24814, 24827, 24840, 24853, 24866, 24879, 24892, 24905, 24918, 24931, 24947, 24963, 0}, {24814, 24827, 24840, 24853, 24866, 24879, 24892, 24905, 24918, 24931, 24947, 24963, 0}, 0, 0, 1, 3, {379,388,397,428,417,406,446,439,453,0,0,0,0,0},{3455,3498,3546,3578,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{3615,666,0,0,0,0,0,0}}, + {109, 722, 725, {24979, 24988, 24998, 25010, 25023, 25032, 25044}, {25056, 25060, 12926, 25065, 25069, 25073, 25077}, {1285, 25081, 1608, 1608, 11804, 4532, 1285}, {25084, 25091, 25100, 25107, 1857, 25114, 25122, 25133, 25138, 25143, 25150, 25159, 0}, {25084, 25091, 25100, 25107, 1857, 25114, 25122, 25133, 25138, 25143, 25150, 25159, 0}, {25167, 25171, 12926, 25175, 1857, 25179, 25183, 25133, 25138, 25187, 25191, 25196, 0}, {25167, 25171, 12926, 25175, 1857, 25179, 25183, 25133, 25138, 25187, 25191, 25196, 0}, 2, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {25201, 25223, 25239, 25258, 25268, 25299, 25315}, {25201, 25223, 25239, 25258, 25268, 25299, 25315}, {25328, 25332, 25328, 25336, 25336, 25340, 25340}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, 0, 0, 1, 3, {9,417,0,0,0,0,0,0,0,0,0,0,0,0},{894,2363,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{3648,0,0,0,0,0,0,0}}, + {109, 728, 753, {25533, 25558, 25577, 25605, 25624, 25649, 25668}, {25690, 25706, 25716, 25735, 25745, 25761, 25771}, {25784, 25791, 25795, 25799, 25803, 25810, 25817}, {25821, 25840, 25856, 25869, 25882, 25904, 25923, 25945, 25961, 25977, 25990, 26006, 0}, {25821, 25840, 25856, 25869, 25882, 25904, 25923, 25945, 25961, 25977, 25990, 26006, 0}, {26022, 26031, 26040, 26049, 26058, 26067, 26079, 26088, 26097, 26106, 26115, 26124, 0}, {26022, 26031, 26040, 26049, 26058, 26067, 26079, 26088, 26097, 26106, 26115, 26124, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{3683,894,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 778, 794, {26133, 26161, 26183, 26202, 26227, 26252, 26271}, {26133, 26161, 26183, 26202, 26227, 26252, 26271}, {26281, 26281, 26285, 26289, 26293, 26297, 26301}, {26305, 26330, 26361, 26371, 26384, 26391, 26404, 26426, 26442, 26467, 26498, 26523, 0}, {26305, 26330, 26361, 26371, 26384, 26391, 26404, 26426, 26442, 26467, 26498, 26523, 0}, {26545, 26555, 26361, 26562, 26384, 26391, 26566, 26573, 26577, 26587, 26603, 26613, 0}, {26545, 26555, 26361, 26562, 26384, 26391, 26566, 26573, 26577, 26587, 26603, 26613, 0}, 0, 0, 55, 3, {744,304,0,0,0,0,0,0,0,0,0,0,0,0},{3710,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 165, 170, {2803, 26620, 2817, 26625, 26635, 26641, 2850}, {26648, 26653, 26658, 26663, 26669, 26674, 26679}, {1828, 1616, 1608, 1608, 2890, 2894, 1285}, {26685, 26693, 26702, 26708, 26714, 26719, 26725, 26731, 26738, 26747, 26755, 26764, 0}, {26773, 26781, 2910, 666, 5557, 26790, 26796, 2933, 5574, 5583, 5591, 26802, 0}, {26811, 13623, 26658, 26816, 26714, 26719, 26821, 26826, 26831, 26836, 13663, 26841, 0}, {26811, 13623, 26658, 26816, 26714, 26719, 26821, 26826, 26831, 26836, 13663, 26841, 0}, 2, 1, 1, 3, {18,3021,0,0,0,0,0,0,0,0,0,0,0,0},{1314,1261,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 644, 804, {26846, 14450, 26874, 14491, 14510, 14532, 14557}, {14576, 14586, 22553, 14609, 14619, 14632, 14648}, {0, 0, 0, 0, 0, 0, 0}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 26893, 26909, 26937, 22724, 22752, 0}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 26893, 26909, 26937, 22724, 22752, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 816, 828, {26959, 26975, 26991, 27019, 27035, 27078, 27103}, {26959, 26975, 27131, 27019, 27141, 27163, 27176}, {27186, 27190, 27194, 27198, 27202, 27215, 27222}, {27229, 27248, 27273, 27292, 27317, 27330, 27343, 27356, 27378, 27412, 27437, 27465, 0}, {27229, 27248, 27273, 27292, 27317, 27330, 27343, 27356, 27378, 27412, 27437, 27465, 0}, {27493, 27500, 27510, 27292, 27317, 27330, 27343, 27523, 27533, 27546, 27556, 27569, 0}, {27493, 27500, 27510, 27292, 27317, 27330, 27343, 27523, 27533, 27546, 27556, 27569, 0}, 0, 1, 55, 11, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{3267,71,0,0,0,0,0,0,0,0,0,0},{3287,89,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 837, 847, {27582, 27604, 27626, 27642, 27658, 27674, 27693}, {27715, 27725, 27735, 27745, 27755, 27765, 27775}, {27785, 27789, 27793, 27797, 27801, 27805, 27809}, {27813, 27829, 27839, 27849, 27859, 27875, 27888, 27901, 27911, 27924, 27937, 27950, 0}, {27813, 27829, 27839, 27849, 27859, 27875, 27888, 27901, 27911, 27924, 27937, 27950, 0}, {27963, 27970, 27977, 27984, 27991, 27998, 28005, 28012, 28019, 28026, 28033, 28040, 0}, {27963, 27970, 27977, 27984, 27991, 27998, 28005, 28012, 28019, 28026, 28033, 28040, 0}, 0, 0, 1, 3, {932,941,948,957,460,417,968,0,0,0,0,0,0,0},{3731,3750,42,2448,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 866, 876, {28047, 28057, 28064, 28077, 28087, 28097, 28107}, {28047, 28057, 28117, 28077, 28087, 28097, 28107}, {28127, 28131, 28135, 28139, 28143, 28147, 28151}, {28155, 28171, 28187, 28197, 28210, 28217, 28224, 28234, 28247, 28266, 28282, 28298, 0}, {28155, 28171, 28187, 28197, 28210, 28217, 28224, 28234, 28247, 28266, 28282, 28298, 0}, {28314, 28324, 28187, 28334, 28210, 28217, 28224, 28344, 28354, 28364, 28374, 28384, 0}, {28314, 28324, 28187, 28334, 28210, 28217, 28224, 28344, 28354, 28364, 28374, 28384, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 889, 899, {28394, 28401, 28407, 28414, 28420, 28426, 28434}, {28444, 28448, 28452, 28456, 28460, 28464, 28468}, {9428, 9428, 9428, 9428, 9428, 9428, 9428}, {28474, 28483, 7020, 28492, 28498, 28504, 28510, 28517, 28523, 28532, 28541, 28549, 0}, {28474, 28483, 7020, 28492, 28498, 28504, 28510, 28517, 28523, 28532, 28541, 28549, 0}, {28558, 28562, 2791, 28566, 2760, 28570, 28574, 28578, 28583, 28587, 28593, 28597, 0}, {28558, 28562, 2791, 28566, 2760, 28570, 28574, 28578, 28583, 28587, 28593, 28597, 0}, 0, 0, 55, 3, {744,755,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 381, 409, {28601, 28620, 28639, 28664, 28683, 28705, 28730}, {28749, 14586, 28759, 14609, 28775, 14632, 14648}, {28788, 14662, 28792, 14676, 28796, 14690, 14697}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 14771, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, 0, 0, 1, 3, {932,941,948,957,460,417,968,0,0,0,0,0,0,0},{3763,3783,42,2448,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{3351,0,0,0,0,0,0,0}}, + {109, 49, 52, {28979, 28985, 28993, 29001, 29010, 29021, 29027}, {29033, 29036, 3084, 4997, 3090, 29039, 1275}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {29042, 29053, 13591, 1851, 29064, 29070, 2769, 13609, 29075, 1888, 29085, 29094, 0}, {29042, 29053, 13591, 1851, 29064, 29070, 2769, 13609, 29075, 1888, 29085, 29094, 0}, {1914, 1918, 29103, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 7781, 0}, {1914, 1918, 29103, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 7781, 0}, 2, 1, 55, 3, {744,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 0, 0, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, 0, 6, 1, 3, {379,417,0,0,0,0,0,0,0,0,0,0,0,0},{894,1217,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {29221, 29228, 29234, 29241, 29252, 29260, 29269}, {29276, 29280, 2791, 29284, 29288, 29292, 7727}, {29276, 29280, 2791, 29284, 29288, 29292, 7727}, {29296, 29302, 29310, 26708, 29316, 29321, 29327, 26731, 29333, 29343, 29351, 29361, 0}, {29296, 29302, 29310, 26708, 29316, 29321, 29327, 26731, 29333, 29343, 29351, 29361, 0}, {29371, 29375, 2791, 29379, 2760, 29383, 29387, 16871, 15223, 1947, 29391, 13346, 0}, {29371, 29375, 2791, 29379, 2760, 29383, 29387, 16871, 15223, 1947, 29391, 13346, 0}, 0, 0, 1, 3, {932,3009,0,0,0,0,0,0,0,0,0,0,0,0},{978,997,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 912, 919, {29395, 29400, 29408, 29417, 29427, 29437, 29444}, {29455, 29459, 29464, 12088, 29468, 29472, 29476}, {29480, 29482, 29484, 6516, 6516, 29484, 29486}, {29488, 29494, 29500, 29506, 29514, 29521, 29527, 29533, 29538, 29545, 29554, 29560, 0}, {29488, 29494, 29500, 29506, 29514, 29521, 29527, 29533, 29538, 29545, 29554, 29560, 0}, {29566, 29570, 29574, 29578, 29582, 29586, 29590, 29594, 29598, 29602, 29606, 29610, 0}, {29566, 29570, 29574, 29578, 29582, 29586, 29590, 29594, 29598, 29602, 29606, 29610, 0}, 0, 0, 1, 3, {18,9,775,755,417,0,0,0,0,0,0,0,0,0},{1217,1234,894,0,0,0,0,0,0,0},{71,266,1151,1243,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {29614, 29621, 29629, 29636, 29643, 29651, 29660}, {29667, 29671, 29675, 29679, 29683, 7723, 28444}, {1616, 1616, 1610, 1616, 9428, 2892, 9428}, {29687, 29695, 29705, 29711, 29719, 29724, 29729, 29734, 29741, 16856, 29749, 29757, 0}, {29687, 29695, 29705, 29711, 29719, 29724, 29729, 29734, 29741, 16856, 29749, 29757, 0}, {1914, 29765, 2791, 29769, 2760, 28570, 28574, 29773, 2731, 1947, 29777, 13346, 0}, {1914, 29765, 2791, 29769, 2760, 28570, 28574, 29773, 2731, 1947, 29777, 13346, 0}, 0, 0, 1, 3, {295,3021,0,0,0,0,0,0,0,0,0,0,0,0},{1010,1029,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 928, 939, {29781, 29799, 29814, 29836, 29849, 29863, 29880}, {29904, 29912, 29917, 29836, 29849, 29929, 29936}, {0, 0, 0, 0, 0, 0, 0}, {29950, 29972, 29988, 30008, 30022, 30039, 30054, 30071, 30085, 30098, 30117, 30131, 0}, {29950, 29972, 29988, 30008, 30022, 30039, 30054, 30071, 30085, 30098, 30117, 30131, 0}, {30150, 30165, 30174, 30187, 30194, 30204, 30212, 30222, 30229, 30235, 30247, 30254, 0}, {30150, 30165, 30174, 30187, 30194, 30204, 30212, 30222, 30229, 30235, 30247, 30254, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 0, 0, {30266, 30274, 12472, 12968, 12490, 30285, 30295}, {12516, 12998, 12524, 12528, 12532, 12535, 30304}, {0, 0, 0, 0, 0, 0, 0}, {30308, 30317, 30327, 30335, 7756, 2764, 30343, 30349, 30358, 30367, 30376, 30385, 0}, {30308, 30317, 30327, 30335, 7756, 2764, 30343, 30349, 30358, 30367, 30376, 30385, 0}, {1914, 1918, 13006, 30394, 7756, 1931, 1935, 16871, 15223, 1947, 30398, 13346, 0}, {1914, 1918, 13006, 30394, 7756, 1931, 1935, 16871, 15223, 1947, 30398, 13346, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {3797, 949, 955, {30402, 30410, 30419, 30430, 30440, 30452, 30460}, {12516, 30470, 30475, 30480, 30485, 30489, 30493}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 30497, 30504, 30512, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1830, 1837, 30497, 30504, 30512, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1914, 1918, 30516, 29379, 30512, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 30516, 29379, 30512, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {775,9,755,0,0,0,0,0,0,0,0,0,0,0},{721,3806,798,2541,3819,3844,0,0,0,0},{71,266,1146,3870,0,0,0,0,0,0,0,0},{89,3882,3897,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3913, 965, 970, {30521, 30528, 30543, 30557, 30573, 30588, 30604}, {4528, 30619, 4512, 30623, 30627, 30631, 30635}, {1285, 9428, 1608, 1280, 1285, 1610, 9428}, {5011, 5019, 30639, 30646, 30653, 1649, 1654, 30658, 30668, 30679, 30688, 30698, 0}, {5011, 5019, 30639, 30646, 30653, 1649, 1654, 30658, 30668, 30679, 30688, 30698, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 5101, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 5101, 5105, 5109, 4642, 6911, 0}, 0, 0, 55, 3, {744,755,417,764,0,0,0,0,0,0,0,0,0,0},{3926,721,2561,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 975, 980, {30708, 30724, 30732, 30740, 30749, 30761, 30771}, {30781, 30787, 30793, 30797, 30801, 30809, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {30816, 30829, 30843, 30852, 30512, 30858, 30863, 30871, 13301, 30884, 13318, 13326, 0}, {30816, 30829, 30843, 30852, 30512, 30858, 30863, 30871, 13301, 30884, 13318, 13326, 0}, {30893, 1918, 30897, 13334, 30512, 30901, 1935, 30905, 1943, 30913, 1951, 13346, 0}, {30893, 1918, 30897, 13334, 30512, 30901, 1935, 30905, 1943, 30913, 1951, 13346, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 985, 988, {30919, 30927, 30935, 30943, 30950, 30958, 30966}, {30974, 30978, 30982, 30986, 7719, 30990, 30994}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {30998, 31006, 31018, 31030, 31035, 31042, 31053, 31064, 31072, 31081, 31094, 31102, 0}, {30998, 31006, 31018, 31030, 31035, 31042, 31053, 31064, 31072, 31081, 31094, 31102, 0}, {31109, 31113, 31117, 31121, 31125, 31129, 31133, 31137, 31141, 31145, 25077, 12918, 0}, {31109, 31113, 31117, 31121, 31125, 31129, 31133, 31137, 31141, 31145, 25077, 12918, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{978,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 991, 1011, {31149, 31162, 31172, 28077, 31182, 31192, 31202}, {31212, 31219, 31226, 31233, 31240, 31247, 31254}, {28131, 28131, 31261, 28139, 31265, 28147, 31269}, {31273, 31280, 31293, 31306, 31319, 31332, 31339, 31349, 31359, 31375, 31388, 31398, 0}, {31273, 31280, 31293, 31306, 31319, 31332, 31339, 31349, 31359, 31375, 31388, 31398, 0}, {31273, 31411, 31418, 31425, 31432, 31332, 31439, 31446, 31453, 31460, 31467, 31474, 0}, {31273, 31411, 31418, 31425, 31432, 31332, 31439, 31446, 31453, 31460, 31467, 31474, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{3945,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {31481, 31489, 31499, 31508, 31518, 31527, 31537}, {31546, 31549, 31552, 31555, 31558, 31561, 31564}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {31567, 31575, 31585, 31592, 7756, 31602, 31607, 31613, 31622, 31633, 31643, 31652, 0}, {31567, 31575, 31585, 31592, 7756, 31602, 31607, 31613, 31622, 31633, 31643, 31652, 0}, {31661, 31666, 31671, 31676, 7756, 31682, 31687, 31692, 31698, 31703, 31709, 31714, 0}, {31661, 31666, 31671, 31676, 7756, 31682, 31687, 31692, 31698, 31703, 31709, 31714, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 1031, 1035, {31719, 31724, 31731, 31739, 31746, 31754, 31760}, {31766, 15901, 29675, 31770, 15905, 30990, 7727}, {9428, 11804, 1610, 9428, 31774, 2892, 1285}, {31777, 31791, 31804, 31820, 31833, 31847, 31860, 31875, 31891, 31907, 31921, 31943, 0}, {31777, 31791, 31804, 31820, 31833, 31847, 31860, 31875, 31891, 31907, 31921, 31943, 0}, {31966, 31970, 25077, 31974, 31978, 31982, 31986, 31990, 31994, 31998, 32002, 32006, 0}, {31966, 31970, 25077, 31974, 31978, 31982, 31986, 31990, 31994, 31998, 32002, 32006, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{3763,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3982, 1039, 1046, {32010, 32020, 32030, 32040, 32050, 32060, 32070}, {32080, 32087, 32094, 32101, 32108, 32115, 32122}, {32129, 32133, 32137, 32141, 32145, 32149, 32153}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, 0, 0, 1, 3, {379,388,397,428,417,406,0,0,0,0,0,0,0,0},{4005,4029,4059,4089,4106,0,0,0,0,0},{583,266,71,0,0,0,0,0,0,0,0,0},{600,271,89,0,0,0,0,0,0},{4129,666,0,0,0,0,0,0}}, + {109, 975, 1053, {25056, 29280, 32247, 32254, 32264, 32269, 32276}, {25056, 29280, 32283, 32288, 32264, 32293, 32298}, {32303, 1616, 32306, 32309, 17126, 4532, 1825}, {32312, 32319, 32247, 32330, 32336, 32340, 32349, 32356, 32361, 32370, 32375, 32378, 0}, {32312, 32319, 32247, 32330, 32336, 32340, 32349, 32356, 32361, 32370, 32375, 32378, 0}, {32384, 32389, 32397, 32403, 32336, 32408, 32414, 32356, 32420, 32370, 32375, 32426, 0}, {32384, 32389, 32397, 32403, 32336, 32408, 32414, 32356, 32420, 32370, 32375, 32426, 0}, 2, 1, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3125, 1058, 1064, {32431, 32448, 32463, 32480, 32497, 32514, 32523}, {32534, 32539, 32544, 32549, 32554, 32559, 32564}, {32569, 10152, 10155, 10158, 10161, 10164, 10167}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, 0, 0, 55, 3, {388,397,417,428,0,0,0,0,0,0,0,0,0,0},{4146,4167,4193,4234,4280,0,0,0,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{4294,2717,666,0,0,0,0,0}}, + {673, 1070, 1075, {32728, 32736, 32746, 32756, 32765, 32775, 32783}, {32793, 32797, 32802, 32806, 32810, 32814, 13568}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 32818, 32827, 32838, 32847, 32857, 0}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 32818, 32827, 32838, 32847, 32857, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 1, 3, {18,9,775,755,417,0,0,0,0,0,0,0,0,0},{1217,1234,894,0,0,0,0,0,0,0},{71,266,1151,1243,1253,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {4315, 1080, 1085, {32867, 32892, 32917, 32942, 32955, 32970, 32987}, {33002, 33007, 33012, 33017, 33022, 33027, 310}, {16083, 16083, 33032, 6081, 6084, 16083, 6081}, {33035, 33054, 33069, 33091, 33111, 33125, 33139, 33151, 33175, 33197, 33214, 33231, 0}, {33248, 33267, 33282, 33304, 33324, 33340, 33356, 33370, 33396, 33420, 33437, 33231, 0}, {33454, 33463, 33472, 33479, 33486, 33493, 33500, 33507, 33514, 33521, 33528, 33535, 0}, {33454, 33463, 33472, 33479, 33486, 33493, 33500, 33507, 33514, 33521, 33528, 33535, 0}, 0, 1, 11, 3, {681,1208,417,4331,4341,0,0,0,0,0,0,0,0,0},{4354,4389,4418,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{4453,0,0,0,0,0,0,0}}, + {925, 49, 52, {33542, 33554, 33565, 33577, 33589, 33599, 33611}, {33626, 33631, 33636, 33641, 33646, 33651, 33656}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {33661, 33670, 33682, 33690, 33695, 33705, 33712, 33721, 33728, 33734, 33743, 33754, 0}, {33661, 33670, 33682, 33690, 33695, 33705, 33712, 33721, 33728, 33734, 33743, 33754, 0}, {33762, 33767, 33772, 33777, 33782, 33787, 33792, 33646, 33797, 33802, 33807, 33812, 0}, {33762, 33767, 33772, 33777, 33782, 33787, 33792, 33646, 33797, 33802, 33807, 33812, 0}, 0, 0, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3239,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {4469, 1090, 1092, {33817, 33830, 33838, 33847, 33857, 33867, 33876}, {33888, 33892, 33896, 33900, 33904, 33908, 33912}, {1828, 1616, 1608, 5210, 9428, 4089, 1285}, {33916, 33930, 33941, 33950, 33961, 33973, 33987, 33999, 34012, 34025, 34037, 34050, 0}, {34064, 34081, 34095, 34107, 34121, 34136, 34150, 34162, 34177, 34192, 34206, 34221, 0}, {34237, 34242, 34248, 34254, 34259, 34265, 34271, 34276, 34282, 34287, 15862, 34293, 0}, {34237, 34242, 34248, 34254, 34259, 34265, 34271, 34276, 34282, 34287, 15862, 34293, 0}, 2, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{4480,4502,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 0, 0, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, {1, 10, 17, 37, 57, 81, 105, 112, 123, 134, 143, 161, 0}, 0, 0, 1, 3, {9,18,0,0,0,0,0,0,0,0,0,0,0,0},{29,42,0,0,0,0,0,0,0,0},{62,71,0,0,0,0,0,0,0,0,0,0},{77,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 5, 8, {177, 190, 211, 226, 237, 256, 267}, {280, 285, 290, 295, 300, 305, 310}, {315, 318, 321, 324, 327, 318, 324}, {330, 343, 360, 369, 380, 387, 394, 401, 414, 433, 450, 465, 0}, {330, 343, 360, 369, 380, 387, 394, 401, 414, 433, 450, 465, 0}, {482, 489, 360, 496, 380, 387, 394, 503, 510, 517, 524, 531, 0}, {482, 489, 360, 496, 380, 387, 394, 503, 510, 517, 524, 531, 0}, 2, 1, 11, 3, {116,131,147,163,0,0,0,0,0,0,0,0,0,0},{180,199,217,242,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{279,0,0,0,0,0,0,0}}, + {109, 13, 19, {538, 547, 555, 563, 572, 579, 589}, {598, 602, 606, 610, 614, 618, 622}, {626, 629, 632, 635, 638, 641, 644}, {647, 653, 660, 666, 672, 677, 682, 689, 695, 704, 712, 721, 0}, {730, 739, 749, 758, 768, 776, 784, 794, 804, 816, 828, 840, 0}, {852, 857, 660, 863, 672, 677, 868, 873, 877, 882, 887, 892, 0}, {852, 857, 660, 863, 672, 677, 868, 873, 877, 882, 887, 892, 0}, 2, 1, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{315,338,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {34299, 34306, 34313, 34320, 34327, 34334, 34341}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {379,406,417,0,0,0,0,0,0,0,0,0,0,0},{469,1484,547,4518,0,0,0,0,0,0},{591,583,71,266,0,0,0,0,0,0,0,0},{611,600,89,271,0,0,0,0,0},{623,639,652,0,0,0,0,0}}, + {673, 39, 44, {1197, 1205, 1215, 1223, 1231, 1240, 1247}, {1254, 1257, 1260, 1264, 1267, 1271, 1275}, {1278, 1280, 1282, 1285, 1287, 1280, 1285}, {1290, 1296, 1302, 1310, 1316, 1324, 1332, 1342, 1348, 1356, 1364, 1373, 0}, {1382, 1388, 1395, 1403, 1409, 1417, 1425, 1435, 1348, 1441, 1449, 1459, 0}, {1468, 1472, 1477, 1482, 1486, 1491, 1496, 1501, 1505, 1511, 1517, 1521, 0}, {1468, 1472, 1477, 1482, 1486, 1491, 1496, 1501, 1505, 1511, 1517, 1521, 0}, 2, 1, 11, 3, {681,692,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 49, 52, {1525, 1533, 1540, 1548, 1555, 1563, 1570}, {1578, 1583, 1587, 1591, 1595, 1599, 1603}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {1618, 1625, 1633, 1639, 1645, 1649, 1654, 1659, 1666, 1676, 1684, 1693, 0}, {1618, 1625, 1633, 1639, 1645, 1649, 1654, 1659, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 55, 3, {744,755,417,764,0,0,0,0,0,0,0,0,0,0},{721,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 57, 63, {1747, 1755, 1762, 1771, 1780, 1791, 1799}, {1807, 1810, 1813, 1816, 1819, 1822, 1825}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {681,775,417,784,0,0,0,0,0,0,0,0,0,0},{798,721,817,0,0,0,0,0,0,0},{71,830,0,0,0,0,0,0,0,0,0,0},{89,842,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 70, 77, {1959, 1974, 1989, 2000, 2015, 2028, 2047}, {2062, 2069, 2076, 2083, 2090, 2097, 2104}, {2111, 2114, 2117, 2117, 2120, 2120, 2123}, {2126, 2147, 2170, 2185, 2202, 2213, 2228, 2243, 2262, 2285, 2304, 2323, 0}, {2344, 2365, 2388, 2403, 2420, 2431, 2446, 2461, 2480, 2503, 2522, 2541, 0}, {2562, 2569, 2576, 2583, 2590, 2597, 2606, 2615, 2622, 2629, 2636, 2643, 0}, {2562, 2569, 2576, 2583, 2590, 2597, 2606, 2615, 2622, 2629, 2636, 2643, 0}, 2, 1, 1, 3, {295,18,857,9,864,417,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {932,941,948,957,460,417,968,0,0,0,0,0,0,0},{978,997,1010,1029,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 84, 88, {2997, 3009, 3021, 3031, 3045, 3055, 3067}, {3078, 3081, 3084, 3087, 3090, 3093, 3096}, {1285, 1608, 1610, 3099, 1610, 1280, 1616}, {3101, 3110, 3119, 3129, 3138, 3147, 3156, 3166, 3173, 3181, 3189, 3199, 0}, {3208, 3219, 3230, 3242, 3253, 3264, 3275, 3287, 3296, 3306, 3316, 3328, 0}, {3339, 3345, 3351, 3358, 3364, 3370, 3376, 3383, 3387, 3392, 3397, 3404, 0}, {3339, 3345, 3351, 3358, 3364, 3370, 3376, 3383, 3387, 3392, 3397, 3404, 0}, 2, 1, 11, 11, {1208,0,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{1146,0,0,0,0,0,0,0,0,0,0,0},{1165,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 2, 1, 1, 3, {18,9,775,755,417,0,0,0,0,0,0,0,0,0},{1217,894,1234,0,0,0,0,0,0,0},{71,266,1151,1243,1253,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 92, 105, {3596, 3614, 3628, 3646, 3664, 3682, 3698}, {3712, 3724, 3736, 3748, 3760, 3772, 3784}, {3791, 3796, 3801, 3806, 3811, 3816, 3821}, {3826, 3837, 3850, 3857, 3868, 3875, 3884, 3893, 3906, 3919, 3934, 3947, 0}, {3826, 3837, 3850, 3857, 3868, 3875, 3884, 3893, 3906, 3919, 3934, 3947, 0}, {3958, 3967, 3850, 3976, 3868, 3875, 3884, 3985, 3994, 4003, 4012, 4021, 0}, {3958, 3967, 3850, 3976, 3868, 3875, 3884, 3985, 3994, 4003, 4012, 4021, 0}, 0, 0, 1, 3, {18,1261,9,29,755,744,1274,417,1287,1304,0,0,0,0},{1314,1261,1332,1354,1287,0,0,0,0,0},{71,62,0,0,0,0,0,0,0,0,0,0},{89,77,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1375, 116, 120, {4030, 4040, 4048, 4053, 4060, 4073, 4081}, {2894, 4089, 3099, 4091, 4095, 1280, 4098}, {2894, 4089, 3099, 4102, 4095, 1280, 4102}, {4105, 4113, 4122, 4131, 4140, 4147, 4155, 4163, 4173, 4184, 1684, 1693, 0}, {4105, 4113, 4122, 4131, 4140, 4147, 4155, 4163, 4173, 4184, 1684, 1693, 0}, {1702, 857, 4193, 4200, 4206, 4212, 4218, 1727, 4224, 1737, 887, 1742, 0}, {1702, 857, 4193, 4200, 4206, 4212, 4218, 1727, 4224, 1737, 887, 1742, 0}, 2, 1, 124, 3, {1383,1397,0,0,0,0,0,0,0,0,0,0,0,0},{1410,1430,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{1444,0,0,0,0,0,0,0}}, + {673, 127, 132, {4231, 4242, 4253, 4267, 4281, 4293, 4305}, {4317, 4322, 4328, 4334, 4340, 4345, 4351}, {1285, 1608, 4356, 1608, 1614, 1614, 1616}, {4359, 4367, 3504, 4376, 4383, 4388, 4395, 4402, 1666, 4184, 4410, 4420, 0}, {4359, 4367, 3504, 4376, 4383, 4388, 4395, 4402, 1666, 4184, 4410, 4420, 0}, {1702, 1707, 1712, 1717, 4383, 4212, 4218, 4429, 1732, 1737, 4436, 892, 0}, {1702, 1707, 1712, 1717, 4383, 4212, 4218, 4429, 1732, 1737, 4436, 892, 0}, 2, 1, 11, 3, {1208,1455,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {4442, 4451, 4459, 4468, 4479, 4488, 4497}, {4504, 4508, 4512, 4516, 4520, 4524, 4528}, {1828, 1616, 1608, 1608, 4532, 2894, 1285}, {4534, 4542, 2910, 4551, 4558, 4565, 4572, 2933, 4579, 4589, 712, 4597, 0}, {4534, 4542, 2910, 4551, 4558, 4565, 4572, 2933, 4579, 4589, 712, 4597, 0}, {4606, 4610, 4512, 4614, 4618, 4622, 4626, 4630, 4634, 4638, 4642, 4646, 0}, {4606, 4610, 4512, 4614, 4618, 4622, 4626, 4630, 4634, 4638, 4642, 4646, 0}, 2, 1, 1, 3, {18,864,9,1467,857,0,0,0,0,0,0,0,0,0},{1217,1475,894,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {370, 137, 144, {4650, 4660, 4670, 4680, 4690, 4700, 4710}, {1016, 4720, 4724, 4728, 4732, 4736, 4740}, {1016, 4720, 4724, 4728, 4732, 4736, 4740}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, 0, 0, 1, 3, {406,460,439,379,417,0,0,0,0,0,0,0,0,0},{469,1484,1508,1535,1564,1588,1617,1637,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{623,1662,652,0,0,0,0,0}}, + {1680, 151, 158, {4771, 4781, 4791, 4801, 4811, 4821, 4831}, {4841, 4845, 4849, 4853, 4857, 4861, 4865}, {4841, 4845, 4849, 4853, 4857, 4861, 4865}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, {4869, 4874, 4879, 4884, 4889, 4894, 4899, 4904, 4909, 4914, 4920, 4926, 0}, 0, 0, 55, 3, {417,1690,446,388,0,0,0,0,0,0,0,0,0,0},{1699,1728,1752,1779,1801,1832,1858,1889,1915,1942},{583,591,266,71,0,0,0,0,0,0,0,0},{600,611,271,89,0,0,0,0,0},{1964,1981,2000,0,0,0,0,0}}, + {109, 165, 170, {4932, 4939, 4947, 4955, 4964, 4974, 4982}, {4991, 3081, 4994, 4997, 5000, 5003, 5006}, {5009, 1608, 1828, 2735, 1828, 2894, 5009}, {5011, 5019, 5028, 1639, 5034, 1649, 1654, 5038, 1666, 1676, 1684, 1693, 0}, {5011, 5019, 5028, 1639, 5034, 1649, 1654, 5038, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 5047, 1717, 5034, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 5047, 1717, 5034, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 55, 3, {2015,1062,755,9,775,2024,417,0,0,0,0,0,0,0},{1217,1475,894,1234,0,0,0,0,0,0},{71,266,1146,2036,2048,0,0,0,0,0,0,0},{89,271,2060,2075,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {2090, 165, 170, {1525, 1533, 1540, 1548, 1555, 1563, 1570}, {5052, 5058, 5063, 5068, 5073, 5078, 5083}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, 2, 1, 11, 11, {681,1455,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {5117, 5127, 5141, 5148, 5155, 5164, 1247}, {5172, 5179, 5184, 5188, 5193, 5198, 5202}, {1278, 1280, 2735, 5207, 5210, 1280, 1285}, {5212, 5221, 5226, 5233, 1645, 5243, 5252, 5259, 5269, 5279, 1364, 5292, 0}, {5302, 5311, 5318, 5324, 5333, 5338, 5346, 5352, 5361, 5371, 5385, 5395, 0}, {5403, 5407, 4512, 5411, 1645, 5415, 5419, 5423, 5427, 5431, 1517, 5436, 0}, {5403, 5407, 4512, 5411, 1645, 5415, 5419, 5423, 5427, 5431, 1517, 5436, 0}, 2, 1, 11, 3, {681,0,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1042, 49, 52, {2803, 5440, 5454, 5467, 5480, 5493, 2850}, {4504, 5505, 5509, 5513, 5517, 5521, 5525}, {1828, 1285, 1610, 5530, 5530, 1285, 1285}, {5532, 5540, 5550, 666, 5557, 5562, 5568, 2933, 5574, 5583, 5591, 5600, 0}, {5532, 5540, 5550, 666, 5557, 5562, 5568, 2933, 5574, 5583, 5591, 5600, 0}, {5089, 5609, 4512, 5613, 3515, 5093, 5097, 4630, 4634, 5617, 4642, 5621, 0}, {5089, 5609, 4512, 5613, 3515, 5093, 5097, 4630, 4634, 5617, 4642, 5621, 0}, 0, 0, 1, 3, {18,9,295,857,755,744,1062,2015,775,681,2024,2098,1208,417},{1069,1124,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{1193,0,0,0,0,0,0,0}}, + {673, 49, 52, {5625, 5634, 3425, 5644, 5652, 5660, 5669}, {5675, 5678, 3081, 5682, 5685, 5689, 1275}, {1828, 4532, 1608, 1608, 4532, 2894, 1285}, {5692, 5700, 3504, 5707, 5714, 5719, 5729, 5737, 5743, 5753, 1684, 1693, 0}, {5692, 5700, 3504, 5707, 5714, 5719, 5729, 5737, 5743, 5753, 1684, 1693, 0}, {5761, 5768, 3504, 3579, 5714, 5774, 5781, 5737, 5786, 882, 887, 1742, 0}, {5761, 5768, 3504, 3579, 5714, 5774, 5781, 5737, 5786, 882, 887, 1742, 0}, 2, 1, 55, 3, {744,0,0,0,0,0,0,0,0,0,0,0,0,0},{2105,2134,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 165, 170, {5792, 5802, 5807, 5814, 5823, 5827, 5834}, {5845, 2863, 1712, 5850, 5823, 5855, 5860}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {5866, 5875, 5885, 5892, 3515, 5900, 5906, 1659, 5912, 5923, 5933, 5943, 0}, {5866, 5875, 5885, 5892, 3515, 5900, 5906, 1659, 5912, 5923, 5933, 5943, 0}, {5953, 1707, 1712, 1717, 3515, 5958, 5963, 1727, 2986, 882, 887, 1742, 0}, {5953, 1707, 1712, 1717, 3515, 5958, 5963, 1727, 2986, 882, 887, 1742, 0}, 0, 1, 11, 3, {681,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 175, 180, {5968, 5991, 211, 6014, 6025, 6040, 6055}, {6070, 285, 290, 295, 300, 305, 310}, {6075, 6078, 6075, 6081, 6084, 6078, 6081}, {6087, 6100, 360, 6115, 380, 6128, 6137, 401, 6146, 6163, 6178, 6191, 0}, {6206, 6219, 6234, 6245, 6258, 6265, 6274, 6283, 6298, 6315, 6330, 6343, 0}, {6358, 6366, 360, 6376, 380, 6128, 6137, 6384, 6392, 6402, 6410, 6420, 0}, {6358, 6366, 360, 6376, 380, 6128, 6137, 6384, 6392, 6402, 6410, 6420, 0}, 0, 1, 11, 3, {681,775,2098,744,9,0,0,0,0,0,0,0,0,0},{199,180,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 49, 52, {6428, 6437, 6449, 6456, 6464, 6474, 6480}, {6487, 6491, 6495, 6499, 6503, 6508, 6512}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {6527, 6537, 6546, 6554, 6562, 6570, 6577, 6584, 6592, 1364, 6598, 6606, 0}, {6615, 6625, 6634, 6642, 6650, 6658, 6665, 6672, 6681, 5385, 6687, 6697, 0}, {6706, 6710, 6715, 6720, 6724, 5419, 1501, 6728, 6732, 1517, 6736, 1521, 0}, {6706, 6710, 6715, 6720, 6724, 5419, 1501, 6728, 6732, 1517, 6736, 1521, 0}, 0, 1, 11, 3, {2151,2161,2169,2181,2193,2203,2213,417,0,0,0,0,0,0},{2225,2239,2254,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {673, 49, 52, {6740, 6748, 6757, 6764, 6771, 6780, 1247}, {1254, 1257, 6787, 1264, 6790, 6794, 1275}, {6516, 6518, 6520, 6522, 6797, 6518, 6522}, {4105, 4113, 6800, 4376, 6806, 6811, 6816, 1659, 1666, 4184, 1684, 1693, 0}, {6821, 6830, 5318, 6840, 6848, 6854, 6860, 6866, 6874, 6884, 6893, 6902, 0}, {5089, 4610, 4512, 4614, 6806, 6811, 6816, 5101, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 6806, 6811, 6816, 5101, 5105, 5109, 4642, 6911, 0}, 2, 1, 11, 3, {681,692,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 185, 197, {6915, 6922, 6931, 6940, 6952, 6960, 6969}, {6979, 6983, 2791, 6988, 6993, 6997, 7001}, {1828, 4089, 1608, 1608, 7005, 1280, 1285}, {7007, 7013, 7020, 7025, 7031, 7035, 7043, 7050, 7056, 7064, 7070, 7078, 0}, {7086, 7092, 3504, 7099, 1645, 7105, 7113, 7120, 7126, 7134, 7140, 7148, 0}, {1914, 7156, 2791, 7160, 7031, 7164, 7168, 7172, 7001, 7176, 7180, 7185, 0}, {1914, 7156, 2791, 7160, 7031, 7164, 7168, 7172, 7001, 7176, 7180, 7185, 0}, 0, 1, 11, 3, {1208,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {2274, 208, 211, {7189, 7197, 7205, 1548, 1555, 1563, 7212}, {7220, 7225, 7230, 1591, 7234, 1599, 7239}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {5011, 5019, 3504, 1639, 1645, 1649, 1654, 7244, 1666, 1676, 1684, 1693, 0}, {5011, 5019, 3504, 1639, 1645, 1649, 1654, 7244, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 3504, 1717, 1645, 1649, 1654, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 3504, 1717, 1645, 1649, 1654, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 55, 3, {417,1690,0,0,0,0,0,0,0,0,0,0,0,0},{2287,2305,0,0,0,0,0,0,0,0},{71,266,2328,0,0,0,0,0,0,0,0,0},{89,271,2338,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 0, 0, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, 0, 0, 1, 3, {295,857,9,18,304,2351,417,0,0,0,0,0,0,0},{894,2363,2379,0,0,0,0,0,0,0},{266,71,906,62,0,0,0,0,0,0,0,0},{271,89,914,77,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 214, 219, {7252, 7258, 7268, 7274, 7285, 7295, 7300}, {7310, 7314, 7318, 7322, 7327, 7331, 7335}, {1280, 1280, 1285, 7339, 1280, 5210, 5210}, {7342, 7347, 7354, 7359, 7365, 7372, 7380, 7387, 7396, 7403, 7408, 7415, 0}, {7342, 7347, 7354, 7359, 7365, 7372, 7380, 7387, 7396, 7403, 7408, 7415, 0}, {7423, 7427, 2791, 7432, 2760, 7436, 7440, 7444, 7449, 7453, 7457, 7461, 0}, {7423, 7427, 2791, 7432, 2760, 7436, 7440, 7444, 7449, 7453, 7457, 7461, 0}, 0, 1, 11, 3, {2421,304,0,0,0,0,0,0,0,0,0,0,0,0},{2431,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 49, 52, {7465, 7476, 7489, 7498, 7505, 7518, 7527}, {7465, 7476, 7489, 7498, 7505, 7518, 7527}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, 0, 0, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 49, 52, {7660, 7667, 7673, 7680, 7685, 7691, 7697}, {7703, 7707, 7711, 7715, 7719, 7723, 7727}, {1608, 1285, 1285, 7731, 3099, 2892, 1285}, {7733, 7741, 7750, 1851, 7756, 1861, 1866, 7760, 1878, 1888, 1896, 7768, 0}, {7733, 7741, 7750, 1851, 7756, 1861, 1866, 7760, 1878, 1888, 1896, 7768, 0}, {1914, 1918, 2791, 1927, 7756, 1931, 1935, 7777, 1943, 1947, 1951, 7781, 0}, {1914, 1918, 2791, 1927, 7756, 1931, 1935, 7777, 1943, 1947, 1951, 7781, 0}, 0, 0, 1, 11, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{2462,894,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 223, 228, {7785, 7798, 7817, 7834, 7847, 7860, 7877}, {280, 285, 290, 295, 300, 305, 310}, {7890, 6078, 6075, 6081, 6084, 6078, 6081}, {7893, 7906, 7917, 7934, 7949, 7964, 7979, 7992, 8007, 8024, 8039, 8056, 0}, {8071, 8082, 8095, 8110, 8123, 8136, 8149, 8160, 8173, 8188, 8201, 8220, 0}, {8233, 8240, 8247, 8254, 8261, 8268, 8275, 8282, 8289, 8296, 8303, 8310, 0}, {8233, 8240, 8247, 8254, 8261, 8268, 8275, 8282, 8289, 8296, 8303, 8310, 0}, 0, 1, 11, 3, {681,775,417,0,0,0,0,0,0,0,0,0,0,0},{2481,0,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{2499,0,0,0,0,0,0,0}}, + {109, 49, 52, {8317, 8332, 8353, 8368, 8381, 8394, 7877}, {280, 285, 8409, 295, 8414, 305, 310}, {315, 318, 8419, 324, 327, 318, 324}, {8422, 8439, 8448, 8463, 380, 8480, 8495, 8508, 8523, 8540, 8561, 8578, 0}, {8593, 8610, 8623, 8640, 6258, 8659, 8674, 8687, 8700, 8715, 8738, 8757, 0}, {8770, 8240, 8777, 8784, 380, 8791, 8798, 8805, 8289, 8812, 8819, 8826, 0}, {8770, 8240, 8777, 8784, 380, 8791, 8798, 8805, 8289, 8812, 8819, 8826, 0}, 0, 1, 11, 3, {775,0,0,0,0,0,0,0,0,0,0,0,0,0},{894,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{2515,0,0,0,0,0,0,0}}, + {673, 39, 233, {8833, 8841, 8852, 8858, 8864, 8873, 1247}, {8879, 5179, 5073, 8884, 8889, 8895, 5202}, {6516, 6518, 8900, 6522, 6524, 6518, 6522}, {1618, 1625, 6800, 1639, 1645, 8902, 8908, 8914, 1666, 1676, 1684, 1693, 0}, {1618, 1625, 6800, 1639, 1645, 8902, 8908, 8914, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 8921, 1732, 1737, 887, 1742, 0}, {1702, 1707, 1712, 1717, 1645, 1722, 868, 8921, 1732, 1737, 887, 1742, 0}, 0, 1, 124, 3, {2529,1455,0,0,0,0,0,0,0,0,0,0,0,0},{2541,2561,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 49, 52, {8926, 8937, 8948, 8959, 8970, 8981, 8987}, {1280, 7005, 1610, 3099, 1278, 7731, 1616}, {1280, 7005, 1610, 3099, 1278, 7731, 1616}, {8996, 9004, 9013, 9020, 3515, 9027, 9033, 1659, 1666, 9039, 1684, 9048, 0}, {8996, 9004, 9013, 9020, 3515, 9027, 9033, 1659, 1666, 9039, 1684, 9048, 0}, {9058, 9063, 9013, 4614, 3515, 9027, 9033, 5101, 9069, 5109, 4642, 9074, 0}, {9058, 9063, 9013, 4614, 3515, 9027, 9033, 5101, 9069, 5109, 4642, 9074, 0}, 2, 1, 11, 3, {681,1455,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{2575,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 238, 248, {9079, 9090, 9100, 9109, 9120, 9132, 9143}, {9153, 9161, 9168, 9174, 9182, 9191, 9199}, {1285, 1280, 1612, 1610, 5210, 1280, 1285}, {9206, 9216, 1633, 9227, 9236, 9242, 9250, 9258, 9266, 9277, 9286, 9296, 0}, {9206, 9216, 1633, 9227, 9236, 9242, 9250, 9258, 9266, 9277, 9286, 9296, 0}, {3566, 857, 1633, 1717, 9236, 9306, 9312, 1727, 2986, 1737, 887, 1742, 0}, {3566, 857, 1633, 1717, 9236, 9306, 9312, 1727, 2986, 1737, 887, 1742, 0}, 0, 1, 11, 3, {681,2583,0,0,0,0,0,0,0,0,0,0,0,0},{2603,2630,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2651,0,0,0,0,0,0,0}}, + {925, 255, 266, {9318, 9330, 9342, 9354, 9368, 9383, 9396}, {9410, 9413, 9416, 9419, 9422, 9425, 6790}, {1285, 1280, 9428, 1610, 3099, 1280, 9430}, {9433, 9440, 9448, 9454, 9463, 9472, 9482, 9488, 9499, 9509, 9516, 9526, 0}, {9534, 9541, 9549, 9554, 9565, 9575, 9585, 9592, 9604, 9613, 9620, 9631, 0}, {9641, 9647, 9652, 9657, 9662, 9667, 9674, 9680, 9686, 9692, 9698, 9705, 0}, {9641, 9647, 9652, 9657, 9662, 9667, 9674, 9680, 9686, 9692, 9698, 9705, 0}, 2, 1, 55, 3, {417,0,0,0,0,0,0,0,0,0,0,0,0,0},{2667,2695,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {1, 273, 285, {9712, 9727, 9742, 9757, 9774, 9793, 9804}, {9815, 9822, 9829, 9836, 9843, 9850, 9857}, {0, 0, 0, 0, 0, 0, 0}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, 0, 1, 11, 3, {681,775,2098,744,9,0,0,0,0,0,0,0,0,0},{2727,2745,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 297, 304, {10057, 10070, 10083, 10099, 10116, 10131, 10140}, {10057, 10070, 10083, 10099, 10116, 10131, 10140}, {10149, 10152, 10155, 10158, 10161, 10164, 10167}, {10170, 10183, 10194, 10203, 10214, 10219, 10228, 10239, 10246, 10261, 10272, 10285, 0}, {10298, 10313, 10194, 10203, 10326, 10219, 10333, 10239, 10246, 10261, 10272, 10285, 0}, {10170, 10183, 10194, 10203, 10214, 10219, 10228, 10239, 10246, 10261, 10272, 10285, 0}, {10170, 10183, 10194, 10203, 10214, 10219, 10228, 10239, 10246, 10261, 10272, 10285, 0}, 0, 6, 1, 3, {18,9,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{62,71,0,0,0,0,0,0,0,0,0,0},{77,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 311, 314, {10346, 10359, 10369, 10378, 10388, 10399, 10410}, {10422, 10425, 10430, 10435, 10440, 10445, 10450}, {10422, 10455, 10458, 10461, 10464, 10467, 10470}, {10473, 10482, 10491, 10500, 10509, 10518, 10527, 10536, 10545, 10554, 10564, 10574, 0}, {10584, 10593, 10602, 10611, 10620, 10629, 10638, 10647, 10656, 10665, 10675, 10685, 0}, {10695, 10701, 10707, 10713, 10719, 10725, 10731, 10737, 10743, 10749, 10756, 10763, 0}, {10695, 10701, 10707, 10713, 10719, 10725, 10731, 10737, 10743, 10749, 10756, 10763, 0}, 0, 1, 1, 3, {18,9,755,744,417,0,0,0,0,0,0,0,0,0},{1261,0,0,0,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 317, 322, {10770, 10783, 10804, 10823, 10844, 10863, 10876}, {10887, 10894, 10901, 10908, 10915, 10922, 10929}, {10936, 10939, 10939, 10942, 10945, 10948, 10951}, {10954, 10969, 10984, 10993, 11004, 11015, 11028, 11041, 11056, 11075, 11094, 11111, 0}, {11130, 11147, 11164, 11175, 11188, 11201, 11216, 11231, 11248, 11269, 11290, 11309, 0}, {11330, 11337, 11344, 11351, 11358, 11365, 11372, 11379, 11386, 11393, 11400, 11407, 0}, {11330, 11337, 11344, 11351, 11358, 11365, 11372, 11379, 11386, 11393, 11400, 11407, 0}, 0, 1, 11, 3, {681,775,2764,18,2774,864,417,0,0,0,0,0,0,0},{1029,876,2462,1261,2785,2796,2808,2825,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 49, 52, {11414, 11420, 11434, 11457, 11471, 11487, 11494}, {11503, 11506, 11511, 11517, 11521, 11526, 11529}, {4756, 4744, 4746, 4748, 4750, 4752, 4754}, {11533, 11540, 7354, 11547, 2760, 11553, 11559, 11565, 11572, 11581, 11589, 11596, 0}, {11603, 11610, 11617, 11622, 11628, 11632, 11637, 11642, 11649, 11658, 11666, 11673, 0}, {11680, 5609, 4512, 4614, 11628, 11684, 11688, 11692, 11696, 5109, 11700, 11704, 0}, {11680, 5609, 4512, 4614, 11628, 11684, 11688, 11692, 11696, 5109, 11700, 11704, 0}, 0, 1, 11, 3, {681,304,0,0,0,0,0,0,0,0,0,0,0,0},{2843,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {11708, 11716, 11727, 11737, 11748, 11757, 11766}, {11776, 11780, 11784, 11788, 11792, 11796, 11800}, {11804, 9428, 9428, 9428, 1612, 1612, 1616}, {11806, 11816, 11824, 11832, 11840, 11848, 11855, 11863, 11871, 11878, 11884, 11891, 0}, {11806, 11899, 11907, 11915, 11923, 11931, 11938, 11946, 11954, 11961, 11967, 11974, 0}, {11982, 11987, 1712, 11992, 11997, 12002, 12007, 12012, 12017, 12022, 12027, 12032, 0}, {11982, 11987, 1712, 11992, 11997, 12002, 12007, 12012, 12017, 12022, 12027, 12032, 0}, 2, 1, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2872,2899,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2920,0,0,0,0,0,0,0}}, + {673, 327, 338, {12037, 12047, 12058, 12065, 12072, 12082, 1247}, {12088, 12092, 12097, 12101, 12105, 12110, 12114}, {6516, 6518, 12118, 6522, 6797, 6518, 6522}, {1618, 1625, 12120, 12126, 12132, 8902, 8908, 12137, 1666, 1676, 12144, 1693, 0}, {12153, 12161, 12170, 12177, 12184, 12189, 12196, 12203, 6874, 12211, 12219, 6902, 0}, {5089, 4610, 12228, 4614, 12233, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, {5089, 4610, 12228, 4614, 12233, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, 2, 1, 11, 3, {1208,0,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{2939,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 349, 363, {12245, 190, 211, 6014, 12258, 12275, 12286}, {12299, 12307, 12315, 12323, 12331, 12339, 12347}, {315, 318, 321, 324, 327, 318, 324}, {12355, 343, 360, 369, 12370, 12377, 12386, 401, 414, 433, 450, 465, 0}, {12355, 343, 360, 369, 12370, 12377, 12386, 401, 414, 433, 450, 465, 0}, {12395, 12403, 12411, 6376, 12370, 12419, 12427, 6384, 12435, 6402, 12445, 6420, 0}, {12395, 12403, 12411, 6376, 12370, 12419, 12427, 6384, 12435, 6402, 12445, 6420, 0}, 0, 1, 11, 3, {2953,0,0,0,0,0,0,0,0,0,0,0,0,0},{2462,1261,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2963,0,0,0,0,0,0,0}}, + {925, 0, 0, {12455, 12463, 12472, 12481, 12490, 12497, 12507}, {12516, 12520, 12524, 12528, 12532, 12535, 12539}, {0, 0, 0, 0, 0, 0, 0}, {12543, 12554, 12562, 12572, 12578, 12590, 12599, 12605, 12611, 12619, 12628, 12640, 0}, {12543, 12554, 12562, 12572, 12578, 12590, 12599, 12605, 12611, 12619, 12628, 12640, 0}, {12648, 12652, 12656, 12660, 12664, 1914, 12668, 12672, 12676, 12680, 12684, 12688, 0}, {12648, 12652, 12656, 12660, 12664, 1914, 12668, 12672, 12676, 12680, 12684, 12688, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 0, 0, {12692, 12698, 12711, 12722, 12733, 12742, 12754}, {12516, 12764, 12768, 12772, 12532, 12776, 12780}, {0, 0, 0, 0, 0, 0, 0}, {12784, 12792, 12804, 12816, 12828, 12838, 12850, 12859, 12867, 12875, 12885, 12892, 0}, {12784, 12792, 12804, 12816, 12828, 12838, 12850, 12859, 12867, 12875, 12885, 12892, 0}, {2707, 12906, 12910, 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12942, 12946, 0}, {2707, 12906, 12910, 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12942, 12946, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 0, 0, {12950, 12957, 12472, 12968, 12490, 12977, 12988}, {12688, 12998, 12524, 12528, 12532, 13002, 13006}, {0, 0, 0, 0, 0, 0, 0}, {13010, 13020, 13029, 13037, 13046, 13059, 13071, 13078, 13085, 13092, 13102, 13114, 0}, {13010, 13020, 13029, 13037, 13046, 13059, 13071, 13078, 13085, 13092, 13102, 13114, 0}, {13127, 12776, 13131, 13135, 12664, 13139, 13143, 12672, 13147, 13151, 13155, 13159, 0}, {13127, 12776, 13131, 13135, 12664, 13139, 13143, 12672, 13147, 13151, 13155, 13159, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 0, 0, {13163, 13168, 13174, 13184, 13196, 13204, 13215}, {13224, 13228, 13232, 13236, 13240, 12535, 13244}, {0, 0, 0, 0, 0, 0, 0}, {13248, 13258, 13268, 13275, 13282, 1861, 13287, 13294, 13301, 13310, 13318, 13326, 0}, {13248, 13258, 13268, 13275, 13282, 1861, 13287, 13294, 13301, 13310, 13318, 13326, 0}, {1914, 1918, 13006, 13334, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, {1914, 1918, 13006, 13334, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 49, 52, {13350, 13357, 13369, 13380, 13393, 13402, 13414}, {12516, 13424, 13428, 13236, 13240, 12535, 13244}, {1285, 1608, 13432, 1610, 1285, 4089, 1608}, {13434, 13258, 13443, 13449, 13282, 1861, 13287, 13294, 13457, 13310, 13318, 13326, 0}, {13467, 13258, 13443, 13449, 13282, 1861, 13287, 13294, 13457, 13310, 13318, 13326, 0}, {1914, 1918, 13478, 13482, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, {1914, 1918, 13478, 13482, 13338, 1931, 1935, 13342, 1943, 1947, 1951, 13346, 0}, 0, 0, 1, 3, {932,3009,0,0,0,0,0,0,0,0,0,0,0,0},{978,997,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 373, 377, {13486, 13493, 13501, 13509, 13518, 13528, 13535}, {13544, 13548, 13552, 13556, 13560, 13564, 13568}, {1285, 1608, 1828, 2735, 1828, 2894, 1285}, {13572, 13581, 13591, 1851, 7756, 13597, 13603, 13609, 1878, 1888, 1896, 7768, 0}, {13572, 13581, 13591, 1851, 7756, 13597, 13603, 13609, 1878, 1888, 1896, 7768, 0}, {13618, 13623, 13628, 13633, 7756, 13638, 13643, 13648, 13653, 13658, 13663, 13668, 0}, {13618, 13623, 13628, 13633, 7756, 13638, 13643, 13648, 13653, 13658, 13663, 13668, 0}, 0, 0, 55, 3, {417,2351,0,0,0,0,0,0,0,0,0,0,0,0},{2462,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {13673, 13689, 13714, 13742, 13770, 13798, 13826}, {13845, 13855, 13865, 13875, 13885, 13895, 13905}, {13915, 13919, 13923, 13919, 13927, 13931, 13935}, {13939, 13961, 13989, 14005, 14024, 14040, 14059, 14078, 14100, 14131, 14159, 14184, 0}, {13939, 13961, 13989, 14005, 14024, 14040, 14059, 14078, 14100, 14131, 14159, 14184, 0}, {14212, 14222, 14232, 14242, 14252, 14262, 14272, 14282, 14292, 14302, 14312, 14322, 0}, {14212, 14222, 14232, 14242, 14252, 14262, 14272, 14282, 14292, 14302, 14312, 14322, 0}, 0, 1, 11, 3, {681,3021,0,0,0,0,0,0,0,0,0,0,0,0},{42,1029,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 49, 52, {4231, 14332, 14343, 14353, 14363, 14373, 14387}, {14399, 14403, 14408, 14413, 14417, 14422, 14427}, {1285, 1608, 1610, 1608, 4089, 1614, 1616}, {1618, 1625, 3504, 4376, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {1618, 1625, 3504, 4376, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, 2, 1, 55, 3, {744,0,0,0,0,0,0,0,0,0,0,0,0,0},{1314,1455,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {1, 381, 409, {14431, 14450, 14469, 14491, 14510, 14532, 14557}, {14576, 14586, 14596, 14609, 14619, 14632, 14648}, {14658, 14662, 14669, 14676, 14683, 14690, 14697}, {14701, 14717, 14736, 14752, 14771, 14778, 14788, 14804, 14820, 14839, 14861, 14877, 0}, {14701, 14717, 14736, 14752, 14771, 14778, 14788, 14804, 14820, 14839, 14861, 14877, 0}, {14896, 14906, 14736, 14752, 14771, 14778, 14919, 14932, 14942, 14955, 14974, 14984, 0}, {14896, 14906, 14736, 14752, 14771, 14778, 14919, 14932, 14942, 14955, 14974, 14984, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {3033, 49, 52, {14997, 15006, 15015, 15025, 15035, 15045, 15057}, {15065, 15070, 15074, 15078, 15082, 15087, 15092}, {15096, 15100, 15103, 15106, 15109, 15113, 15117}, {15120, 15127, 15132, 1851, 15138, 15144, 15151, 15157, 15165, 15175, 15183, 15192, 0}, {15120, 15127, 15132, 1851, 15138, 15144, 15151, 15157, 15165, 15175, 15183, 15192, 0}, {1914, 15202, 2791, 1927, 15206, 15210, 15215, 15219, 15223, 15227, 1951, 15231, 0}, {1914, 15202, 2791, 1927, 15206, 15210, 15215, 15219, 15223, 15227, 1951, 15231, 0}, 0, 0, 1, 3, {18,2351,0,0,0,0,0,0,0,0,0,0,0,0},{3048,3074,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{3094,0,0,0,0,0,0,0}}, + {925, 431, 436, {15236, 15248, 15259, 15273, 15285, 15295, 15305}, {15316, 15321, 15326, 15331, 15336, 15341, 15346}, {1285, 2894, 1608, 4532, 1828, 13432, 1616}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, 2, 1, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {109, 441, 444, {15872, 15877, 7673, 7680, 15883, 15890, 7697}, {15897, 15901, 7711, 7715, 15905, 7723, 7727}, {9428, 11804, 1285, 7731, 3099, 2892, 1285}, {7733, 7741, 15909, 1851, 7756, 1931, 15913, 15919, 1878, 1888, 1896, 15924, 0}, {7733, 7741, 15909, 1851, 7756, 1931, 15913, 15919, 1878, 1888, 1896, 15924, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 15933, 1943, 1947, 1951, 13346, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 15933, 1943, 1947, 1951, 13346, 0}, 0, 1, 1, 3, {2764,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {15937, 15954, 15971, 15988, 16005, 16022, 16031}, {16042, 16047, 16052, 16057, 16062, 16067, 16072}, {16077, 16080, 6081, 6081, 16083, 16077, 6081}, {16086, 16099, 16110, 16123, 16134, 16145, 16158, 16169, 16180, 16197, 16208, 16221, 0}, {16240, 16253, 16264, 16277, 16288, 16299, 16312, 16323, 16334, 16351, 16362, 16375, 0}, {16394, 16402, 16410, 16418, 16426, 16434, 16442, 16450, 16458, 16466, 16474, 16482, 0}, {16394, 16402, 16410, 16418, 16426, 16434, 16442, 16450, 16458, 16466, 16474, 16482, 0}, 0, 1, 1, 3, {18,3112,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3125, 448, 453, {16490, 16507, 16524, 16541, 16558, 16575, 16584}, {16597, 16605, 16613, 16623, 16633, 16575, 16643}, {16077, 16080, 16651, 16651, 16083, 16077, 16654}, {16657, 16670, 9888, 16685, 9908, 16698, 16707, 9929, 16716, 16733, 16748, 16761, 0}, {6087, 6100, 360, 6115, 380, 6128, 6137, 401, 6146, 6163, 6178, 6191, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, 0, 1, 55, 3, {3132,0,0,0,0,0,0,0,0,0,0,0,0,0},{3141,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{3160,0,0,0,0,0,0,0}}, + {109, 49, 52, {16776, 16785, 16794, 16802, 16811, 16820, 16827}, {16776, 16785, 16794, 16802, 16811, 16820, 16827}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {7733, 7741, 16836, 16842, 7756, 1861, 15913, 16849, 13301, 16856, 13318, 16863, 0}, {7733, 7741, 16836, 16842, 7756, 1861, 15913, 16849, 13301, 16856, 13318, 16863, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 16871, 1943, 1947, 1951, 7781, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 16871, 1943, 1947, 1951, 7781, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 0, 0, {16875, 16886, 16895, 16904, 16915, 16925, 16930}, {16937, 16941, 16944, 16947, 16951, 9416, 16954}, {16958, 1828, 1285, 7339, 1280, 9428, 16961}, {16964, 16972, 11617, 11622, 16979, 16984, 16990, 12137, 16996, 17006, 17015, 11673, 0}, {16964, 16972, 11617, 11622, 16979, 16984, 16990, 12137, 16996, 17006, 17015, 11673, 0}, {17023, 17028, 11617, 4614, 16979, 16984, 16990, 12237, 11696, 5109, 17032, 11704, 0}, {17023, 17028, 11617, 4614, 16979, 16984, 16990, 12237, 11696, 5109, 17032, 11704, 0}, 0, 1, 11, 3, {3176,681,0,0,0,0,0,0,0,0,0,0,0,0},{3191,0,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{3223,0,0,0,0,0,0,0}}, + {925, 458, 461, {17037, 17047, 17056, 17065, 17076, 17086, 17091}, {17098, 17102, 17107, 17112, 17117, 7723, 17121}, {17126, 1828, 1285, 5210, 1280, 2892, 1285}, {11533, 11540, 7354, 11547, 2760, 17128, 17133, 17138, 17145, 17153, 11589, 11596, 0}, {11603, 11610, 11617, 11622, 11628, 11632, 11637, 8914, 17160, 17168, 11666, 11673, 0}, {12906, 17175, 2791, 1927, 2760, 17179, 17183, 17187, 7707, 1947, 17191, 17195, 0}, {12906, 17175, 2791, 1927, 2760, 17179, 17183, 17187, 7707, 1947, 17191, 17195, 0}, 0, 1, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3239,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {109, 49, 52, {17199, 17218, 17237, 17262, 17281, 17315, 17340}, {17359, 17369, 17379, 17395, 17405, 17430, 17446}, {17456, 17460, 17467, 17471, 17478, 17485, 17492}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, 0, 0, 55, 11, {755,1062,744,755,744,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{1151,1146,3258,3267,0,0,0,0,0,0,0,0},{1173,1165,3275,3287,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 49, 52, {18324, 18343, 18362, 18384, 18403, 18425, 18450}, {18469, 18479, 18489, 18502, 18512, 18525, 18541}, {18551, 18555, 18562, 18569, 18576, 18583, 18590}, {18594, 18622, 18650, 18666, 18685, 18692, 18702, 18718, 18734, 18762, 18784, 18806, 0}, {18594, 18622, 18650, 18666, 18685, 18692, 18702, 18718, 18734, 18762, 18784, 18806, 0}, {18831, 18850, 18650, 18666, 18685, 18692, 18702, 18718, 18869, 18885, 18901, 18911, 0}, {18831, 18850, 18650, 18666, 18685, 18692, 18702, 18718, 18869, 18885, 18901, 18911, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 5, 8, {18924, 18943, 18962, 18987, 19006, 19028, 19053}, {19072, 19082, 19092, 19108, 19118, 19131, 19147}, {19157, 19161, 19168, 19172, 19179, 19186, 19193}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, {19197, 19219, 19241, 19263, 19282, 19289, 19299, 19315, 19331, 19362, 19384, 19406, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 494, 519, {19431, 19450, 19472, 19497, 19513, 19535, 19554}, {19564, 19578, 19592, 19606, 19617, 19631, 19554}, {19645, 19652, 19659, 19666, 19673, 19680, 19687}, {19691, 19707, 19732, 19751, 19770, 19777, 19790, 19803, 19822, 19853, 19878, 19900, 0}, {19691, 19707, 19732, 19751, 19770, 19777, 19790, 19803, 19822, 19853, 19878, 19900, 0}, {19925, 19933, 19947, 19961, 19770, 19777, 19790, 19972, 19980, 19994, 20005, 20013, 0}, {19925, 19933, 19947, 19961, 19770, 19777, 19790, 19972, 19980, 19994, 20005, 20013, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {20024, 20046, 20068, 20093, 20115, 20140, 20168}, {20190, 20200, 20210, 20223, 20233, 20246, 20262}, {20272, 20276, 20283, 20287, 20294, 20301, 20308}, {20312, 20328, 20353, 20372, 20394, 20401, 20414, 20427, 20446, 20477, 20502, 20521, 0}, {20312, 20328, 20353, 20372, 20394, 20401, 20414, 20427, 20446, 20477, 20502, 20521, 0}, {20546, 20553, 20353, 20569, 20394, 20401, 20414, 20427, 20585, 20607, 20623, 20633, 0}, {20546, 20553, 20353, 20569, 20394, 20401, 20414, 20427, 20585, 20607, 20623, 20633, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 544, 572, {20649, 20671, 20690, 20712, 20731, 20753, 20778}, {20797, 20810, 20820, 20833, 20843, 20856, 20872}, {20882, 20889, 20896, 20903, 20910, 20917, 20924}, {20928, 20944, 20969, 20988, 21010, 21017, 21030, 21043, 21062, 21093, 21118, 21140, 0}, {20928, 20944, 20969, 20988, 21010, 21017, 21030, 21043, 21062, 21093, 21118, 21140, 0}, {21165, 21172, 20969, 21188, 21010, 21017, 21030, 21204, 21211, 21233, 21249, 21262, 0}, {21165, 21172, 20969, 21188, 21010, 21017, 21030, 21204, 21211, 21233, 21249, 21262, 0}, 0, 0, 55, 3, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {3316, 49, 52, {21278, 21306, 21340, 21368, 21396, 21427, 21464}, {21492, 21505, 21524, 21540, 21553, 21572, 21591}, {21601, 21608, 21615, 21622, 21629, 21642, 21649}, {21653, 21672, 21700, 21722, 21741, 21754, 21764, 21777, 21802, 21833, 21858, 21874, 0}, {21653, 21672, 21700, 21722, 21741, 21754, 21764, 21777, 21802, 21833, 21858, 21874, 0}, {21893, 21903, 21922, 21932, 21741, 21754, 21764, 21948, 21955, 21980, 21996, 22006, 0}, {21893, 21903, 21922, 21932, 21741, 21754, 21764, 21948, 21955, 21980, 21996, 22006, 0}, 0, 0, 55, 11, {755,1062,775,2098,0,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{1151,1146,3258,3267,0,0,0,0,0,0,0,0},{1173,1165,3275,3287,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 594, 622, {22019, 22038, 22057, 22082, 22101, 22135, 22160}, {22179, 17369, 17379, 17395, 22189, 22214, 17446}, {0, 0, 0, 0, 0, 0, 0}, {22230, 22255, 22286, 22302, 17593, 17600, 17610, 22321, 22337, 22368, 22390, 22412, 0}, {22230, 22255, 22286, 22302, 17593, 17600, 17610, 22321, 22337, 22368, 22390, 22412, 0}, {22437, 22450, 22286, 22302, 17593, 17600, 17610, 22469, 22476, 22492, 22508, 22518, 0}, {22437, 22450, 22286, 22302, 17593, 17600, 17610, 22469, 22476, 22492, 22508, 22518, 0}, 0, 0, 55, 3, {744,0,0,0,0,0,0,0,0,0,0,0,0,0},{3324,0,0,0,0,0,0,0,0,0},{583,591,266,0,0,0,0,0,0,0,0,0},{600,611,271,0,0,0,0,0,0},{3343,3351,0,0,0,0,0,0}}, + {1, 644, 656, {14431, 14450, 22531, 14491, 14510, 14532, 14557}, {14576, 14586, 22553, 14609, 14619, 14632, 14648}, {14658, 14662, 14669, 14676, 14683, 14690, 14697}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 22661, 22677, 22702, 22724, 22752, 0}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 22661, 22677, 22702, 22724, 22752, 0}, {22774, 22787, 14736, 22806, 22641, 14778, 22648, 22822, 22829, 22848, 22864, 22886, 0}, {22774, 22787, 14736, 22806, 22641, 14778, 22648, 22822, 22829, 22848, 22864, 22886, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 665, 670, {22902, 22909, 22920, 22933, 22946, 22957, 22970}, {22981, 22986, 22991, 22996, 23001, 23006, 23011}, {22981, 22986, 22991, 22996, 23001, 23006, 23011}, {23016, 23042, 23070, 23100, 23130, 23156, 23186, 23212, 23240, 23264, 23292, 23329, 0}, {23016, 23042, 23070, 23100, 23130, 23156, 23186, 23212, 23240, 23264, 23292, 23329, 0}, {23368, 23380, 23392, 23404, 23416, 23428, 23440, 23452, 23464, 23476, 23489, 23502, 0}, {23368, 23380, 23392, 23404, 23416, 23428, 23440, 23452, 23464, 23476, 23489, 23502, 0}, 0, 1, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3361,3399,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {3431, 675, 697, {23515, 23543, 23571, 23608, 23639, 23673, 23704}, {23738, 23754, 23770, 23795, 23814, 23836, 23855}, {23877, 23884, 23891, 23901, 23911, 23921, 23931}, {23944, 23978, 24015, 24052, 24086, 24117, 24154, 24191, 24231, 24265, 24299, 24348, 0}, {24397, 24428, 24462, 24496, 24527, 24555, 24589, 24623, 24660, 24691, 24722, 24768, 0}, {24814, 24827, 24840, 24853, 24866, 24879, 24892, 24905, 24918, 24931, 24947, 24963, 0}, {24814, 24827, 24840, 24853, 24866, 24879, 24892, 24905, 24918, 24931, 24947, 24963, 0}, 0, 0, 1, 3, {379,388,397,428,417,406,446,439,453,0,0,0,0,0},{3455,3498,3546,3578,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{3615,666,0,0,0,0,0,0}}, + {109, 722, 725, {24979, 24988, 24998, 25010, 25023, 25032, 25044}, {25056, 25060, 12926, 25065, 25069, 25073, 25077}, {1285, 25081, 1608, 1608, 11804, 4532, 1285}, {25084, 25091, 25100, 25107, 1857, 25114, 25122, 25133, 25138, 25143, 25150, 25159, 0}, {25084, 25091, 25100, 25107, 1857, 25114, 25122, 25133, 25138, 25143, 25150, 25159, 0}, {25167, 25171, 12926, 25175, 1857, 25179, 25183, 25133, 25138, 25187, 25191, 25196, 0}, {25167, 25171, 12926, 25175, 1857, 25179, 25183, 25133, 25138, 25187, 25191, 25196, 0}, 2, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {25201, 25223, 25239, 25258, 25268, 25299, 25315}, {25201, 25223, 25239, 25258, 25268, 25299, 25315}, {25328, 25332, 25328, 25336, 25336, 25340, 25340}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, {25344, 25357, 25376, 25389, 25402, 25415, 25434, 25453, 25466, 25482, 25495, 25520, 0}, 0, 0, 1, 3, {9,417,0,0,0,0,0,0,0,0,0,0,0,0},{894,2363,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{3648,0,0,0,0,0,0,0}}, + {109, 728, 753, {25533, 25558, 25577, 25605, 25624, 25649, 25668}, {25690, 25706, 25716, 25735, 25745, 25761, 25771}, {25784, 25791, 25795, 25799, 25803, 25810, 25817}, {25821, 25840, 25856, 25869, 25882, 25904, 25923, 25945, 25961, 25977, 25990, 26006, 0}, {25821, 25840, 25856, 25869, 25882, 25904, 25923, 25945, 25961, 25977, 25990, 26006, 0}, {26022, 26031, 26040, 26049, 26058, 26067, 26079, 26088, 26097, 26106, 26115, 26124, 0}, {26022, 26031, 26040, 26049, 26058, 26067, 26079, 26088, 26097, 26106, 26115, 26124, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{3683,894,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 778, 794, {26133, 26161, 26183, 26202, 26227, 26252, 26271}, {26133, 26161, 26183, 26202, 26227, 26252, 26271}, {26281, 26281, 26285, 26289, 26293, 26297, 26301}, {26305, 26330, 26361, 26371, 26384, 26391, 26404, 26426, 26442, 26467, 26498, 26523, 0}, {26305, 26330, 26361, 26371, 26384, 26391, 26404, 26426, 26442, 26467, 26498, 26523, 0}, {26545, 26555, 26361, 26562, 26384, 26391, 26566, 26573, 26577, 26587, 26603, 26613, 0}, {26545, 26555, 26361, 26562, 26384, 26391, 26566, 26573, 26577, 26587, 26603, 26613, 0}, 0, 0, 55, 3, {744,304,0,0,0,0,0,0,0,0,0,0,0,0},{3710,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 165, 170, {2803, 26620, 2817, 26625, 26635, 26641, 2850}, {26648, 26653, 26658, 26663, 26669, 26674, 26679}, {1828, 1616, 1608, 1608, 2890, 2894, 1285}, {26685, 26693, 26702, 26708, 26714, 26719, 26725, 26731, 26738, 26747, 26755, 26764, 0}, {26773, 26781, 2910, 666, 5557, 26790, 26796, 2933, 5574, 5583, 5591, 26802, 0}, {26811, 13623, 26658, 26816, 26714, 26719, 26821, 26826, 26831, 26836, 13663, 26841, 0}, {26811, 13623, 26658, 26816, 26714, 26719, 26821, 26826, 26831, 26836, 13663, 26841, 0}, 2, 1, 1, 3, {18,3021,0,0,0,0,0,0,0,0,0,0,0,0},{1314,1261,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 644, 804, {26846, 14450, 26874, 14491, 14510, 14532, 14557}, {14576, 14586, 22553, 14609, 14619, 14632, 14648}, {0, 0, 0, 0, 0, 0, 0}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 26893, 26909, 26937, 22724, 22752, 0}, {22566, 22591, 14736, 22622, 22641, 14778, 22648, 26893, 26909, 26937, 22724, 22752, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, {4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, 4765, 4768, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,591,583,0,0,0,0,0,0,0,0},{89,271,611,600,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 816, 828, {26959, 26975, 26991, 27019, 27035, 27078, 27103}, {26959, 26975, 27131, 27019, 27141, 27163, 27176}, {27186, 27190, 27194, 27198, 27202, 27215, 27222}, {27229, 27248, 27273, 27292, 27317, 27330, 27343, 27356, 27378, 27412, 27437, 27465, 0}, {27229, 27248, 27273, 27292, 27317, 27330, 27343, 27356, 27378, 27412, 27437, 27465, 0}, {27493, 27500, 27510, 27292, 27317, 27330, 27343, 27523, 27533, 27546, 27556, 27569, 0}, {27493, 27500, 27510, 27292, 27317, 27330, 27343, 27523, 27533, 27546, 27556, 27569, 0}, 0, 1, 55, 11, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{3267,71,0,0,0,0,0,0,0,0,0,0},{3287,89,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 866, 876, {28047, 28057, 28064, 28077, 28087, 28097, 28107}, {28047, 28057, 28117, 28077, 28087, 28097, 28107}, {28127, 28131, 28135, 28139, 28143, 28147, 28151}, {28155, 28171, 28187, 28197, 28210, 28217, 28224, 28234, 28247, 28266, 28282, 28298, 0}, {28155, 28171, 28187, 28197, 28210, 28217, 28224, 28234, 28247, 28266, 28282, 28298, 0}, {28314, 28324, 28187, 28334, 28210, 28217, 28224, 28344, 28354, 28364, 28374, 28384, 0}, {28314, 28324, 28187, 28334, 28210, 28217, 28224, 28344, 28354, 28364, 28374, 28384, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 381, 409, {28601, 28620, 28639, 28664, 28683, 28705, 28730}, {28749, 14586, 28759, 14609, 28775, 14632, 14648}, {28788, 14662, 28792, 14676, 28796, 14690, 14697}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 14771, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, 0, 0, 1, 3, {932,941,948,957,460,417,968,0,0,0,0,0,0,0},{3763,3783,42,2448,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{3351,0,0,0,0,0,0,0}}, + {109, 49, 52, {28979, 28985, 28993, 29001, 29010, 29021, 29027}, {29033, 29036, 3084, 4997, 3090, 29039, 1275}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {29042, 29053, 13591, 1851, 29064, 29070, 2769, 13609, 29075, 1888, 29085, 29094, 0}, {29042, 29053, 13591, 1851, 29064, 29070, 2769, 13609, 29075, 1888, 29085, 29094, 0}, {1914, 1918, 29103, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 7781, 0}, {1914, 1918, 29103, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 7781, 0}, 2, 1, 55, 3, {744,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 0, 0, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, {29107, 29114, 29123, 29138, 29149, 29158, 29165, 29172, 29179, 29190, 29203, 29216, 0}, 0, 6, 1, 3, {379,417,0,0,0,0,0,0,0,0,0,0,0,0},{894,1217,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {29221, 29228, 29234, 29241, 29252, 29260, 29269}, {29276, 29280, 2791, 29284, 29288, 29292, 7727}, {29276, 29280, 2791, 29284, 29288, 29292, 7727}, {29296, 29302, 29310, 26708, 29316, 29321, 29327, 26731, 29333, 29343, 29351, 29361, 0}, {29296, 29302, 29310, 26708, 29316, 29321, 29327, 26731, 29333, 29343, 29351, 29361, 0}, {29371, 29375, 2791, 29379, 2760, 29383, 29387, 16871, 15223, 1947, 29391, 13346, 0}, {29371, 29375, 2791, 29379, 2760, 29383, 29387, 16871, 15223, 1947, 29391, 13346, 0}, 0, 0, 1, 3, {932,3009,0,0,0,0,0,0,0,0,0,0,0,0},{978,997,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 49, 52, {29614, 29621, 29629, 29636, 29643, 29651, 29660}, {29667, 29671, 29675, 29679, 29683, 7723, 28444}, {1616, 1616, 1610, 1616, 9428, 2892, 9428}, {29687, 29695, 29705, 29711, 29719, 29724, 29729, 29734, 29741, 16856, 29749, 29757, 0}, {29687, 29695, 29705, 29711, 29719, 29724, 29729, 29734, 29741, 16856, 29749, 29757, 0}, {1914, 29765, 2791, 29769, 2760, 28570, 28574, 29773, 2731, 1947, 29777, 13346, 0}, {1914, 29765, 2791, 29769, 2760, 28570, 28574, 29773, 2731, 1947, 29777, 13346, 0}, 0, 0, 1, 3, {295,3021,0,0,0,0,0,0,0,0,0,0,0,0},{1010,1029,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 928, 939, {29781, 29799, 29814, 29836, 29849, 29863, 29880}, {29904, 29912, 29917, 29836, 29849, 29929, 29936}, {0, 0, 0, 0, 0, 0, 0}, {29950, 29972, 29988, 30008, 30022, 30039, 30054, 30071, 30085, 30098, 30117, 30131, 0}, {29950, 29972, 29988, 30008, 30022, 30039, 30054, 30071, 30085, 30098, 30117, 30131, 0}, {30150, 30165, 30174, 30187, 30194, 30204, 30212, 30222, 30229, 30235, 30247, 30254, 0}, {30150, 30165, 30174, 30187, 30194, 30204, 30212, 30222, 30229, 30235, 30247, 30254, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 0, 0, {30266, 30274, 12472, 12968, 12490, 30285, 30295}, {12516, 12998, 12524, 12528, 12532, 12535, 30304}, {0, 0, 0, 0, 0, 0, 0}, {30308, 30317, 30327, 30335, 7756, 2764, 30343, 30349, 30358, 30367, 30376, 30385, 0}, {30308, 30317, 30327, 30335, 7756, 2764, 30343, 30349, 30358, 30367, 30376, 30385, 0}, {1914, 1918, 13006, 30394, 7756, 1931, 1935, 16871, 15223, 1947, 30398, 13346, 0}, {1914, 1918, 13006, 30394, 7756, 1931, 1935, 16871, 15223, 1947, 30398, 13346, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {3797, 949, 955, {30402, 30410, 30419, 30430, 30440, 30452, 30460}, {12516, 30470, 30475, 30480, 30485, 30489, 30493}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 30497, 30504, 30512, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1830, 1837, 30497, 30504, 30512, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1914, 1918, 30516, 29379, 30512, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 30516, 29379, 30512, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {775,9,755,0,0,0,0,0,0,0,0,0,0,0},{721,3806,798,2541,3819,3844,0,0,0,0},{71,266,1146,3870,0,0,0,0,0,0,0,0},{89,3882,3897,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3913, 965, 970, {30521, 30528, 30543, 30557, 30573, 30588, 30604}, {4528, 30619, 4512, 30623, 30627, 30631, 30635}, {1285, 9428, 1608, 1280, 1285, 1610, 9428}, {5011, 5019, 30639, 30646, 30653, 1649, 1654, 30658, 30668, 30679, 30688, 30698, 0}, {5011, 5019, 30639, 30646, 30653, 1649, 1654, 30658, 30668, 30679, 30688, 30698, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 5101, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 5101, 5105, 5109, 4642, 6911, 0}, 0, 0, 55, 3, {744,755,417,764,0,0,0,0,0,0,0,0,0,0},{3926,721,2561,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 975, 980, {30708, 30724, 30732, 30740, 30749, 30761, 30771}, {30781, 30787, 30793, 30797, 30801, 30809, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {30816, 30829, 30843, 30852, 30512, 30858, 30863, 30871, 13301, 30884, 13318, 13326, 0}, {30816, 30829, 30843, 30852, 30512, 30858, 30863, 30871, 13301, 30884, 13318, 13326, 0}, {30893, 1918, 30897, 13334, 30512, 30901, 1935, 30905, 1943, 30913, 1951, 13346, 0}, {30893, 1918, 30897, 13334, 30512, 30901, 1935, 30905, 1943, 30913, 1951, 13346, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 985, 988, {30919, 30927, 30935, 30943, 30950, 30958, 30966}, {30974, 30978, 30982, 30986, 7719, 30990, 30994}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {30998, 31006, 31018, 31030, 31035, 31042, 31053, 31064, 31072, 31081, 31094, 31102, 0}, {30998, 31006, 31018, 31030, 31035, 31042, 31053, 31064, 31072, 31081, 31094, 31102, 0}, {31109, 31113, 31117, 31121, 31125, 31129, 31133, 31137, 31141, 31145, 25077, 12918, 0}, {31109, 31113, 31117, 31121, 31125, 31129, 31133, 31137, 31141, 31145, 25077, 12918, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{978,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 991, 1011, {31149, 31162, 31172, 28077, 31182, 31192, 31202}, {31212, 31219, 31226, 31233, 31240, 31247, 31254}, {28131, 28131, 31261, 28139, 31265, 28147, 31269}, {31273, 31280, 31293, 31306, 31319, 31332, 31339, 31349, 31359, 31375, 31388, 31398, 0}, {31273, 31280, 31293, 31306, 31319, 31332, 31339, 31349, 31359, 31375, 31388, 31398, 0}, {31273, 31411, 31418, 31425, 31432, 31332, 31439, 31446, 31453, 31460, 31467, 31474, 0}, {31273, 31411, 31418, 31425, 31432, 31332, 31439, 31446, 31453, 31460, 31467, 31474, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{4538,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {31481, 31489, 31499, 31508, 31518, 31527, 31537}, {31546, 31549, 31552, 31555, 31558, 31561, 31564}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {31567, 31575, 31585, 31592, 7756, 31602, 31607, 31613, 31622, 31633, 31643, 31652, 0}, {31567, 31575, 31585, 31592, 7756, 31602, 31607, 31613, 31622, 31633, 31643, 31652, 0}, {31661, 31666, 31671, 31676, 7756, 31682, 31687, 31692, 31698, 31703, 31709, 31714, 0}, {31661, 31666, 31671, 31676, 7756, 31682, 31687, 31692, 31698, 31703, 31709, 31714, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 1031, 1035, {31719, 31724, 31731, 31739, 31746, 31754, 31760}, {31766, 15901, 29675, 31770, 15905, 30990, 7727}, {9428, 11804, 1610, 9428, 31774, 2892, 1285}, {31777, 31791, 31804, 31820, 31833, 31847, 31860, 31875, 31891, 31907, 31921, 31943, 0}, {31777, 31791, 31804, 31820, 31833, 31847, 31860, 31875, 31891, 31907, 31921, 31943, 0}, {31966, 31970, 25077, 31974, 31978, 31982, 31986, 31990, 31994, 31998, 32002, 32006, 0}, {31966, 31970, 25077, 31974, 31978, 31982, 31986, 31990, 31994, 31998, 32002, 32006, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{3763,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3982, 1039, 1046, {32010, 32020, 32030, 32040, 32050, 32060, 32070}, {32080, 32087, 32094, 32101, 32108, 32115, 32122}, {32129, 32133, 32137, 32141, 32145, 32149, 32153}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, {32157, 32164, 32171, 32178, 32185, 32192, 32199, 32206, 32213, 32220, 32227, 32237, 0}, 0, 0, 1, 3, {379,388,397,428,417,406,0,0,0,0,0,0,0,0},{4005,4029,4059,4089,4106,0,0,0,0,0},{583,266,71,0,0,0,0,0,0,0,0,0},{600,271,89,0,0,0,0,0,0},{4129,666,0,0,0,0,0,0}}, + {109, 975, 1053, {25056, 29280, 32247, 32254, 32264, 32269, 32276}, {25056, 29280, 32283, 32288, 32264, 32293, 32298}, {32303, 1616, 32306, 32309, 17126, 4532, 1825}, {32312, 32319, 32247, 32330, 32336, 32340, 32349, 32356, 32361, 32370, 32375, 32378, 0}, {32312, 32319, 32247, 32330, 32336, 32340, 32349, 32356, 32361, 32370, 32375, 32378, 0}, {32384, 32389, 32397, 32403, 32336, 32408, 32414, 32356, 32420, 32370, 32375, 32426, 0}, {32384, 32389, 32397, 32403, 32336, 32408, 32414, 32356, 32420, 32370, 32375, 32426, 0}, 2, 1, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3125, 1058, 1064, {32431, 32448, 32463, 32480, 32497, 32514, 32523}, {32534, 32539, 32544, 32549, 32554, 32559, 32564}, {32569, 10152, 10155, 10158, 10161, 10164, 10167}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, {32572, 32585, 32598, 32607, 32620, 32627, 32638, 32649, 32664, 32681, 32698, 32713, 0}, 0, 0, 55, 3, {388,397,417,428,0,0,0,0,0,0,0,0,0,0},{4146,4167,4193,4234,4280,0,0,0,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{4294,2717,666,0,0,0,0,0}}, + {673, 1070, 1075, {32728, 32736, 32746, 32756, 32765, 32775, 32783}, {32793, 32797, 32802, 32806, 32810, 32814, 13568}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 32818, 32827, 32838, 32847, 32857, 0}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 32818, 32827, 32838, 32847, 32857, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 1, 3, {18,9,775,755,417,0,0,0,0,0,0,0,0,0},{1217,1234,894,0,0,0,0,0,0,0},{71,266,1151,1243,1253,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {4315, 1080, 1085, {32867, 32892, 32917, 32942, 32955, 32970, 32987}, {33002, 33007, 33012, 33017, 33022, 33027, 310}, {16083, 16083, 33032, 6081, 6084, 16083, 6081}, {33035, 33054, 33069, 33091, 33111, 33125, 33139, 33151, 33175, 33197, 33214, 33231, 0}, {33248, 33267, 33282, 33304, 33324, 33340, 33356, 33370, 33396, 33420, 33437, 33231, 0}, {33454, 33463, 33472, 33479, 33486, 33493, 33500, 33507, 33514, 33521, 33528, 33535, 0}, {33454, 33463, 33472, 33479, 33486, 33493, 33500, 33507, 33514, 33521, 33528, 33535, 0}, 0, 1, 11, 3, {681,1208,417,4331,4341,0,0,0,0,0,0,0,0,0},{4354,4389,4418,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{4453,0,0,0,0,0,0,0}}, + {925, 49, 52, {33542, 33554, 33565, 33577, 33589, 33599, 33611}, {33626, 33631, 33636, 33641, 33646, 33651, 33656}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {33661, 33670, 33682, 33690, 33695, 33705, 33712, 33721, 33728, 33734, 33743, 33754, 0}, {33661, 33670, 33682, 33690, 33695, 33705, 33712, 33721, 33728, 33734, 33743, 33754, 0}, {33762, 33767, 33772, 33777, 33782, 33787, 33792, 33646, 33797, 33802, 33807, 33812, 0}, {33762, 33767, 33772, 33777, 33782, 33787, 33792, 33646, 33797, 33802, 33807, 33812, 0}, 0, 0, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3239,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {4469, 1090, 1092, {33817, 33830, 33838, 33847, 33857, 33867, 33876}, {33888, 33892, 33896, 33900, 33904, 33908, 33912}, {1828, 1616, 1608, 5210, 9428, 4089, 1285}, {33916, 33930, 33941, 33950, 33961, 33973, 33987, 33999, 34012, 34025, 34037, 34050, 0}, {34064, 34081, 34095, 34107, 34121, 34136, 34150, 34162, 34177, 34192, 34206, 34221, 0}, {34237, 34242, 34248, 34254, 34259, 34265, 34271, 34276, 34282, 34287, 15862, 34293, 0}, {34237, 34242, 34248, 34254, 34259, 34265, 34271, 34276, 34282, 34287, 15862, 34293, 0}, 2, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{4480,4502,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,0,0,0,0,0,0,0,0,0,0},{77,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 13, 19, {538, 547, 555, 563, 572, 579, 589}, {598, 602, 606, 610, 614, 618, 622}, {626, 629, 632, 635, 638, 641, 644}, {647, 653, 660, 666, 672, 677, 682, 689, 695, 704, 712, 721, 0}, {730, 739, 749, 758, 768, 776, 784, 794, 804, 816, 828, 840, 0}, {852, 857, 660, 863, 672, 677, 868, 873, 877, 882, 887, 892, 0}, {852, 857, 660, 863, 672, 677, 868, 873, 877, 882, 887, 892, 0}, 2, 1, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{315,338,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {967, 974, 981, 988, 995, 1002, 1009}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {379,388,397,406,417,428,439,446,453,460,0,0,0,0},{469,491,519,547,562,0,0,0,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {4575, 57, 63, {1747, 1755, 1762, 1771, 1780, 1791, 1799}, {1807, 1810, 1813, 1816, 1819, 1822, 1825}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {681,0,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 5, 8, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 2, 1, 1, 3, {18,9,857,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,876,2462,0,0,0,0,0,0},{71,266,62,906,0,0,0,0,0,0,0,0},{89,271,77,914,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1042, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {34628, 4610, 4512, 5613, 11628, 5093, 5097, 4630, 5105, 34632, 4642, 4646, 0}, {34628, 4610, 4512, 5613, 11628, 5093, 5097, 4630, 5105, 34632, 4642, 4646, 0}, 0, 0, 1, 3, {18,864,9,1054,857,755,417,0,0,0,0,0,0,0},{1069,1124,0,0,0,0,0,0,0,0},{62,906,266,71,0,0,0,0,0,0,0,0},{77,914,271,89,0,0,0,0,0},{1193,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 2, 1, 55, 3, {755,18,9,744,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,266,1151,1243,1253,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {4584, 49, 52, {4442, 4451, 4459, 4468, 4479, 4488, 4497}, {4504, 4508, 4512, 4516, 4520, 4524, 4528}, {1828, 1616, 1608, 1608, 4532, 2894, 1285}, {4534, 4542, 2910, 4551, 4558, 4565, 4572, 2933, 4579, 4589, 712, 4597, 0}, {4534, 4542, 2910, 4551, 4558, 4565, 4572, 2933, 4579, 4589, 712, 4597, 0}, {4606, 4610, 4512, 4614, 4618, 4622, 4626, 4630, 4634, 4638, 4642, 4646, 0}, {4606, 4610, 4512, 4614, 4618, 4622, 4626, 4630, 4634, 4638, 4642, 4646, 0}, 2, 1, 11, 3, {681,2785,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{4592,0,0,0,0,0,0,0}}, + {109, 165, 170, {4932, 4939, 4947, 4955, 4964, 4974, 4982}, {4991, 3081, 4994, 4997, 5000, 5003, 5006}, {5009, 1608, 1828, 2735, 1828, 2894, 5009}, {5011, 5019, 5028, 1639, 5034, 1649, 1654, 5038, 1666, 1676, 1684, 1693, 0}, {5011, 5019, 5028, 1639, 5034, 1649, 1654, 5038, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 5047, 1717, 5034, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 5047, 1717, 5034, 1722, 868, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 1, 3, {2764,1054,755,775,2024,417,0,0,0,0,0,0,0,0},{1217,968,894,1304,0,0,0,0,0,0},{266,71,4602,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1100, 1105, {1525, 7197, 34636, 1548, 1555, 1563, 34643}, {1578, 7225, 34651, 1591, 1595, 1599, 34655}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, 2, 1, 11, 3, {681,1455,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1042, 165, 170, {2803, 5440, 5454, 5467, 5480, 5493, 2850}, {2803, 34659, 34667, 34674, 34681, 34688, 2850}, {1828, 1285, 1610, 5530, 5530, 1285, 1285}, {5532, 5540, 5550, 666, 5557, 5562, 5568, 2933, 5574, 5583, 5591, 5600, 0}, {5532, 5540, 5550, 666, 5557, 5562, 5568, 2933, 5574, 5583, 5591, 5600, 0}, {5089, 5609, 4512, 5613, 3515, 5093, 5097, 4630, 4634, 5617, 4642, 5621, 0}, {5089, 5609, 4512, 5613, 3515, 5093, 5097, 4630, 4634, 5617, 4642, 5621, 0}, 2, 1, 1, 3, {18,681,744,9,775,755,406,428,417,460,4612,1690,0,0},{1124,1069,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{1193,0,0,0,0,0,0,0}}, + {109, 165, 170, {5792, 5802, 5807, 5814, 5823, 5827, 5834}, {34694, 29280, 2791, 34698, 34702, 34706, 34710}, {1828, 1616, 34715, 1816, 2892, 2894, 1285}, {5866, 5875, 5885, 5892, 3515, 5900, 5906, 1659, 5912, 5923, 5933, 5943, 0}, {5866, 5875, 5885, 5892, 3515, 5900, 5906, 1659, 5912, 5923, 5933, 5943, 0}, {5953, 1707, 1712, 1717, 3515, 5958, 5963, 1727, 2986, 882, 887, 1742, 0}, {5953, 1707, 1712, 1717, 3515, 5958, 5963, 1727, 2986, 882, 887, 1742, 0}, 0, 1, 11, 3, {681,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {4584, 175, 180, {5968, 5991, 211, 6014, 6025, 6040, 6055}, {6070, 285, 290, 295, 300, 305, 310}, {6075, 6078, 6075, 6081, 6084, 6078, 6081}, {6087, 6100, 360, 6115, 380, 6128, 6137, 401, 6146, 6163, 6178, 6191, 0}, {6206, 6219, 6234, 6245, 6258, 6265, 6274, 6283, 6298, 6315, 6330, 6343, 0}, {6358, 6366, 360, 6376, 380, 6128, 6137, 6384, 6392, 6402, 6410, 6420, 0}, {6358, 6366, 360, 6376, 380, 6128, 6137, 6384, 6392, 6402, 6410, 6420, 0}, 0, 1, 11, 3, {681,4621,0,0,0,0,0,0,0,0,0,0,0,0},{4638,4662,0,0,0,0,0,0,0,0},{266,0,0,0,0,0,0,0,0,0,0,0},{271,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 208, 211, {7189, 7197, 7205, 1548, 1555, 1563, 7212}, {7220, 7225, 7230, 1591, 7234, 1599, 7239}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {5011, 5019, 3504, 1639, 1645, 1649, 1654, 7244, 1666, 1676, 1684, 1693, 0}, {5011, 5019, 3504, 1639, 1645, 1649, 1654, 7244, 1666, 1676, 1684, 1693, 0}, {1702, 1707, 3504, 1717, 1645, 1649, 1654, 1727, 1732, 1737, 887, 1742, 0}, {1702, 1707, 3504, 1717, 1645, 1649, 1654, 1727, 1732, 1737, 887, 1742, 0}, 2, 1, 55, 3, {744,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {7465, 34718, 7489, 7498, 7505, 7518, 7527}, {7465, 34718, 7489, 7498, 7505, 7518, 7527}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 7578, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, 0, 0, 1, 3, {857,3021,0,0,0,0,0,0,0,0,0,0,0,0},{1010,1029,0,0,0,0,0,0,0,0},{906,266,0,0,0,0,0,0,0,0,0,0},{914,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 1110, 1115, {34725, 34736, 34760, 34790, 34807, 34829, 34838}, {34849, 34853, 34860, 34867, 34871, 34878, 34882}, {4756, 4744, 4746, 4748, 4750, 4752, 4754}, {34886, 9875, 9888, 9897, 9908, 34899, 34908, 9929, 34917, 34934, 34949, 9981, 0}, {34962, 34975, 360, 34988, 380, 34999, 35008, 401, 35017, 35034, 35049, 35062, 0}, {35075, 489, 35082, 496, 380, 35089, 35096, 503, 35103, 517, 35110, 531, 0}, {35075, 489, 35082, 496, 380, 35089, 35096, 503, 35103, 517, 35110, 531, 0}, 0, 1, 11, 3, {681,775,2098,9,417,0,0,0,0,0,0,0,0,0},{894,1261,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 327, 1120, {35117, 35126, 35138, 35147, 35154, 35163, 1247}, {12088, 12092, 35169, 12101, 35174, 35178, 12114}, {6516, 6518, 12118, 6522, 6522, 6518, 6522}, {1618, 1625, 12120, 12126, 1645, 8902, 8908, 12137, 1666, 1676, 12144, 1693, 0}, {12153, 12161, 12170, 12177, 5333, 12189, 12196, 12203, 6874, 12211, 12219, 6902, 0}, {5089, 4610, 12228, 4614, 1645, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, {5089, 4610, 12228, 4614, 1645, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, 2, 1, 124, 3, {692,4680,681,775,417,0,0,0,0,0,0,0,0,0},{798,721,692,0,0,0,0,0,0,0},{71,266,4689,4703,0,0,0,0,0,0,0,0},{89,4716,4733,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 0, 0, {12950, 12957, 12472, 12968, 12490, 12977, 12988}, {12688, 12998, 12524, 12528, 12532, 13002, 13006}, {0, 0, 0, 0, 0, 0, 0}, {13010, 13020, 13029, 13037, 13046, 13059, 13071, 13078, 13085, 13092, 13102, 13114, 0}, {13010, 13020, 13029, 13037, 13046, 13059, 13071, 13078, 13085, 13092, 13102, 13114, 0}, {13127, 12776, 13131, 13135, 12664, 13139, 13143, 12672, 13147, 13151, 13155, 13159, 0}, {13127, 12776, 13131, 13135, 12664, 13139, 13143, 12672, 13147, 13151, 13155, 13159, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {4749, 431, 436, {15236, 15248, 15259, 15273, 15285, 15295, 15305}, {15316, 15321, 15326, 15331, 15336, 15341, 15346}, {1285, 2894, 1608, 4532, 1828, 13432, 1616}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, 2, 1, 55, 3, {417,1690,0,0,0,0,0,0,0,0,0,0,0,0},{4762,4786,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 165, 170, {15579, 15593, 15603, 15614, 15628, 15639, 15650}, {15663, 15668, 15673, 15680, 15686, 15692, 15698}, {1828, 1616, 1608, 5210, 1828, 9428, 1285}, {15703, 15711, 15719, 15726, 15735, 15745, 15755, 15761, 15769, 15784, 15802, 15810, 0}, {15703, 15711, 15719, 15726, 15735, 15745, 15755, 15761, 15769, 15784, 15802, 15810, 0}, {15818, 15822, 15719, 15828, 15832, 15837, 15755, 15843, 15848, 15855, 15862, 15867, 0}, {15818, 15822, 15719, 15828, 15832, 15837, 15755, 15843, 15848, 15855, 15862, 15867, 0}, 2, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 441, 444, {15872, 15877, 7673, 7680, 15883, 15890, 7697}, {15897, 15901, 7711, 7715, 15905, 7723, 7727}, {9428, 11804, 1285, 7731, 3099, 2892, 1285}, {7733, 7741, 15909, 1851, 7756, 1931, 15913, 15919, 1878, 1888, 1896, 15924, 0}, {7733, 7741, 15909, 1851, 7756, 1931, 15913, 15919, 1878, 1888, 1896, 15924, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 15933, 1943, 1947, 1951, 13346, 0}, {1914, 1918, 15909, 1927, 7756, 1931, 1935, 15933, 1943, 1947, 1951, 13346, 0}, 0, 1, 1, 3, {2764,304,0,0,0,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 1133, 1138, {35183, 35198, 35213, 35228, 35245, 16575, 35262}, {35273, 35280, 35287, 35294, 35301, 35308, 35315}, {35322, 16080, 6081, 6084, 6078, 16077, 16651}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {35325, 34975, 360, 34988, 380, 35336, 35343, 401, 35350, 35365, 35378, 35062, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, 0, 1, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3239,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {1, 49, 52, {17199, 17218, 17237, 17262, 17281, 17315, 17340}, {17359, 17369, 17379, 17395, 17405, 17430, 17446}, {17456, 17460, 17467, 17471, 17478, 17485, 17492}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, {17496, 17524, 17558, 17574, 17593, 17600, 17610, 17626, 17642, 17673, 17695, 17717, 0}, 0, 5, 55, 11, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{1151,1146,3258,3267,0,0,0,0,0,0,0,0},{1173,1165,3275,3287,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 464, 479, {7465, 34718, 7489, 35389, 7505, 7518, 7527}, {17899, 17906, 17916, 17929, 17942, 17952, 17971}, {17993, 17997, 18004, 18011, 18021, 18028, 18041}, {7536, 7547, 7558, 7567, 35398, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 35398, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {18228, 18235, 18083, 18245, 18115, 18122, 18261, 18274, 18281, 18291, 18304, 18314, 0}, {18228, 18235, 18083, 18245, 18115, 18122, 18261, 18274, 18281, 18291, 18304, 18314, 0}, 0, 0, 55, 11, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{3298,894,0,0,0,0,0,0,0,0},{4804,62,266,71,0,0,0,0,0,0,0,0},{4812,77,271,89,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 494, 519, {19431, 19450, 19472, 19497, 19513, 19535, 19554}, {19564, 19578, 19592, 19606, 19617, 19631, 19554}, {19645, 19652, 19659, 19666, 19673, 19680, 19687}, {19691, 19707, 19732, 19751, 19770, 19777, 19790, 19803, 19822, 19853, 19878, 19900, 0}, {19691, 19707, 19732, 19751, 19770, 19777, 19790, 19803, 19822, 19853, 19878, 19900, 0}, {19925, 19933, 19947, 19961, 19770, 19777, 19790, 19972, 19980, 19994, 20005, 20013, 0}, {19925, 19933, 19947, 19961, 19770, 19777, 19790, 19972, 19980, 19994, 20005, 20013, 0}, 0, 1, 55, 3, {2015,3021,0,0,0,0,0,0,0,0,0,0,0,0},{1010,1029,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 381, 409, {28601, 28620, 28639, 28664, 28683, 28705, 28730}, {28749, 14586, 28759, 14609, 28775, 14632, 14648}, {28788, 14662, 28792, 14676, 28796, 14690, 14697}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 14771, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, {14701, 28803, 14736, 28831, 22641, 28850, 14788, 28860, 28876, 28907, 28929, 28954, 0}, 0, 0, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{2979,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {1, 991, 1011, {31149, 31162, 31172, 28077, 31182, 31192, 31202}, {31212, 31219, 31226, 31233, 31240, 31247, 31254}, {28131, 28131, 28131, 28139, 31265, 28147, 31269}, {31273, 31280, 31293, 31306, 31319, 31332, 31339, 31349, 31359, 31375, 31388, 31398, 0}, {31273, 31280, 31293, 31306, 31319, 31332, 31339, 31349, 31359, 31375, 31388, 31398, 0}, {31273, 31411, 31418, 31425, 31432, 31332, 31439, 31446, 31453, 31460, 31467, 31474, 0}, {31273, 31411, 31418, 31425, 31432, 31332, 31439, 31446, 31453, 31460, 31467, 31474, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{3945,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,0,0,0,0,0,0,0,0,0,0},{77,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {34299, 34306, 34313, 34320, 34327, 34334, 34341}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {295,857,9,439,460,379,406,417,0,0,0,0,0,0},{469,1484,547,562,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {4575, 57, 63, {1747, 1755, 1762, 1771, 1780, 1791, 1799}, {1807, 1810, 1813, 1816, 1819, 1822, 1825}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {35532, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {35532, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {35540, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {35540, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {681,0,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {35545, 35550, 35555, 35560, 35565, 35570, 35575}, {32793, 35580, 35583, 35587, 35590, 35594, 13568}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {13618, 13623, 26658, 13633, 2760, 13638, 13643, 13648, 13653, 35597, 13663, 26841, 0}, {13618, 13623, 26658, 13633, 2760, 13638, 13643, 13648, 13653, 35597, 13663, 26841, 0}, 0, 0, 1, 3, {2764,1054,857,295,9,18,968,1274,417,460,406,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,266,71,0,0,0,0,0,0,0,0,0},{914,271,89,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1042, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 2890, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, 2, 1, 1, 3, {18,9,1054,857,1062,755,775,417,0,0,0,0,0,0},{1069,1097,1124,0,0,0,0,0,0,0},{266,71,1146,1151,1157,0,0,0,0,0,0,0},{271,89,1165,1173,1182,0,0,0,0},{1193,0,0,0,0,0,0,0}}, + {109, 165, 170, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 35602, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 35602, 3532, 2986, 882, 887, 3590, 0}, 0, 0, 55, 3, {417,1690,755,4823,9,864,0,0,0,0,0,0,0,0},{894,304,0,0,0,0,0,0,0,0},{71,266,1151,1243,1253,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {4749, 431, 436, {15236, 35609, 35621, 35636, 35647, 35658, 35669}, {15316, 15321, 15326, 15331, 15336, 15341, 15346}, {1285, 1608, 1828, 4532, 1828, 13432, 1616}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15351, 15368, 15381, 15395, 15408, 15421, 15434, 15448, 15460, 15474, 15488, 15502, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, {15515, 15522, 15527, 15532, 15536, 15541, 15546, 15551, 15556, 15563, 15568, 15574, 0}, 2, 1, 11, 3, {1208,681,2098,417,0,0,0,0,0,0,0,0,0,0},{4832,4786,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,0,0,0,0,0,0,0,0,0,0},{77,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {967, 974, 981, 988, 995, 1002, 1009}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {295,857,9,439,460,379,406,417,0,0,0,0,0,0},{469,1484,547,4518,0,0,0,0,0,0},{583,591,266,71,0,0,0,0,0,0,0,0},{600,611,271,89,0,0,0,0,0},{623,639,652,0,0,0,0,0}}, + {4575, 57, 63, {1747, 1755, 1762, 1771, 1780, 1791, 1799}, {1807, 1810, 1813, 1816, 1819, 1822, 1825}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {681,0,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 55, 3, {417,18,9,857,1690,4858,968,2796,417,0,0,0,0,0},{997,3763,4866,1475,0,0,0,0,0,0},{906,62,71,266,0,0,0,0,0,0,0,0},{914,77,89,271,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {2764,0,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {4584, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 2, 1, 11, 3, {681,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{4592,0,0,0,0,0,0,0}}, + {673, 49, 52, {6428, 6437, 6449, 6456, 6464, 6474, 6480}, {6487, 6491, 6495, 6499, 6503, 6508, 6512}, {1278, 1280, 35681, 1285, 1287, 1280, 1285}, {6527, 6537, 6546, 6554, 6562, 6570, 6577, 6584, 6592, 1364, 6598, 6606, 0}, {6615, 6625, 6634, 6642, 6650, 6658, 6665, 6672, 6681, 5385, 6687, 6697, 0}, {6706, 6710, 6715, 6720, 6724, 5419, 1501, 6728, 6732, 1517, 6736, 1521, 0}, {6706, 6710, 6715, 6720, 6724, 5419, 1501, 6728, 6732, 1517, 6736, 1521, 0}, 0, 1, 11, 3, {2181,4935,0,0,0,0,0,0,0,0,0,0,0,0},{2254,2225,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, 0, 6, 55, 3, {744,755,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{266,71,62,0,0,0,0,0,0,0,0,0},{271,89,77,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {34299, 34306, 34313, 34320, 34327, 34334, 34341}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {295,857,9,439,460,379,406,417,0,0,0,0,0,0},{469,4959,4986,764,547,4518,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {4575, 57, 63, {1747, 1755, 1762, 1771, 1780, 1791, 1799}, {1807, 1810, 1813, 1816, 1819, 1822, 1825}, {1285, 1608, 1828, 1608, 1828, 1614, 1285}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1830, 1837, 1845, 1851, 1857, 1861, 1866, 1871, 1878, 1888, 1896, 1905, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, {1914, 1918, 1922, 1927, 1857, 1931, 1935, 1939, 1943, 1947, 1951, 1955, 0}, 2, 1, 11, 3, {681,0,0,0,0,0,0,0,0,0,0,0,0,0},{798,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {5002, 165, 170, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {2764,0,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 1, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 2, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1143, 1154, {6428, 6437, 6449, 6456, 6464, 6474, 6480}, {6487, 6491, 6495, 6499, 6503, 6508, 6512}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {1618, 1625, 11617, 1639, 1645, 1649, 1654, 8914, 35745, 35755, 35763, 35772, 0}, {1618, 1625, 11617, 1639, 1645, 1649, 1654, 8914, 35745, 35755, 35763, 35772, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, 0, 1, 11, 3, {2181,5019,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 32620, 35447, 35785, 35798, 35805, 35493, 35816, 35827, 0}, {35403, 35414, 10194, 35427, 32620, 35447, 35785, 35798, 35805, 35493, 35816, 35827, 0}, {35403, 35414, 10194, 35427, 32620, 35447, 35785, 35798, 35805, 35493, 35816, 35827, 0}, {35403, 35414, 10194, 35427, 32620, 35447, 35785, 35798, 35805, 35493, 35816, 35827, 0}, 0, 6, 55, 3, {744,755,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{266,71,62,0,0,0,0,0,0,0,0,0},{271,89,77,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {5002, 165, 170, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 2, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,906,0,0,0,0,0,0,0,0,0,0},{89,914,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {5055, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {957,0,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 2, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1162, 1174, {6428, 35838, 6449, 6456, 6464, 6474, 6480}, {8879, 5179, 35849, 35853, 8889, 8895, 35857}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {1702, 1707, 11617, 1717, 1645, 5093, 5097, 8921, 2986, 1737, 887, 1742, 0}, {1702, 1707, 11617, 1717, 1645, 5093, 5097, 8921, 2986, 1737, 887, 1742, 0}, 0, 1, 11, 3, {2151,2181,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{71,1151,0,0,0,0,0,0,0,0,0,0},{89,1173,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, {35683, 35694, 10194, 35705, 32620, 35716, 35725, 35738, 35480, 35493, 35506, 35519, 0}, 0, 0, 55, 3, {744,755,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{266,71,62,0,0,0,0,0,0,0,0,0},{271,89,77,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {406,2351,0,0,0,0,0,0,0,0,0,0,0,0},{2462,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {673, 1183, 1205, {35862, 35877, 35896, 35909, 35924, 35941, 7877}, {12299, 12307, 35952, 35958, 12331, 12339, 35964}, {315, 318, 35972, 324, 327, 318, 324}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {12395, 36085, 360, 6376, 12370, 36003, 36010, 6384, 12435, 6402, 36093, 36101, 0}, {12395, 36085, 360, 6376, 12370, 36003, 36010, 6384, 12435, 6402, 36093, 36101, 0}, 0, 1, 11, 3, {2151,2181,0,0,0,0,0,0,0,0,0,0,0,0},{721,2561,798,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {5002, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 2, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {3316, 1221, 1239, {36109, 35877, 35896, 35909, 35924, 35941, 7877}, {36122, 36129, 36136, 36143, 36150, 36157, 36164}, {315, 318, 35972, 324, 327, 318, 324}, {35975, 35988, 360, 369, 12370, 12377, 12386, 401, 36017, 36036, 36051, 36068, 0}, {35975, 35988, 360, 369, 12370, 12377, 12386, 401, 36017, 36036, 36051, 36068, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, 0, 1, 11, 3, {1208,2098,692,681,4680,775,5063,417,0,0,0,0,0,0},{721,2561,798,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 0, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {29480, 36192, 29484, 29484, 36194, 36196, 6522}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, 0, 0, 1, 3, {2764,0,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1254, 1174, {8833, 35838, 6449, 8858, 6464, 6474, 6480}, {6487, 6491, 6495, 36198, 6503, 6508, 6512}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, 0, 1, 11, 11, {2151,2181,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {5074, 88, 1264, {36202, 36213, 36225, 36237, 36245, 36256, 36270}, {36280, 36284, 1645, 36288, 36292, 36296, 15346}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {36301, 36319, 36333, 36349, 36365, 36378, 36390, 36404, 36417, 36433, 36449, 36464, 0}, {36301, 36319, 36333, 36349, 36365, 36378, 36390, 36404, 36417, 36433, 36449, 36464, 0}, {36479, 36485, 36492, 36501, 36510, 36516, 36521, 36528, 36534, 36543, 36552, 36560, 0}, {36479, 36485, 36492, 36501, 36510, 36516, 36521, 36528, 36534, 36543, 36552, 36560, 0}, 2, 1, 11, 3, {1208,681,2098,417,0,0,0,0,0,0,0,0,0,0},{5088,0,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {18,2796,0,0,0,0,0,0,0,0,0,0,0,0},{2462,1261,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {29296, 36568, 26702, 26708, 29316, 36576, 36582, 26731, 36588, 36598, 36606, 36616, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 36626, 704, 2951, 2961, 0}, {36636, 13623, 26658, 26816, 36641, 13638, 13643, 26826, 26831, 35597, 13663, 36646, 0}, {36636, 13623, 26658, 26816, 36641, 13638, 13643, 26826, 26831, 35597, 13663, 36646, 0}, 0, 0, 1, 3, {2764,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1221, 1205, {36109, 35877, 35896, 6014, 35924, 35941, 7877}, {36122, 36129, 36136, 36651, 36150, 36157, 36164}, {315, 318, 35972, 324, 327, 318, 324}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, 0, 1, 11, 3, {2181,0,0,0,0,0,0,0,0,0,0,0,0,0},{2225,2239,2254,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5106,0,0,0,0,0,0,0}}, + {109, 1268, 1273, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 1, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1162, 1174, {6428, 35838, 6449, 6456, 6464, 6474, 6480}, {8879, 5179, 35849, 35853, 8889, 8895, 35857}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {1702, 1707, 11617, 1717, 1645, 5093, 5097, 8921, 2986, 1737, 887, 1742, 0}, {1702, 1707, 11617, 1717, 1645, 5093, 5097, 8921, 2986, 1737, 887, 1742, 0}, 0, 1, 11, 11, {2151,2181,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, {34460, 34484, 34493, 34502, 34513, 34522, 34535, 34544, 34549, 34560, 34582, 34606, 0}, 0, 1, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {1, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {295,5116,0,0,0,0,0,0,0,0,0,0,0,0},{2462,1261,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 1, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1183, 1205, {35862, 35877, 35896, 35909, 35924, 35941, 7877}, {12299, 12307, 35952, 35958, 12331, 12339, 35964}, {315, 318, 35972, 324, 327, 318, 324}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {12395, 36085, 360, 6376, 12370, 36003, 36010, 6384, 12435, 6402, 36093, 36101, 0}, {12395, 36085, 360, 6376, 12370, 36003, 36010, 6384, 12435, 6402, 36093, 36101, 0}, 0, 1, 11, 3, {2151,2161,2169,2181,2193,2203,2213,5128,0,0,0,0,0,0},{2225,2239,2254,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, 0, 1, 55, 3, {744,0,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{5106,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {29296, 36568, 26702, 26708, 29316, 36576, 36582, 26731, 36588, 36598, 36606, 36616, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 36626, 704, 2951, 2961, 0}, {36636, 13623, 26658, 26816, 36641, 13638, 13643, 26826, 26831, 35597, 13663, 36646, 0}, {36636, 13623, 26658, 26816, 36641, 13638, 13643, 26826, 26831, 35597, 13663, 36646, 0}, 0, 1, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{266,71,62,906,0,0,0,0,0,0,0,0},{271,89,77,914,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 165, 170, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {1702, 36658, 1712, 3579, 3515, 36664, 3584, 3532, 2986, 882, 887, 3590, 0}, {1702, 36658, 1712, 3579, 3515, 36664, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 6, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {5002, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 2986, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {3410, 3419, 3425, 3431, 3440, 3446, 3455}, {3462, 2863, 1712, 3467, 3472, 3477, 3482}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3487, 3495, 3504, 3509, 3515, 3519, 3524, 3532, 3538, 3548, 712, 3556, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, {3566, 3572, 3504, 3579, 3515, 3519, 3584, 3532, 2986, 882, 887, 3590, 0}, 0, 0, 1, 3, {18,304,0,0,0,0,0,0,0,0,0,0,0,0},{1217,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {1, 1094, 1097, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34348, 34359, 34374, 34391, 34408, 34421, 34434}, {34445, 34448, 34451, 34454, 34457, 10164, 10155}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, {35403, 35414, 10194, 35427, 35438, 35447, 35458, 35469, 35480, 35493, 35506, 35519, 0}, 0, 6, 1, 3, {18,9,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{62,71,266,0,0,0,0,0,0,0,0,0},{77,89,271,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 55, 3, {744,755,1062,2098,417,0,0,0,0,0,0,0,0,0},{1261,894,0,0,0,0,0,0,0,0},{71,266,62,0,0,0,0,0,0,0,0,0},{89,271,4812,77,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 1, 1, 3, {295,857,18,9,417,0,0,0,0,0,0,0,0,0},{1010,1029,0,0,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{98,734,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {109, 49, 52, {2650, 2657, 2664, 2672, 2682, 2691, 2698}, {2707, 2711, 2715, 2719, 2723, 2727, 2731}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {2737, 2745, 2754, 1851, 2760, 2764, 2769, 1871, 1878, 2774, 1896, 2782, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, {1914, 1918, 2791, 1927, 2760, 1931, 1935, 1939, 1943, 2795, 1951, 2799, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{876,894,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{5140,5168,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {4877, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {5055, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {957,0,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{5009,0,0,0,0,0,0,0}}, + {925, 13, 19, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {932,941,948,957,460,417,968,0,0,0,0,0,0,0},{3763,3783,42,2448,0,0,0,0,0,0},{906,62,266,71,0,0,0,0,0,0,0,0},{914,77,271,89,0,0,0,0,0},{1193,0,0,0,0,0,0,0}}, + {4877, 165, 170, {2803, 2811, 2817, 2824, 2835, 2842, 2850}, {2858, 2863, 1712, 2868, 2874, 2879, 2884}, {1828, 1616, 1608, 1608, 2892, 2894, 1285}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2896, 2902, 2910, 666, 2916, 2921, 2927, 2933, 2940, 704, 2951, 2961, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, {2971, 1707, 1712, 863, 2976, 1722, 868, 2981, 1732, 882, 887, 2992, 0}, 0, 0, 1, 3, {295,304,0,0,0,0,0,0,0,0,0,0,0,0},{4885,4913,0,0,0,0,0,0,0,0},{906,71,0,0,0,0,0,0,0,0,0,0},{914,89,0,0,0,0,0,0,0},{355,0,0,0,0,0,0,0}}, + {3316, 1221, 1239, {36109, 35877, 35896, 35909, 35924, 35941, 7877}, {36122, 36129, 36136, 36143, 36150, 36157, 36164}, {315, 318, 35972, 324, 327, 318, 324}, {35975, 35988, 360, 369, 12370, 12377, 12386, 401, 36017, 36036, 36051, 36068, 0}, {35975, 35988, 360, 369, 12370, 12377, 12386, 401, 36017, 36036, 36051, 36068, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, 0, 1, 11, 3, {1208,2098,692,681,4680,775,5063,417,0,0,0,0,0,0},{721,2561,798,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {673, 1143, 1154, {6428, 6437, 6449, 6456, 6464, 6474, 6480}, {6487, 6491, 6495, 6499, 6503, 6508, 6512}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {1618, 1625, 11617, 1639, 1645, 1649, 1654, 8914, 35745, 35755, 35763, 35772, 0}, {1618, 1625, 11617, 1639, 1645, 1649, 1654, 8914, 35745, 35755, 35763, 35772, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, 0, 1, 11, 3, {2181,5019,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {673, 1221, 1205, {36109, 35877, 35896, 6014, 35924, 35941, 7877}, {36122, 36129, 36136, 36651, 36150, 36157, 36164}, {315, 318, 35972, 324, 327, 318, 324}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, 0, 1, 11, 3, {2181,0,0,0,0,0,0,0,0,0,0,0,0,0},{2225,2239,2254,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {673, 1254, 1174, {8833, 35838, 6449, 8858, 6464, 6474, 6480}, {6487, 6491, 6495, 36198, 6503, 6508, 6512}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {1618, 1625, 11617, 1639, 1645, 5093, 5097, 8914, 35745, 35755, 35763, 35772, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, 0, 1, 11, 11, {2151,2181,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {5074, 88, 1264, {36202, 36213, 36225, 36237, 36245, 36256, 36270}, {36280, 36284, 1645, 36288, 36292, 36296, 15346}, {1285, 1608, 1610, 2735, 1610, 1614, 1285}, {36301, 36319, 36333, 36349, 36365, 36378, 36390, 36404, 36417, 36433, 36449, 36464, 0}, {36301, 36319, 36333, 36349, 36365, 36378, 36390, 36404, 36417, 36433, 36449, 36464, 0}, {36479, 36485, 36492, 36501, 36510, 36516, 36521, 36528, 36534, 36543, 36552, 36560, 0}, {36479, 36485, 36492, 36501, 36510, 36516, 36521, 36528, 36534, 36543, 36552, 36560, 0}, 2, 1, 11, 3, {1208,681,2098,417,0,0,0,0,0,0,0,0,0,0},{5088,0,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {109, 1110, 1115, {34725, 34736, 34760, 34790, 34807, 34829, 34838}, {34849, 34853, 34860, 34867, 34871, 34878, 34882}, {4756, 4744, 4746, 4748, 4750, 4752, 4754}, {34886, 9875, 9888, 9897, 9908, 34899, 34908, 9929, 34917, 34934, 34949, 9981, 0}, {34962, 34975, 360, 34988, 380, 34999, 35008, 401, 35017, 35034, 35049, 35062, 0}, {35075, 489, 35082, 496, 380, 35089, 35096, 503, 35103, 517, 35110, 531, 0}, {35075, 489, 35082, 496, 380, 35089, 35096, 503, 35103, 517, 35110, 531, 0}, 0, 1, 11, 3, {681,775,2098,9,417,0,0,0,0,0,0,0,0,0},{894,1261,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {967, 974, 981, 988, 995, 1002, 1009}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1044, 1051, 1058, 1065, 1072, 1079, 1086, 1093, 1100, 1107, 1114, 1124, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {379,388,397,406,417,428,439,446,453,460,0,0,0,0},{469,491,519,547,562,0,0,0,0,0},{266,71,583,591,0,0,0,0,0,0,0,0},{271,89,600,611,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {673, 1100, 1105, {1525, 7197, 34636, 1548, 1555, 1563, 34643}, {1578, 7225, 34651, 1591, 1595, 1599, 34655}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, 2, 1, 11, 3, {681,1455,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1143, 1154, {6428, 6437, 6449, 6456, 6464, 6474, 6480}, {6487, 6491, 6495, 6499, 6503, 6508, 6512}, {6516, 6518, 6520, 6522, 6524, 6518, 6522}, {1618, 1625, 11617, 1639, 1645, 1649, 1654, 8914, 35745, 35755, 35763, 35772, 0}, {1618, 1625, 11617, 1639, 1645, 1649, 1654, 8914, 35745, 35755, 35763, 35772, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, {5089, 4610, 4512, 4614, 1645, 5093, 5097, 35781, 5105, 5109, 4642, 6911, 0}, 0, 1, 11, 3, {2181,5019,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {109, 49, 52, {11414, 11420, 11434, 11457, 11471, 11487, 11494}, {11503, 11506, 11511, 11517, 11521, 11526, 11529}, {4756, 4744, 4746, 4748, 4750, 4752, 4754}, {11533, 11540, 7354, 11547, 2760, 11553, 11559, 11565, 11572, 11581, 11589, 11596, 0}, {11603, 11610, 11617, 11622, 11628, 11632, 11637, 11642, 11649, 11658, 11666, 11673, 0}, {11680, 5609, 4512, 4614, 11628, 11684, 11688, 11692, 11696, 5109, 11700, 11704, 0}, {11680, 5609, 4512, 4614, 11628, 11684, 11688, 11692, 11696, 5109, 11700, 11704, 0}, 0, 1, 11, 3, {681,304,0,0,0,0,0,0,0,0,0,0,0,0},{2843,894,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 1133, 1138, {35183, 35198, 35213, 35228, 35245, 16575, 35262}, {35273, 35280, 35287, 35294, 35301, 35308, 35315}, {35322, 16080, 6081, 6084, 6078, 16077, 16651}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {35325, 34975, 360, 34988, 380, 35336, 35343, 401, 35350, 35365, 35378, 35062, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, 0, 1, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3239,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {925, 665, 670, {22902, 22909, 22920, 22933, 22946, 22957, 22970}, {22981, 22986, 22991, 22996, 23001, 23006, 23011}, {22981, 22986, 22991, 22996, 23001, 23006, 23011}, {23016, 23042, 23070, 23100, 23130, 23156, 23186, 23212, 23240, 23264, 23292, 23329, 0}, {23016, 23042, 23070, 23100, 23130, 23156, 23186, 23212, 23240, 23264, 23292, 23329, 0}, {23368, 23380, 23392, 23404, 23416, 23428, 23440, 23452, 23464, 23476, 23489, 23502, 0}, {23368, 23380, 23392, 23404, 23416, 23428, 23440, 23452, 23464, 23476, 23489, 23502, 0}, 0, 1, 55, 3, {417,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3361,3399,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {34299, 34306, 34313, 34320, 34327, 34334, 34341}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {295,857,9,439,460,379,406,417,0,0,0,0,0,0},{469,1484,547,562,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {370, 25, 32, {897, 907, 917, 927, 937, 947, 957}, {34299, 34306, 34313, 34320, 34327, 34334, 34341}, {1016, 1020, 1024, 1028, 1032, 1036, 1040}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, {1134, 1139, 1144, 1149, 1154, 1159, 1164, 1169, 1174, 1179, 1185, 1191, 0}, 0, 0, 1, 3, {295,857,9,439,460,379,406,417,0,0,0,0,0,0},{469,1484,547,562,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{623,639,652,666,0,0,0,0}}, + {2090, 165, 170, {1525, 1533, 1540, 1548, 1555, 1563, 1570}, {5052, 5058, 5063, 5068, 5073, 5078, 5083}, {1285, 1608, 1610, 1612, 1610, 1614, 1616}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {1618, 1625, 3504, 1639, 3515, 1649, 1654, 1659, 1666, 1676, 1684, 4420, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, {5089, 4610, 4512, 4614, 3515, 5093, 5097, 5101, 5105, 5109, 4642, 5113, 0}, 2, 1, 11, 11, {681,1455,0,0,0,0,0,0,0,0,0,0,0,0},{703,721,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 1221, 1205, {36109, 35877, 35896, 6014, 35924, 35941, 7877}, {36122, 36129, 36136, 36651, 36150, 36157, 36164}, {315, 318, 35972, 324, 327, 318, 324}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35975, 35988, 360, 369, 12370, 36003, 36010, 401, 36017, 36036, 36051, 36068, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, {35075, 36171, 35082, 496, 12370, 36003, 36010, 503, 510, 517, 36178, 36185, 0}, 0, 1, 11, 11, {2151,2181,0,0,0,0,0,0,0,0,0,0,0,0},{5034,2239,0,0,0,0,0,0,0,0},{1151,0,0,0,0,0,0,0,0,0,0,0},{1173,0,0,0,0,0,0,0,0},{4948,0,0,0,0,0,0,0}}, + {1, 273, 285, {9712, 9727, 9742, 9757, 9774, 9793, 9804}, {9815, 9822, 9829, 9836, 9843, 9850, 9857}, {0, 0, 0, 0, 0, 0, 0}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {9864, 9875, 9888, 9897, 9908, 9915, 9922, 9929, 9942, 9957, 9970, 9981, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, {9994, 10001, 10008, 10015, 9908, 9915, 9922, 10022, 10029, 10036, 10043, 10050, 0}, 0, 1, 11, 3, {681,775,2098,744,9,0,0,0,0,0,0,0,0,0},{2727,2745,0,0,0,0,0,0,0,0},{71,266,0,0,0,0,0,0,0,0,0,0},{89,271,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {673, 327, 1120, {35117, 35126, 35138, 35147, 35154, 35163, 1247}, {12088, 12092, 35169, 12101, 35174, 35178, 12114}, {6516, 6518, 12118, 6522, 6522, 6518, 6522}, {1618, 1625, 12120, 12126, 1645, 8902, 8908, 12137, 1666, 1676, 12144, 1693, 0}, {12153, 12161, 12170, 12177, 5333, 12189, 12196, 12203, 6874, 12211, 12219, 6902, 0}, {5089, 4610, 12228, 4614, 1645, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, {5089, 4610, 12228, 4614, 1645, 5093, 5097, 12237, 5105, 5109, 12241, 6911, 0}, 2, 1, 124, 3, {692,4680,681,775,417,0,0,0,0,0,0,0,0,0},{798,721,692,0,0,0,0,0,0,0},{71,266,4689,4703,0,0,0,0,0,0,0,0},{89,4716,4733,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}}, + {925, 458, 461, {17037, 17047, 17056, 17065, 17076, 17086, 17091}, {17098, 17102, 17107, 17112, 17117, 7723, 17121}, {17126, 1828, 1285, 5210, 1280, 2892, 1285}, {11533, 11540, 7354, 11547, 2760, 17128, 17133, 17138, 17145, 17153, 11589, 11596, 0}, {11603, 11610, 11617, 11622, 11628, 11632, 11637, 8914, 17160, 17168, 11666, 11673, 0}, {12906, 17175, 2791, 1927, 2760, 17179, 17183, 17187, 7707, 1947, 17191, 17195, 0}, {12906, 17175, 2791, 1927, 2760, 17179, 17183, 17187, 7707, 1947, 17191, 17195, 0}, 0, 1, 1, 3, {406,2861,0,0,0,0,0,0,0,0,0,0,0,0},{3239,2997,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{2717,0,0,0,0,0,0,0}}, + {1, 464, 479, {7465, 34718, 7489, 35389, 7505, 7518, 7527}, {17899, 17906, 17916, 17929, 17942, 17952, 17971}, {17993, 17997, 18004, 18011, 18021, 18028, 18041}, {7536, 7547, 7558, 7567, 35398, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {7536, 7547, 7558, 7567, 35398, 7585, 7592, 7605, 7614, 7625, 7638, 7649, 0}, {18228, 18235, 18083, 18245, 18115, 18122, 18261, 18274, 18281, 18291, 18304, 18314, 0}, {18228, 18235, 18083, 18245, 18115, 18122, 18261, 18274, 18281, 18291, 18304, 18314, 0}, 0, 0, 55, 11, {755,1062,2098,744,417,0,0,0,0,0,0,0,0,0},{3298,894,0,0,0,0,0,0,0,0},{4804,62,266,71,0,0,0,0,0,0,0,0},{4812,77,271,89,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {109, 889, 899, {28394, 28401, 28407, 28414, 28420, 28426, 28434}, {28444, 28448, 28452, 28456, 28460, 28464, 28468}, {9428, 9428, 9428, 9428, 9428, 9428, 9428}, {28474, 28483, 7020, 28492, 28498, 28504, 28510, 28517, 28523, 28532, 28541, 28549, 0}, {28474, 28483, 7020, 28492, 28498, 28504, 28510, 28517, 28523, 28532, 28541, 28549, 0}, {28558, 28562, 2791, 28566, 2760, 28570, 28574, 28578, 28583, 28587, 28593, 28597, 0}, {28558, 28562, 2791, 28566, 2760, 28570, 28574, 28578, 28583, 28587, 28593, 28597, 0}, 0, 0, 55, 3, {744,755,417,0,0,0,0,0,0,0,0,0,0,0},{2448,42,0,0,0,0,0,0,0,0},{266,71,0,0,0,0,0,0,0,0,0,0},{271,89,0,0,0,0,0,0,0},{98,0,0,0,0,0,0,0}}, + {925, 49, 52, {29614, 29621, 29629, 29636, 29643, 29651, 29660}, {29667, 29671, 29675, 29679, 29683, 7723, 28444}, {1616, 1616, 1610, 1616, 9428, 2892, 9428}, {29687, 29695, 29705, 29711, 29719, 29724, 29729, 29734, 29741, 16856, 29749, 29757, 0}, {29687, 29695, 29705, 29711, 29719, 29724, 29729, 29734, 29741, 16856, 29749, 29757, 0}, {1914, 29765, 2791, 29769, 2760, 28570, 28574, 29773, 2731, 1947, 29777, 13346, 0}, {1914, 29765, 2791, 29769, 2760, 28570, 28574, 29773, 2731, 1947, 29777, 13346, 0}, 0, 0, 1, 3, {295,3021,0,0,0,0,0,0,0,0,0,0,0,0},{1010,1029,0,0,0,0,0,0,0,0},{71,0,0,0,0,0,0,0,0,0,0,0},{89,0,0,0,0,0,0,0,0},{734,0,0,0,0,0,0,0}} +}; + + +static const NumberFormatEntry number_format_entries [] = { + {11, 1278, 11, 1278, 1280, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1339, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1361, 1370, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1378, 1345, 1347, 1310, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1378, 1345, 1347, 1310, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1381, 1345, 0, 1351, 1385, 1397, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1409, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1413, 1424, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1435, 1449, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 0, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1464, 1474, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1483, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1511, 1345, 1347, 1351, 1313, 1323, 55, 1515, 2, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1520, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1523, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1464, 1527, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1537, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1541, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1310, 1545, 1555, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 0, 1290, 1347, 1310, 1313, 1323, 55, 1332, 9, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1564, 1345, 1347, 1351, 1568, 1587, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1606, 1345, 1347, 1351, 1464, 1527, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1609, 11, 1609, 1613, 1345, 1347, 1351, 1617, 1626, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1635, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1639, 1345, 1643, 1351, 1660, 1688, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1715, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 2, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1385, 1397, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1718, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 1336, 1724, 1345, 1727, 1734, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1740, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1744, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 2, 2, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1748, 1345, 1347, 1351, 1313, 1323, 55, 1751, 3, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1759, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1762, 1345, 1347, 1351, 1313, 1323, 55, 1355, 5, 1, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1766, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1769, 1783, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1796, 1351, 1799, 1811, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {2, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1822, 1833, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 0, 1345, 0, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1, 1278, 1, 1278, 1843, 1492, 0, 1310, 1313, 1323, 55, 1355, 3, 0, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1852, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1856, 1345, 1859, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 0, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1866, 1876, 55, 1355, 8, 3, 7, 3, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1885, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1336, 11, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1892, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1894, 1345, 1898, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1724, 1345, 1347, 1351, 1313, 1323, 55, 1355, 2, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1727, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1943, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1946, 1345, 1950, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1967, 1345, 1974, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1991, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1995, 1345, 1999, 1351, 1313, 1323, 55, 1355, 5, 1, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 0, 1492, 2009, 1310, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2028, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 1, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 0, 1492, 1347, 1310, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 2, 2, 1, 2, 2, {3, -1}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 1, 1, 1, 2, 2, {3, 2}, {3, 2}}, + {2035, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 0, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1378, 1345, 1347, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, 0}, {3, -1}}, + {11, 1278, 11, 1278, 2037, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2040, 1345, 1347, 1351, 1313, 1323, 55, 1355, 5, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2044, 1345, 2048, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2094, 1345, 2096, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 2136, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 0, 1345, 1347, 1351, 1313, 1323, 55, 1355, 0, 0, 1, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2144, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 1, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 0, 1345, 0, 1351, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2151, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, 2}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 11, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2158, 1492, 1347, 1310, 1313, 1323, 55, 1751, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2161, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 0, 1345, 0, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 0, 1345, 0, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2165, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1336, 11, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1409, 1345, 1727, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 0}, {3, -1}}, + {11, 1278, 11, 1278, 2165, 1345, 1347, 1310, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1766, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2169, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2173, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1378, 1345, 0, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 0, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1537, 1345, 1347, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1639, 1345, 2175, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2204, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2037, 1492, 1347, 1310, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1280, 1492, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1339, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1361, 1370, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 2207, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1381, 1345, 0, 1351, 1385, 1397, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1409, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1413, 1424, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1435, 1449, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 0, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1483, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1511, 1345, 1347, 1351, 1313, 1323, 55, 1515, 2, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1520, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1523, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1464, 1527, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1537, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1541, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1310, 1545, 1555, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1724, 1290, 1347, 1310, 1313, 1323, 55, 1332, 9, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1564, 1345, 1347, 1351, 1568, 1587, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1606, 1345, 1347, 1351, 1464, 1527, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1609, 11, 1609, 1613, 1345, 1347, 1351, 1617, 1626, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1635, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1639, 1345, 1643, 1351, 1660, 1688, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2217, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 2, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1385, 1397, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1718, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 1336, 1724, 1345, 1727, 1734, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1740, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1744, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 2, 2, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1748, 1345, 1347, 1351, 1313, 1323, 55, 1751, 3, 0, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1759, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1762, 1345, 1347, 1351, 1313, 1323, 55, 1355, 5, 1, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1766, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1769, 1783, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1796, 1351, 1799, 1811, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {2, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1822, 1833, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1967, 1345, 0, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1, 1278, 1, 1278, 1843, 1492, 0, 1310, 1313, 1323, 55, 1355, 3, 0, 0, 0, 3, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1852, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1856, 1345, 1859, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2221, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1866, 1876, 55, 1355, 8, 3, 7, 3, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1885, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1336, 11, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1892, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1894, 1345, 1898, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1724, 1345, 1347, 1351, 1313, 1323, 55, 1355, 2, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1724, 1345, 1727, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1943, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1946, 1345, 1950, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1967, 1345, 1974, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1991, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1995, 1345, 1999, 1351, 1313, 1323, 55, 1355, 5, 1, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2225, 1492, 2009, 1310, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 1, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 2, 2, 1, 2, 2, {3, -1}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 1, 1, 1, 2, 2, {3, 2}, {3, 2}}, + {2035, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 2231, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1378, 1345, 1347, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, 0}, {3, -1}}, + {11, 1278, 11, 1278, 2037, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2040, 1345, 1347, 1351, 1313, 1323, 55, 1355, 5, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2044, 1345, 2048, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2094, 1345, 2096, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1939, 1345, 0, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 2136, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2144, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 1, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2235, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, 2}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 11, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2158, 1492, 1347, 1310, 1313, 1323, 55, 1751, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2161, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2165, 1345, 0, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2165, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1336, 11, 1336, 1892, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1409, 1345, 1727, 1351, 1313, 1323, 55, 1355, 12, 2, 0, 0, 1, 2, 2, {3, 0}, {3, -1}}, + {11, 1278, 11, 1278, 2165, 1345, 1347, 1310, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1766, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1766, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2173, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1378, 1345, 0, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 0, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1537, 1345, 1347, 1351, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1639, 1345, 2175, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2204, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2037, 1492, 1347, 1310, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2248, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1361, 1370, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1537, 1345, 1347, 1310, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 2258, 11, 2258, 1613, 1345, 1347, 1351, 1413, 1424, 55, 1355, 2, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2037, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 2258, 11, 2258, 1613, 1345, 1347, 1351, 1464, 1527, 55, 1355, 2, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 1336, 1357, 1345, 1347, 1310, 1545, 1555, 55, 1355, 12, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1724, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1347, 1351, 1464, 1527, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2260, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2260, 1345, 1643, 1351, 1660, 1688, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1727, 1734, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1751, 1, 0, 1, 2, 1, 2, 2, {3, 2}, {3, -1}}, + {1278, 1336, 1278, 1336, 2221, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1336, 11, 1336, 2262, 1345, 0, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 1336, 1724, 1345, 1727, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2264, 1492, 2271, 1310, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2304, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 1, 0, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 2308, 1492, 1347, 1310, 1313, 1323, 55, 1515, 9, 2, 9, 3, 2, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2311, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, 2}, {3, 2}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2169, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2315, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2325, 1345, 2207, 1351, 1313, 1323, 55, 1355, 0, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1413, 1424, 55, 1355, 9, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1464, 1474, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1462, 1492, 1347, 1310, 1495, 1503, 55, 1355, 15, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 1727, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2329, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 0, 0, 0, 3, 3, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1310, 1313, 1323, 55, 1355, 0, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1413, 1424, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2339, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1336, 11, 1336, 1613, 1492, 1347, 1310, 1495, 1503, 55, 1355, 2, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2341, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2344, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2354, 1345, 2207, 1351, 1313, 1323, 55, 1355, 0, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 2258, 11, 2258, 1613, 1345, 1347, 1351, 1413, 1424, 55, 1355, 9, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2359, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2341, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2363, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2373, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2341, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2377, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 3, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1892, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2387, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2391, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2396, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 3, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2406, 1345, 1347, 1351, 1464, 1474, 55, 1355, 2, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2391, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2410, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2420, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2423, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 2427, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2435, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2445, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2448, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2423, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2452, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 3, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2462, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2467, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 2, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2448, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2477, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 3, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2161, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 2, 0, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2448, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2487, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 9, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2497, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2501, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 3, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2325, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2511, 1345, 1347, 1351, 1464, 1474, 55, 1355, 12, 2, 0, 0, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2515, 1492, 1347, 1310, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2517, 1290, 1295, 1310, 1313, 1323, 55, 1332, 3, 2, 0, 0, 3, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1939, 1345, 1347, 1351, 1313, 1323, 55, 1355, 12, 2, 1, 1, 1, 2, 2, {3, 2}, {3, 2}}, + {1278, 11, 1278, 11, 2527, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1943, 1345, 1347, 1351, 1313, 1323, 55, 1355, 0, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1313, 1323, 55, 1355, 1, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2260, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2530, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 0, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1462, 1345, 1347, 1351, 1464, 1474, 55, 1355, 1, 0, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2391, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2341, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2533, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2541, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1357, 1345, 2427, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2221, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 1378, 1345, 1347, 1310, 1313, 1323, 55, 1355, 2, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1724, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2341, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2221, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2264, 1492, 2271, 1310, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2231, 1345, 1347, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2325, 1345, 2207, 1351, 1313, 1323, 55, 1355, 0, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2325, 1345, 2207, 1351, 1313, 1323, 55, 1355, 0, 0, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1724, 1290, 1347, 1310, 1313, 1323, 55, 1332, 9, 2, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 2541, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 1967, 1345, 0, 1351, 1313, 1323, 55, 1355, 8, 3, 1, 1, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 11, 1278, 11, 1357, 1345, 1347, 1351, 1313, 1323, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 2225, 1492, 2009, 1310, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 0, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2308, 1492, 1347, 1310, 1313, 1323, 55, 1515, 9, 2, 9, 3, 2, 2, 2, {3, -1}, {3, -1}}, + {1278, 1336, 1278, 1336, 0, 1345, 0, 1351, 1495, 1503, 55, 1355, 8, 3, 0, 0, 1, 2, 2, {3, -1}, {3, -1}}, + {11, 1278, 11, 1278, 2165, 1345, 0, 1351, 1313, 1323, 55, 1355, 9, 2, 1, 1, 1, 2, 2, {3, -1}, {3, -1}} +}; + + +static const CultureInfoEntry culture_entries [] = { + {0x0001, 0x007F, 768, -1, 2546, 2549, 2556, 2571, 2575, 2546, 0, {0, 0, 36669, 0}, 0, 0, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x0002, 0x007F, 257, -1, 2579, 2582, 2592, 2611, 2615, 2579, 0, {36697, 0, 0, 0}, 1, 1, { 1251, 21025, 10007, 866, 0, ';' }}, + {0x0003, 0x007F, 257, -1, 2619, 2622, 2630, 2638, 2642, 2619, 0, {36739, 0, 0, 0}, 2, 2, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0004, 0x7804, 257, -1, 2646, 2654, 2675, 2682, 2686, 2690, 0, {36759, 0, 0, 0}, 3, 3, { 936, 500, 10008, 936, 0, ',' }}, + {0x0004, 0x0004, 257, -1, 2693, 2700, 2675, 2682, 2686, 2690, 0, {36759, 0, 0, 0}, 4, 4, { 936, 500, 10008, 936, 0, ',' }}, + {0x0005, 0x007F, 257, -1, 2728, 2731, 2737, 2747, 2751, 2728, 0, {36766, 0, 0, 0}, 5, 5, { 1250, 500, 10029, 852, 0, ';' }}, + {0x0006, 0x007F, 257, -1, 2755, 2758, 2765, 2771, 2775, 2755, 0, {36792, 0, 0, 0}, 6, 6, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x0007, 0x007F, 257, -1, 2779, 2782, 2789, 2797, 2801, 2779, 0, {36813, 0, 0, 0}, 7, 7, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x0008, 0x007F, 257, -1, 2805, 2808, 2814, 2831, 2835, 2805, 0, {36838, 0, 0, 0}, 8, 8, { 1253, 20273, 10006, 737, 0, ';' }}, + {0x0009, 0x007F, 257, -1, 2839, 2842, 2842, 2850, 2854, 2839, 0, {36880, 0, 0, 0}, 9, 9, { 1252, 37, 10000, 437, 0, ',' }}, + {0x000A, 0x007F, 257, -1, 2858, 2861, 2869, 2878, 2882, 2858, 0, {36899, 0, 0, 0}, 10, 10, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x000B, 0x007F, 257, -1, 2886, 2889, 2897, 2903, 2907, 2886, 0, {36921, 0, 0, 0}, 11, 11, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x000C, 0x007F, 257, -1, 2911, 2914, 2921, 2931, 2935, 2911, 0, {36946, 0, 0, 0}, 12, 12, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x000D, 0x007F, 257, -1, 2939, 2942, 2949, 2960, 2964, 2939, 0, {36968, 0, 0, 0}, 13, 13, { 1255, 500, 10005, 862, 1, ',' }}, + {0x000E, 0x007F, 257, -1, 2968, 2971, 2981, 2988, 2992, 2968, 0, {37005, 0, 0, 0}, 14, 14, { 1250, 500, 10029, 852, 0, ';' }}, + {0x000F, 0x007F, 257, -1, 2996, 2999, 3009, 3019, 3023, 2996, 0, {37021, 0, 0, 0}, 15, 15, { 1252, 20871, 10079, 850, 0, ';' }}, + {0x0010, 0x007F, 257, -1, 3027, 3030, 3038, 3047, 3051, 3027, 0, {37041, 0, 0, 0}, 16, 16, { 1252, 20280, 10000, 850, 0, ';' }}, + {0x0011, 0x007F, 257, -1, 3055, 3058, 3067, 3077, 3081, 3055, 0, {37063, 0, 0, 0}, 17, 17, { 932, 20290, 10001, 932, 0, ',' }}, + {0x0012, 0x007F, 257, -1, 3085, 3088, 3095, 3105, 3109, 3085, 0, {37090, 0, 0, 0}, 18, 18, { 949, 20833, 10003, 949, 0, ',' }}, + {0x0013, 0x007F, 257, -1, 3113, 3116, 3122, 3133, 3137, 3113, 0, {37097, 0, 0, 0}, 19, 19, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0014, 0x007F, 257, -1, 3141, 3144, 3154, 3160, 3164, 3168, 0, {36792, 0, 0, 0}, 20, 20, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x0015, 0x007F, 257, -1, 3171, 3174, 3181, 3188, 3192, 3171, 0, {37119, 0, 0, 0}, 21, 21, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0016, 0x007F, 257, -1, 3196, 3199, 3210, 3221, 3225, 3196, 0, {37143, 0, 0, 0}, 22, 22, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0017, 0x007F, 257, -1, 3229, 3232, 3240, 3250, 3254, 3229, 0, {37166, 0, 0, 0}, 23, 23, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x0018, 0x007F, 257, -1, 3258, 3261, 3270, 3279, 3283, 3258, 0, {37186, 0, 0, 0}, 24, 24, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0019, 0x007F, 257, -1, 3287, 3290, 3298, 3313, 3317, 3287, 0, {37205, 0, 0, 0}, 25, 25, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x001A, 0x007F, 257, -1, 3321, 3324, 3333, 3342, 3346, 3321, 0, {37251, 0, 0, 0}, 26, 26, { 1250, 500, 10082, 852, 0, ';' }}, + {0x001B, 0x007F, 257, -1, 3350, 3353, 3360, 3372, 3376, 3350, 0, {37274, 0, 0, 0}, 27, 27, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x001C, 0x007F, 257, -1, 3380, 3383, 3392, 3398, 3402, 3380, 0, {37298, 0, 0, 0}, 28, 28, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x001D, 0x007F, 257, -1, 3406, 3409, 3417, 3425, 3429, 3406, 0, {36792, 0, 0, 0}, 29, 29, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x001E, 0x007F, 512, -1, 3433, 3436, 3441, 3451, 3455, 3433, 0, {0, 37317, 0, 0}, 30, 30, { 874, 20838, 10021, 874, 0, ',' }}, + {0x001F, 0x007F, 257, -1, 3459, 3462, 3470, 3479, 3483, 3459, 0, {37348, 0, 0, 0}, 31, 31, { 1254, 20905, 10081, 857, 0, ';' }}, + {0x0020, 0x007F, 257, -1, 3487, 3490, 3495, 3504, 3508, 3487, 0, {37362, 0, 0, 0}, 32, 32, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x0021, 0x007F, 257, -1, 3512, 3515, 3526, 3536, 3540, 3512, 0, {37392, 0, 0, 0}, 33, 33, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0022, 0x007F, 257, -1, 3544, 3547, 3557, 3578, 3582, 3544, 0, {37411, 0, 0, 0}, 34, 34, { 1251, 500, 10017, 866, 0, ';' }}, + {0x0023, 0x007F, 257, -1, 3586, 3589, 3600, 3621, 3625, 3586, 0, {37457, 0, 0, 0}, 35, 35, { 1251, 500, 10007, 866, 0, ';' }}, + {0x0024, 0x007F, 257, -1, 3629, 3632, 3642, 3656, 3660, 3629, 0, {37499, 0, 0, 0}, 36, 36, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0025, 0x007F, 257, -1, 3664, 3667, 3676, 3682, 3686, 3664, 0, {37521, 0, 0, 0}, 37, 37, { 1257, 500, 10029, 775, 0, ';' }}, + {0x0026, 0x007F, 257, -1, 3690, 3693, 3701, 3711, 3715, 3690, 0, {37541, 0, 0, 0}, 38, 38, { 1257, 500, 10029, 775, 0, ';' }}, + {0x0027, 0x007F, 257, -1, 3719, 3722, 3733, 3743, 3747, 3719, 0, {37560, 0, 0, 0}, 39, 39, { 1257, 500, 10029, 775, 0, ';' }}, + {0x0028, 0x007F, 257, -1, 3751, 3754, 3760, 3773, 3777, 3751, 0, {0, 0, 0, 0}, 40, 40, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0029, 0x007F, 257, -1, 3781, 3784, 3792, 3803, 3807, 3781, 0, {37583, 0, 0, 0}, 41, 41, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x002A, 0x007F, 257, -1, 3811, 3814, 3825, 3840, 3844, 3811, 0, {37607, 0, 0, 0}, 42, 42, { 1258, 500, 10000, 1258, 0, ',' }}, + {0x002B, 0x007F, 257, -1, 3848, 3851, 3860, 3875, 3879, 3848, 0, {37622, 0, 0, 0}, 43, 43, { 0, 500, 2, 1, 0, ',' }}, + {0x002C, 0x007F, 257, -1, 3883, 3886, 3898, 3910, 3914, 3883, 0, {37652, 0, 0, 0}, 44, 44, { 1254, 20905, 10081, 857, 0, ';' }}, + {0x002D, 0x007F, 257, -1, 3918, 3921, 3928, 3936, 3940, 3918, 0, {37671, 0, 0, 0}, 45, 45, { 1252, 500, 2, 850, 0, ';' }}, + {0x002E, 0x007F, 257, -1, 3944, 3948, 3962, 3980, 3944, 3944, 0, {37691, 0, 0, 0}, 46, 46, { 1252, 870, 10000, 850, 0, ';' }}, + {0x002F, 0x007F, 257, -1, 3984, 3987, 3998, 4019, 4023, 3984, 0, {37712, 0, 0, 0}, 47, 47, { 1251, 500, 10007, 866, 0, ';' }}, + {0x0030, 0x007F, 257, -1, 4027, 4030, 4045, 4053, 4057, 4027, 0, {0, 0, 0, 0}, 48, 48, { 0, 500, 2, 1, 0, ';' }}, + {0x0031, 0x007F, 257, -1, 4061, 4064, 4071, 4080, 4084, 4061, 0, {0, 0, 0, 0}, 49, 49, { 0, 500, 2, 1, 0, ';' }}, + {0x0032, 0x007F, 257, -1, 4088, 4091, 4098, 4107, 4111, 4088, 0, {0, 0, 0, 0}, 50, 50, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0034, 0x007F, 257, -1, 4115, 4118, 4124, 4133, 4137, 4115, 0, {0, 0, 0, 0}, 51, 51, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0035, 0x007F, 257, -1, 4141, 4144, 4149, 4157, 4161, 4141, 0, {37756, 0, 0, 0}, 52, 52, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0036, 0x007F, 257, -1, 4165, 4168, 4168, 4178, 4182, 4165, 0, {37781, 0, 0, 0}, 53, 53, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0037, 0x007F, 257, -1, 4186, 4189, 4198, 4220, 4224, 4186, 0, {37801, 0, 0, 0}, 54, 54, { 0, 500, 2, 1, 0, ';' }}, + {0x0038, 0x007F, 257, -1, 4228, 4231, 4239, 4249, 4253, 4228, 0, {37866, 0, 0, 0}, 55, 55, { 1252, 20277, 10079, 850, 0, ';' }}, + {0x0039, 0x007F, 257, -1, 4257, 4260, 4266, 4285, 4289, 4257, 0, {37890, 0, 0, 0}, 56, 56, { 0, 500, 2, 1, 0, ',' }}, + {0x003A, 0x007F, 257, -1, 4293, 4296, 4304, 4310, 4314, 4293, 0, {37943, 0, 0, 0}, 57, 57, { 0, 500, 2, 1, 0, ';' }}, + {0x003B, 0x007F, 257, -1, 4318, 4321, 4335, 4352, 4356, 4318, 0, {37964, 0, 0, 0}, 58, 58, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x003C, 0x007F, 257, -1, 4360, 4363, 4369, 4377, 4381, 4360, 0, {37983, 0, 0, 0}, 59, 59, { 1252, 500, 10000, 850, 0, ';' }}, + {0x003E, 0x007F, 257, -1, 4385, 4388, 4394, 4408, 4412, 4385, 0, {38004, 0, 0, 0}, 60, 60, { 1252, 500, 10000, 850, 0, ';' }}, + {0x003F, 0x007F, 257, -1, 4416, 4419, 4426, 4446, 4450, 4416, 0, {38021, 0, 0, 0}, 61, 61, { 0, 500, 2, 1, 0, ';' }}, + {0x0040, 0x007F, 257, -1, 4454, 4457, 4464, 4481, 4485, 4454, 0, {38063, 0, 0, 0}, 62, 62, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0041, 0x007F, 257, -1, 4489, 4492, 4500, 4510, 4514, 4489, 0, {38103, 0, 0, 0}, 63, 63, { 1252, 500, 10000, 437, 0, ';' }}, + {0x0042, 0x007F, 257, -1, 4518, 4521, 4529, 4541, 4545, 4518, 0, {38124, 0, 0, 0}, 64, 64, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0043, 0x007F, 257, -1, 4549, 4552, 4558, 4567, 4571, 4549, 0, {38146, 0, 0, 0}, 65, 65, { 1254, 500, 10029, 857, 0, ';' }}, + {0x0045, 0x007F, 257, -1, 4575, 4578, 4585, 4601, 4605, 4575, 0, {38164, 0, 0, 0}, 66, 66, { 0, 500, 2, 1, 0, ',' }}, + {0x0046, 0x007F, 257, -1, 4609, 4612, 4620, 4639, 4643, 4609, 0, {38235, 0, 0, 0}, 67, 67, { 0, 500, 2, 1, 0, ',' }}, + {0x0047, 0x007F, 257, -1, 4647, 4650, 4659, 4681, 4685, 4647, 0, {38282, 0, 0, 0}, 68, 68, { 0, 500, 2, 1, 0, ',' }}, + {0x0048, 0x007F, 257, -1, 4689, 4692, 4697, 4713, 4717, 4689, 0, {0, 0, 0, 0}, 69, 69, { 0, 500, 2, 1, 0, ',' }}, + {0x0049, 0x007F, 257, -1, 4721, 4724, 4730, 4746, 4750, 4721, 0, {38338, 0, 0, 0}, 70, 70, { 0, 500, 2, 1, 0, ',' }}, + {0x004A, 0x007F, 257, -1, 4754, 4757, 4764, 4783, 4787, 4754, 0, {38403, 0, 0, 0}, 71, 71, { 0, 500, 2, 1, 0, ',' }}, + {0x004B, 0x007F, 257, -1, 1715, 4791, 4799, 4815, 4819, 1715, 0, {38468, 0, 0, 0}, 72, 72, { 0, 500, 2, 1, 0, ',' }}, + {0x004C, 0x007F, 257, -1, 4823, 4826, 4836, 4855, 4859, 4823, 0, {38533, 0, 0, 0}, 73, 73, { 0, 500, 2, 1, 0, ',' }}, + {0x004D, 0x007F, 257, -1, 4863, 4866, 4875, 4897, 4901, 4863, 0, {38577, 0, 0, 0}, 74, 74, { 0, 500, 2, 1, 0, ',' }}, + {0x004E, 0x007F, 257, -1, 4905, 4908, 4916, 4932, 4936, 4905, 0, {38630, 0, 0, 0}, 75, 75, { 0, 500, 2, 1, 0, ',' }}, + {0x0050, 0x007F, 257, -1, 4940, 4943, 4953, 4966, 4970, 4940, 0, {38692, 0, 0, 0}, 76, 76, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0051, 0x007F, 257, -1, 4974, 4977, 4985, 5010, 5014, 4974, 0, {0, 0, 0, 0}, 77, 77, { 0, 500, 2, 1, 0, ',' }}, + {0x0052, 0x007F, 257, -1, 5018, 5021, 5027, 5035, 5039, 5018, 0, {38724, 0, 0, 0}, 78, 78, { 1252, 20285, 10000, 850, 0, ';' }}, + {0x0053, 0x007F, 257, -1, 5043, 5046, 5052, 5068, 5072, 5043, 0, {38740, 0, 0, 0}, 79, 79, { 0, 500, 2, 1, 0, ',' }}, + {0x0054, 0x007F, 257, -1, 5076, 5079, 5083, 5093, 5097, 5076, 0, {38795, 0, 0, 0}, 80, 80, { 0, 500, 2, 1, 0, ';' }}, + {0x0055, 0x007F, 257, -1, 5101, 5104, 5112, 5131, 5135, 5101, 0, {38841, 0, 0, 0}, 81, 81, { 0, 500, 2, 1, 0, ';' }}, + {0x0056, 0x007F, 257, -1, 5139, 5142, 5151, 5158, 5162, 5139, 0, {36899, 0, 0, 0}, 82, 82, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0057, 0x007F, 257, -1, 5166, 5170, 5178, 5197, 5166, 5166, 0, {0, 0, 0, 0}, 83, 83, { 0, 500, 2, 1, 0, ',' }}, + {0x005B, 0x007F, 257, -1, 5201, 5204, 5212, 5228, 5232, 5201, 0, {38912, 0, 0, 0}, 84, 84, { 0, 500, 2, 1, 0, ';' }}, + {0x005C, 0x007F, 257, -1, 5236, 5240, 5249, 5259, 5236, 5236, 0, {38978, 0, 0, 0}, 85, 85, { 0, 500, 2, 1, 0, ',' }}, + {0x005E, 0x007F, 257, -1, 5, 5263, 5271, 5284, 5288, 5, 0, {39017, 0, 0, 0}, 86, 86, { 0, 500, 2, 1, 0, ';' }}, + {0x005F, 0x007F, 257, -1, 5292, 5296, 5320, 5343, 5292, 5292, 0, {0, 0, 0, 0}, 87, 87, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0061, 0x007F, 257, -1, 5347, 5350, 5357, 5376, 5380, 5347, 0, {39065, 0, 0, 0}, 88, 88, { 0, 500, 2, 1, 0, ',' }}, + {0x0062, 0x007F, 257, -1, 5384, 5387, 5403, 5414, 5418, 5384, 0, {39115, 0, 0, 0}, 89, 89, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0063, 0x007F, 1024, -1, 5422, 5425, 5432, 5441, 5445, 5422, 0, {0, 0, 0, 0}, 90, 90, { 0, 500, 2, 1, 1, ';' }}, + {0x0064, 0x007F, 257, -1, 5449, 5453, 5453, 5462, 5449, 5449, 0, {39138, 0, 0, 0}, 91, 91, { 1252, 500, 10000, 437, 0, ';' }}, + {0x0067, 0x007F, 257, -1, 5466, 5469, 5475, 5482, 5486, 5466, 0, {0, 0, 0, 0}, 92, 92, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0068, 0x007F, 257, -1, 5490, 5493, 5493, 5499, 5503, 5490, 0, {0, 0, 0, 0}, 93, 93, { 1252, 37, 10000, 437, 0, ';' }}, + {0x006A, 0x007F, 257, -1, 5507, 5510, 5517, 5532, 5536, 5507, 0, {0, 0, 0, 0}, 94, 94, { 1252, 37, 10000, 437, 0, ';' }}, + {0x006C, 0x007F, 257, -1, 5540, 5544, 5559, 5576, 5540, 5540, 0, {0, 0, 0, 0}, 95, 95, { 1252, 500, 10000, 850, 0, ';' }}, + {0x006E, 0x007F, 257, -1, 5580, 5583, 5597, 5613, 5617, 5580, 0, {39162, 0, 0, 0}, 96, 96, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x006F, 0x007F, 257, -1, 5621, 5624, 5636, 5648, 5652, 5621, 0, {39186, 0, 0, 0}, 97, 97, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x0070, 0x007F, 257, -1, 5656, 5659, 5659, 5664, 5668, 5656, 0, {0, 0, 0, 0}, 98, 98, { 1252, 37, 10000, 437, 0, ';' }}, + {0x0072, 0x007F, 257, -1, 5672, 5675, 5681, 5688, 5692, 5672, 0, {0, 0, 0, 0}, 99, 99, { 0, 500, 2, 1, 0, ';' }}, + {0x0073, 0x007F, 257, -1, 5696, 5699, 5708, 5721, 5725, 5696, 0, {0, 0, 0, 0}, 100, 100, { 0, 500, 2, 1, 0, ';' }}, + {0x0075, 0x007F, 257, -1, 5729, 5733, 5742, 5760, 5729, 5729, 0, {0, 0, 0, 0}, 101, 101, { 1252, 37, 10000, 437, 0, ';' }}, + {0x0077, 0x007F, 257, -1, 5764, 5767, 5774, 5783, 5787, 5764, 0, {0, 0, 0, 0}, 102, 102, { 0, 500, 2, 1, 0, ';' }}, + {0x0078, 0x007F, 257, -1, 5791, 5794, 5805, 5815, 5819, 5791, 0, {39213, 0, 0, 0}, 103, 103, { 0, 500, 2, 1, 0, ';' }}, + {0x007E, 0x007F, 257, -1, 5823, 5826, 5833, 5843, 5847, 5823, 0, {39226, 0, 0, 0}, 104, 104, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0080, 0x007F, 257, -1, 5851, 5854, 5861, 5878, 5882, 5851, 0, {39246, 0, 0, 0}, 105, 105, { 1256, 20420, 10004, 720, 1, ',' }}, + {0x0084, 0x007F, 257, -1, 5886, 5890, 5903, 5922, 5886, 5886, 0, {39282, 0, 0, 0}, 106, 106, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0085, 0x007F, 257, -1, 5926, 5930, 5936, 5954, 5926, 5926, 0, {0, 0, 0, 0}, 107, 107, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0087, 0x007F, 257, -1, 5958, 5961, 5961, 5973, 5977, 5958, 0, {0, 0, 0, 0}, 108, 108, { 1252, 37, 10000, 437, 0, ';' }}, + {0x0091, 0x007F, 257, -1, 5981, 5984, 6000, 6010, 6014, 5981, 0, {39307, 0, 0, 0}, 109, 109, { 1252, 20285, 10000, 850, 0, ';' }}, + {0x0401, 0x0001, 768, 111, 6018, 6024, 6046, 2571, 2575, 2546, 311, {0, 0, 36669, 0}, 110, 110, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x0402, 0x0002, 257, 11, 6110, 6116, 6137, 2611, 2615, 2579, 6175, {36697, 0, 0, 0}, 111, 111, { 1251, 21025, 10007, 866, 0, ';' }}, + {0x0403, 0x0003, 257, 38, 6178, 6184, 6200, 2638, 2642, 2619, 6218, {36739, 0, 0, 0}, 112, 112, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0404, 0x7C04, 257, 126, 6221, 6227, 6249, 6265, 2686, 2690, 6269, {39332, 0, 0, 0}, 113, 113, { 950, 500, 10002, 950, 0, ',' }}, + {0x0405, 0x0005, 257, 29, 6272, 6278, 6301, 2747, 2751, 2728, 6331, {36766, 0, 0, 0}, 114, 114, { 1250, 500, 10029, 852, 0, ';' }}, + {0x0406, 0x0006, 257, 31, 6334, 6340, 6357, 2771, 2775, 2755, 6373, {36792, 0, 0, 0}, 115, 115, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x0407, 0x0007, 257, 30, 6376, 6382, 6399, 2797, 2801, 2779, 6421, {36813, 0, 0, 0}, 116, 116, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x0408, 0x0008, 257, 46, 6424, 6430, 6445, 2831, 2835, 2805, 6477, {36838, 0, 0, 0}, 117, 117, { 1253, 20273, 10006, 737, 0, ';' }}, + {0x0409, 0x0009, 257, 128, 6480, 6486, 6486, 2850, 2854, 2839, 6510, {36880, 0, 0, 0}, 118, 118, { 1252, 37, 10000, 437, 0, ',' }}, + {0x040B, 0x000B, 257, 40, 6513, 6519, 6537, 2903, 2907, 2886, 6551, {36921, 0, 0, 0}, 119, 119, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x040C, 0x000C, 257, 42, 6554, 6560, 6576, 2931, 2935, 2911, 6595, {36946, 0, 0, 0}, 120, 120, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x040D, 0x000D, 257, 55, 6598, 6604, 6620, 2960, 2964, 2939, 6644, {36968, 0, 0, 0}, 121, 121, { 1255, 500, 10005, 862, 1, ',' }}, + {0x040E, 0x000E, 257, 52, 6647, 6653, 6673, 2988, 2992, 2968, 6696, {37005, 0, 0, 0}, 122, 122, { 1250, 500, 10029, 852, 0, ';' }}, + {0x040F, 0x000F, 257, 59, 6699, 6705, 6725, 3019, 3023, 2996, 6745, {37021, 0, 0, 0}, 123, 123, { 1252, 20871, 10079, 850, 0, ';' }}, + {0x0410, 0x0010, 257, 60, 6748, 6754, 6770, 3047, 3051, 3027, 6788, {37041, 0, 0, 0}, 124, 124, { 1252, 20280, 10000, 850, 0, ';' }}, + {0x0411, 0x0011, 257, 63, 6791, 6797, 6814, 3077, 3081, 3055, 6833, {37063, 0, 0, 0}, 125, 125, { 932, 20290, 10001, 932, 0, ',' }}, + {0x0412, 0x0012, 257, 67, 6836, 6842, 6863, 3105, 3109, 3085, 6888, {37090, 0, 0, 0}, 126, 126, { 949, 20833, 10003, 949, 0, ',' }}, + {0x0413, 0x0013, 257, 92, 6891, 6897, 6917, 3133, 3137, 3113, 6940, {37097, 0, 0, 0}, 127, 127, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0414, 0x7C14, 257, 93, 6943, 6949, 6976, 3160, 3164, 3168, 6998, {36792, 0, 0, 0}, 128, 128, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x0415, 0x0015, 257, 101, 7001, 7007, 7023, 3188, 3192, 3171, 7039, {37119, 0, 0, 0}, 129, 129, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0416, 0x0016, 257, 15, 7042, 7048, 7068, 3221, 3225, 3196, 7088, {37143, 0, 0, 0}, 130, 130, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0417, 0x0017, 257, 21, 7091, 7097, 7119, 3250, 3254, 3229, 314, {37166, 0, 0, 0}, 131, 131, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x0418, 0x0018, 257, 107, 7138, 7144, 7163, 3279, 3283, 3258, 7183, {37186, 0, 0, 0}, 132, 132, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0419, 0x0019, 257, 109, 7186, 7192, 7209, 3313, 3317, 3287, 7239, {37205, 0, 0, 0}, 133, 133, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x041A, 0x001A, 257, 50, 7242, 7248, 7267, 3342, 3346, 3321, 7287, {37251, 0, 0, 0}, 134, 134, { 1250, 500, 10082, 852, 0, ';' }}, + {0x041B, 0x001B, 257, 115, 7290, 7296, 7314, 3372, 3376, 3350, 7338, {37274, 0, 0, 0}, 135, 135, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x041C, 0x001C, 257, 2, 7341, 7347, 7366, 3398, 3402, 3380, 7384, {37298, 0, 0, 0}, 136, 136, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x041D, 0x001D, 257, 112, 7387, 7393, 7410, 3425, 3429, 3406, 7428, {36792, 0, 0, 0}, 137, 137, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x041E, 0x001E, 512, 120, 7431, 7437, 7453, 3451, 3455, 3433, 7475, {0, 37317, 0, 0}, 138, 138, { 874, 20838, 10021, 874, 0, ',' }}, + {0x041F, 0x001F, 257, 124, 7478, 7484, 7501, 3479, 3483, 3459, 7521, {37348, 0, 0, 0}, 139, 139, { 1254, 20905, 10081, 857, 0, ';' }}, + {0x0420, 0x0020, 257, 100, 7524, 7530, 7546, 3504, 3508, 3487, 7572, {37362, 0, 0, 0}, 140, 140, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x0421, 0x0021, 257, 53, 7575, 7581, 7604, 3536, 3540, 3512, 7626, {37392, 0, 0, 0}, 141, 141, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0422, 0x0022, 257, 127, 7629, 7635, 7655, 3578, 3582, 3544, 7693, {37411, 0, 0, 0}, 142, 142, { 1251, 500, 10017, 866, 0, ';' }}, + {0x0423, 0x0023, 257, 17, 7696, 7702, 7723, 3621, 3625, 3586, 7763, {37457, 0, 0, 0}, 143, 143, { 1251, 500, 10007, 866, 0, ';' }}, + {0x0424, 0x0024, 257, 114, 7766, 7772, 7793, 3656, 3660, 3629, 7819, {37499, 0, 0, 0}, 144, 144, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0425, 0x0025, 257, 35, 7822, 7828, 7847, 3682, 3686, 3664, 7861, {37521, 0, 0, 0}, 145, 145, { 1257, 500, 10029, 775, 0, ';' }}, + {0x0426, 0x0026, 257, 76, 7864, 7870, 7887, 3711, 3715, 3690, 7907, {37541, 0, 0, 0}, 146, 146, { 1257, 500, 10029, 775, 0, ';' }}, + {0x0427, 0x0027, 257, 74, 7910, 7916, 7939, 3743, 3747, 3719, 7959, {37560, 0, 0, 0}, 147, 147, { 1257, 500, 10029, 775, 0, ';' }}, + {0x0428, 0x7C28, 257, 121, 7962, 7973, 8002, 3773, 3777, 3751, 8038, {0, 0, 0, 0}, 148, 148, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0429, 0x0029, 257, 58, 8041, 8047, 8062, 3803, 3807, 3781, 8086, {37583, 0, 0, 0}, 149, 149, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x042A, 0x002A, 257, 132, 8089, 8095, 8116, 3840, 3844, 3811, 8144, {37607, 0, 0, 0}, 150, 150, { 1258, 500, 10000, 1258, 0, ',' }}, + {0x042B, 0x002B, 257, 3, 8147, 8153, 8172, 3875, 3879, 3848, 49, {37622, 0, 0, 0}, 151, 151, { 0, 500, 2, 1, 0, ',' }}, + {0x042C, 0x782C, 257, 7, 8206, 8217, 8249, 3910, 3914, 3883, 8275, {37652, 0, 0, 0}, 152, 152, { 1254, 20905, 10081, 857, 0, ';' }}, + {0x042D, 0x002D, 257, 38, 8278, 8284, 8299, 3936, 3940, 3918, 6218, {37671, 0, 0, 0}, 153, 153, { 1252, 500, 2, 850, 0, ';' }}, + {0x042E, 0x002E, 257, 30, 8318, 8325, 8349, 3980, 3944, 3944, 6421, {37691, 0, 0, 0}, 154, 154, { 1252, 870, 10000, 850, 0, ';' }}, + {0x042F, 0x002F, 257, 82, 8377, 8383, 8406, 4019, 4023, 3984, 8450, {37712, 0, 0, 0}, 155, 155, { 1251, 500, 10007, 866, 0, ';' }}, + {0x0430, 0x0030, 257, 134, 8453, 8459, 4045, 4053, 4057, 4027, 8489, {0, 0, 0, 0}, 156, 156, { 0, 500, 2, 1, 0, ';' }}, + {0x0431, 0x0031, 257, 134, 8492, 8498, 4071, 4080, 4084, 4061, 8489, {0, 0, 0, 0}, 157, 157, { 0, 500, 2, 1, 0, ';' }}, + {0x0432, 0x0032, 257, 134, 8520, 8526, 4098, 4107, 4111, 4088, 8489, {0, 0, 0, 0}, 158, 158, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0434, 0x0034, 257, 134, 8548, 8554, 4124, 4133, 4137, 4115, 8489, {0, 0, 0, 0}, 159, 159, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0435, 0x0035, 257, 134, 8575, 8581, 8601, 4157, 4161, 4141, 8489, {37756, 0, 0, 0}, 160, 160, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0436, 0x0036, 257, 134, 8626, 8632, 8657, 4178, 4182, 4165, 8489, {37781, 0, 0, 0}, 161, 161, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0437, 0x0037, 257, 44, 8681, 8687, 8706, 4220, 4224, 4186, 8761, {37801, 0, 0, 0}, 162, 162, { 0, 500, 2, 1, 0, ';' }}, + {0x0438, 0x0038, 257, 41, 8764, 8770, 8794, 4249, 4253, 4228, 8815, {37866, 0, 0, 0}, 163, 163, { 1252, 20277, 10079, 850, 0, ';' }}, + {0x0439, 0x0039, 257, 56, 8818, 8824, 8838, 4285, 4289, 4257, 8872, {37890, 0, 0, 0}, 164, 164, { 0, 500, 2, 1, 0, ',' }}, + {0x043A, 0x003A, 257, 87, 8875, 8881, 8897, 4310, 4314, 4293, 8911, {37943, 0, 0, 0}, 165, 165, { 0, 500, 2, 1, 0, ';' }}, + {0x043B, 0x003B, 257, 93, 8914, 8920, 8943, 4352, 4356, 4318, 6998, {37964, 0, 0, 0}, 166, 166, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x043E, 0x003E, 257, 89, 8968, 8974, 8991, 4408, 4412, 4385, 9016, {38004, 0, 0, 0}, 167, 167, { 1252, 500, 10000, 850, 0, ';' }}, + {0x043F, 0x003F, 257, 69, 9019, 9025, 9045, 4446, 4450, 4416, 9086, {38021, 0, 0, 0}, 168, 168, { 0, 500, 2, 1, 0, ';' }}, + {0x0440, 0x0040, 257, 65, 9089, 9095, 9115, 4481, 4485, 4454, 9155, {38063, 0, 0, 0}, 169, 169, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0441, 0x0041, 257, 64, 9158, 9164, 9180, 4510, 4514, 4489, 9198, {38103, 0, 0, 0}, 170, 170, { 1252, 500, 10000, 437, 0, ';' }}, + {0x0442, 0x0042, 257, 122, 9201, 9207, 9230, 4541, 4545, 4518, 9258, {38124, 0, 0, 0}, 171, 171, { 1250, 20880, 10029, 852, 0, ';' }}, + {0x0443, 0x7C43, 257, 130, 9261, 9272, 9298, 4567, 4571, 4549, 9322, {38146, 0, 0, 0}, 172, 172, { 1254, 500, 10029, 857, 0, ';' }}, + {0x0445, 0x0045, 257, 56, 9325, 9331, 9346, 4601, 4605, 4575, 8872, {38164, 0, 0, 0}, 173, 173, { 0, 500, 2, 1, 0, ',' }}, + {0x0447, 0x0047, 257, 56, 9377, 9383, 9400, 4681, 4685, 4647, 8872, {38282, 0, 0, 0}, 174, 174, { 0, 500, 2, 1, 0, ',' }}, + {0x0448, 0x0048, 257, 56, 9437, 9443, 9456, 4713, 4717, 4689, 8872, {0, 0, 0, 0}, 175, 175, { 0, 500, 2, 1, 0, ',' }}, + {0x0449, 0x0049, 257, 56, 9487, 9493, 9507, 4746, 4750, 4721, 8872, {38338, 0, 0, 0}, 176, 176, { 0, 500, 2, 1, 0, ',' }}, + {0x044A, 0x004A, 257, 56, 9547, 9553, 9568, 4783, 4787, 4754, 8872, {38403, 0, 0, 0}, 177, 177, { 0, 500, 2, 1, 0, ',' }}, + {0x044B, 0x004B, 257, 56, 9615, 9621, 9637, 4815, 4819, 1715, 8872, {38468, 0, 0, 0}, 178, 178, { 0, 500, 2, 1, 0, ',' }}, + {0x044C, 0x004C, 257, 56, 9668, 9674, 9692, 4855, 4859, 4823, 8872, {38533, 0, 0, 0}, 179, 179, { 0, 500, 2, 1, 0, ',' }}, + {0x044D, 0x004D, 257, 56, 9732, 9738, 9755, 4897, 4901, 4863, 8872, {38577, 0, 0, 0}, 180, 180, { 0, 500, 2, 1, 0, ',' }}, + {0x044E, 0x004E, 257, 56, 9792, 9798, 9814, 4932, 4936, 4905, 8872, {38630, 0, 0, 0}, 181, 181, { 0, 500, 2, 1, 0, ',' }}, + {0x0450, 0x7850, 257, 85, 9845, 9851, 9872, 9900, 4970, 4940, 9904, {38692, 0, 0, 0}, 182, 182, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0451, 0x0051, 257, 25, 9907, 9913, 9929, 5010, 5014, 4974, 9975, {0, 0, 0, 0}, 183, 183, { 0, 500, 2, 1, 0, ',' }}, + {0x0452, 0x0052, 257, 43, 9978, 9984, 10007, 5035, 5039, 5018, 10034, {38724, 0, 0, 0}, 184, 184, { 1252, 20285, 10000, 850, 0, ';' }}, + {0x0453, 0x0053, 257, 66, 10037, 10043, 10060, 5068, 5072, 5043, 10100, {38740, 0, 0, 0}, 185, 185, { 0, 500, 2, 1, 0, ',' }}, + {0x0454, 0x0054, 257, 70, 10103, 10109, 10120, 5093, 5097, 5076, 10142, {38795, 0, 0, 0}, 186, 186, { 0, 500, 2, 1, 0, ';' }}, + {0x0455, 0x0055, 257, 84, 10145, 10151, 10177, 5131, 5135, 5101, 10217, {38841, 0, 0, 0}, 187, 187, { 0, 500, 2, 1, 0, ';' }}, + {0x0456, 0x0056, 257, 38, 10220, 10226, 10243, 5158, 5162, 5139, 6218, {36899, 0, 0, 0}, 188, 188, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0457, 0x0057, 257, 56, 10260, 10267, 10283, 5197, 5166, 5166, 8872, {0, 0, 0, 0}, 189, 189, { 0, 500, 2, 1, 0, ',' }}, + {0x045B, 0x005B, 257, 73, 10317, 10323, 10343, 5228, 5232, 5201, 10393, {38912, 0, 0, 0}, 190, 190, { 0, 500, 2, 1, 0, ';' }}, + {0x045E, 0x005E, 257, 39, 10396, 10402, 10421, 5284, 5288, 5, 10452, {39017, 0, 0, 0}, 191, 191, { 0, 500, 2, 1, 0, ';' }}, + {0x0461, 0x0061, 257, 94, 10455, 10461, 10476, 5376, 5380, 5347, 10513, {39065, 0, 0, 0}, 192, 192, { 0, 500, 2, 1, 0, ',' }}, + {0x0462, 0x0062, 257, 92, 10516, 10522, 10552, 5414, 5418, 5384, 6940, {39115, 0, 0, 0}, 193, 193, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0463, 0x0063, 1024, 1, 10575, 10581, 10602, 5441, 5445, 5422, 10632, {0, 0, 0, 0}, 194, 194, { 0, 500, 2, 1, 1, ';' }}, + {0x0464, 0x0064, 257, 99, 10635, 10642, 10665, 5462, 5449, 5449, 10686, {39138, 0, 0, 0}, 195, 195, { 1252, 500, 10000, 437, 0, ';' }}, + {0x0468, 0x7C68, 257, 90, 10689, 10700, 10723, 5499, 5503, 5490, 10740, {0, 0, 0, 0}, 196, 196, { 1252, 37, 10000, 437, 0, ';' }}, + {0x046A, 0x006A, 257, 90, 10743, 10749, 10766, 5532, 5536, 5507, 10740, {0, 0, 0, 0}, 197, 197, { 1252, 37, 10000, 437, 0, ';' }}, + {0x046C, 0x006C, 257, 134, 10812, 10819, 5559, 5576, 5540, 5540, 8489, {0, 0, 0, 0}, 198, 198, { 1252, 500, 10000, 850, 0, ';' }}, + {0x046E, 0x006E, 257, 75, 10849, 10855, 10882, 5613, 5617, 5580, 10912, {39162, 0, 0, 0}, 199, 199, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x046F, 0x006F, 257, 45, 10915, 10921, 10945, 5648, 5652, 5621, 10976, {39186, 0, 0, 0}, 200, 200, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x0470, 0x0070, 257, 90, 10979, 10985, 10985, 5664, 5668, 5656, 10740, {0, 0, 0, 0}, 201, 201, { 1252, 37, 10000, 437, 0, ';' }}, + {0x0472, 0x0072, 257, 39, 11000, 11006, 11023, 5688, 5692, 5672, 10452, {0, 0, 0, 0}, 202, 202, { 0, 500, 2, 1, 0, ';' }}, + {0x0473, 0x0073, 257, 39, 11043, 11049, 11069, 11100, 5725, 5696, 10452, {0, 0, 0, 0}, 203, 203, { 0, 500, 2, 1, 0, ';' }}, + {0x0475, 0x0075, 257, 128, 11104, 11111, 11136, 5760, 5729, 5729, 6510, {0, 0, 0, 0}, 204, 204, { 1252, 37, 10000, 437, 0, ';' }}, + {0x0477, 0x0077, 257, 117, 11179, 11185, 11202, 5783, 5787, 5764, 11224, {0, 0, 0, 0}, 205, 205, { 0, 500, 2, 1, 0, ';' }}, + {0x0478, 0x0078, 257, 25, 11227, 11233, 11252, 5815, 5819, 5791, 9975, {39213, 0, 0, 0}, 206, 206, { 0, 500, 2, 1, 0, ';' }}, + {0x047E, 0x007E, 257, 42, 11271, 11277, 11293, 5843, 5847, 5823, 6595, {39226, 0, 0, 0}, 207, 207, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0480, 0x0080, 257, 25, 11312, 11318, 11333, 5878, 5882, 5851, 9975, {39246, 0, 0, 0}, 208, 208, { 1256, 20420, 10004, 720, 1, ',' }}, + {0x0484, 0x0084, 257, 42, 11363, 11370, 11392, 5922, 5886, 5886, 6595, {39282, 0, 0, 0}, 209, 209, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0485, 0x0085, 257, 109, 11424, 11431, 11446, 5954, 5926, 5926, 7239, {0, 0, 0, 0}, 210, 210, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0487, 0x0087, 257, 110, 11485, 11491, 11491, 5973, 5977, 5958, 11512, {0, 0, 0, 0}, 211, 211, { 1252, 37, 10000, 437, 0, ';' }}, + {0x0491, 0x0091, 257, 43, 11515, 11521, 11554, 6010, 6014, 5981, 10034, {39307, 0, 0, 0}, 212, 212, { 1252, 20285, 10000, 850, 0, ';' }}, + {0x0801, 0x0001, 257, 57, 11590, 11596, 11610, 11640, 2575, 2546, 11644, {39339, 0, 0, 0}, 213, 213, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x0803, 0x0403, 257, 38, 11647, 6184, 6200, 11662, 2642, 2619, 6218, {36739, 0, 0, 0}, 214, 214, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0804, 0x0004, 257, 25, 11666, 2654, 11672, 2682, 2686, 2690, 9975, {36759, 0, 0, 0}, 215, 215, { 936, 500, 10008, 936, 0, ',' }}, + {0x0807, 0x0007, 257, 21, 11688, 11694, 11715, 11733, 2801, 2779, 314, {36813, 0, 0, 0}, 216, 216, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x0809, 0x0009, 257, 43, 11737, 11743, 11743, 11768, 2854, 2839, 10034, {36880, 0, 0, 0}, 217, 217, { 1252, 20285, 10000, 850, 0, ',' }}, + {0x080A, 0x000A, 257, 88, 11772, 11778, 11795, 11814, 2882, 2858, 11818, {37041, 0, 0, 0}, 218, 218, { 1252, 20284, 10000, 850, 0, ',' }}, + {0x080C, 0x000C, 257, 10, 11821, 11827, 11844, 11865, 2935, 2911, 11869, {36946, 0, 0, 0}, 219, 219, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0810, 0x0010, 257, 21, 11872, 11878, 11900, 11920, 3051, 3027, 314, {37041, 0, 0, 0}, 220, 220, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0813, 0x0013, 257, 10, 11924, 11930, 11946, 11967, 3137, 3113, 11869, {37097, 0, 0, 0}, 221, 221, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0814, 0x7814, 257, 93, 11971, 11977, 12004, 12020, 12024, 12028, 6998, {36792, 0, 0, 0}, 222, 222, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x0816, 0x0016, 257, 103, 12031, 12037, 12059, 444, 3225, 3196, 12081, {39371, 0, 0, 0}, 223, 223, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0818, 0x0018, 257, 80, 12084, 12090, 12109, 12138, 3283, 3258, 12142, {37186, 0, 0, 0}, 224, 224, { 1250, 500, 2, 852, 0, ';' }}, + {0x0819, 0x0019, 257, 80, 12145, 12151, 12169, 12201, 3317, 3287, 12142, {37205, 0, 0, 0}, 225, 225, { 1251, 500, 2, 866, 0, ';' }}, + {0x081D, 0x001D, 257, 40, 12205, 12211, 12229, 12247, 3429, 3406, 6551, {36792, 0, 0, 0}, 226, 226, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x0820, 0x0020, 257, 56, 12251, 12257, 12270, 12292, 3508, 3487, 8872, {37362, 0, 0, 0}, 227, 227, { 1256, 500, 2, 720, 1, ';' }}, + {0x082C, 0x742C, 257, 7, 12296, 12307, 8249, 12342, 3914, 3883, 8275, {37652, 0, 0, 0}, 228, 228, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x082E, 0x7C2E, 257, 30, 12346, 12353, 12377, 12403, 12407, 12407, 6421, {39394, 0, 0, 0}, 229, 229, { 1252, 870, 10000, 850, 0, ';' }}, + {0x0832, 0x0032, 257, 16, 12411, 12417, 4098, 12435, 4111, 4088, 12439, {0, 0, 0, 0}, 230, 230, { 1252, 500, 10000, 850, 0, ';' }}, + {0x083B, 0x003B, 257, 112, 12442, 12448, 12471, 12499, 4356, 4318, 7428, {37964, 0, 0, 0}, 231, 231, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x083C, 0x003C, 257, 54, 12503, 12509, 12525, 4377, 4381, 4360, 12541, {37983, 0, 0, 0}, 232, 232, { 1252, 500, 10000, 850, 0, ';' }}, + {0x083E, 0x003E, 257, 13, 12544, 12550, 12565, 12588, 4412, 4385, 12592, {38004, 0, 0, 0}, 233, 233, { 1252, 500, 10000, 850, 0, ';' }}, + {0x0843, 0x7843, 257, 130, 12595, 12606, 9298, 12635, 4571, 4549, 9322, {39417, 0, 0, 0}, 234, 234, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x0845, 0x0045, 257, 9, 12639, 12645, 12665, 12708, 4605, 4575, 12712, {38164, 0, 0, 0}, 235, 235, { 0, 500, 2, 1, 0, ',' }}, + {0x0846, 0x7C46, 257, 100, 12715, 12726, 12753, 12799, 4643, 4609, 7572, {38235, 0, 0, 0}, 236, 236, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x0849, 0x0049, 257, 73, 12803, 12809, 12827, 12864, 4750, 4721, 10393, {38338, 0, 0, 0}, 237, 237, { 0, 500, 2, 1, 0, ';' }}, + {0x0861, 0x0061, 257, 56, 12868, 12874, 12889, 12923, 5380, 5347, 8872, {39065, 0, 0, 0}, 238, 238, { 0, 500, 2, 1, 0, ';' }}, + {0x0873, 0x0073, 257, 37, 12927, 12933, 12952, 5721, 5725, 5696, 12980, {0, 0, 0, 0}, 239, 239, { 0, 500, 2, 1, 0, ';' }}, + {0x0C01, 0x0001, 257, 36, 12983, 12989, 13004, 13028, 2575, 2546, 13032, {39339, 0, 0, 0}, 240, 240, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x0C04, 0x7C04, 257, 48, 13035, 13041, 13084, 13121, 2686, 2690, 13125, {39332, 0, 0, 0}, 241, 241, { 950, 500, 10002, 950, 0, ',' }}, + {0x0C07, 0x0007, 257, 5, 13128, 13134, 13151, 13173, 2801, 2779, 13177, {36813, 0, 0, 0}, 242, 242, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x0C09, 0x0009, 257, 6, 13180, 13186, 13186, 13206, 2854, 2839, 13210, {36880, 0, 0, 0}, 243, 243, { 1252, 500, 10000, 850, 0, ',' }}, + {0x0C0A, 0x000A, 257, 38, 13213, 13219, 13235, 13254, 2882, 2858, 6218, {36899, 0, 0, 0}, 244, 244, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x0C0C, 0x000C, 257, 19, 13258, 13264, 13280, 13299, 2935, 2911, 13303, {36946, 0, 0, 0}, 245, 245, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x0C3B, 0x003B, 257, 40, 13306, 13312, 13336, 13362, 4356, 4318, 6551, {39455, 0, 0, 0}, 246, 246, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x1001, 0x0001, 257, 77, 13366, 13372, 13387, 13415, 2575, 2546, 13419, {39339, 0, 0, 0}, 247, 247, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x1004, 0x0004, 257, 113, 13422, 13428, 13460, 13479, 2686, 2690, 13483, {36759, 0, 0, 0}, 248, 248, { 936, 500, 10008, 936, 0, ',' }}, + {0x1007, 0x0007, 257, 75, 13486, 13492, 13512, 13532, 2801, 2779, 10912, {36813, 0, 0, 0}, 249, 249, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x1009, 0x0009, 257, 19, 13536, 13542, 13542, 13559, 2854, 2839, 13303, {36880, 0, 0, 0}, 250, 250, { 1252, 37, 10000, 850, 0, ',' }}, + {0x100A, 0x000A, 257, 47, 13563, 13569, 13589, 13610, 2882, 2858, 13614, {36899, 0, 0, 0}, 251, 251, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x100C, 0x000C, 257, 21, 13617, 13623, 13644, 13663, 2935, 2911, 314, {36946, 0, 0, 0}, 252, 252, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x101A, 0x001A, 257, 8, 13667, 13673, 13705, 13736, 3346, 3321, 13740, {37251, 0, 0, 0}, 253, 253, { 1250, 870, 10082, 852, 0, ';' }}, + {0x1401, 0x0001, 257, 33, 13743, 13749, 13766, 13798, 2575, 2546, 13802, {39339, 0, 0, 0}, 254, 254, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x1404, 0x7C04, 257, 86, 13805, 13811, 13850, 13887, 2686, 2690, 13891, {39332, 0, 0, 0}, 255, 255, { 950, 500, 10002, 950, 0, ',' }}, + {0x1407, 0x0007, 257, 72, 13894, 13900, 13923, 13947, 2801, 2779, 13951, {36813, 0, 0, 0}, 256, 256, { 1252, 20273, 10000, 850, 0, ';' }}, + {0x1409, 0x0009, 257, 95, 13954, 13960, 13960, 13982, 2854, 2839, 13986, {36880, 0, 0, 0}, 257, 257, { 1252, 500, 10000, 850, 0, ',' }}, + {0x140A, 0x000A, 257, 27, 13989, 13995, 14016, 14038, 2882, 2858, 14042, {36899, 0, 0, 0}, 258, 258, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x140C, 0x000C, 257, 75, 14045, 14051, 14071, 14094, 2935, 2911, 10912, {36946, 0, 0, 0}, 259, 259, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x141A, 0x681A, 257, 8, 14098, 14109, 14147, 14178, 14182, 14186, 13740, {37251, 0, 0, 0}, 260, 260, { 1250, 870, 10082, 852, 0, ';' }}, + {0x1801, 0x0001, 257, 78, 14189, 14195, 14212, 14242, 2575, 2546, 14246, {39339, 0, 0, 0}, 261, 261, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x1809, 0x0009, 257, 54, 14249, 14255, 14255, 14273, 2854, 2839, 12541, {36880, 0, 0, 0}, 262, 262, { 1252, 500, 10000, 850, 0, ',' }}, + {0x180A, 0x000A, 257, 97, 14277, 14283, 14300, 14319, 2882, 2858, 14323, {36899, 0, 0, 0}, 263, 263, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x180C, 0x000C, 257, 79, 14326, 14332, 14348, 14367, 2935, 2911, 14371, {36946, 0, 0, 0}, 264, 264, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x181A, 0x701A, 257, 8, 14374, 14385, 14423, 14475, 14479, 14483, 13740, {37251, 0, 0, 0}, 265, 265, { 1250, 870, 10082, 852, 0, ';' }}, + {0x1C01, 0x0001, 257, 123, 14486, 14492, 14509, 14535, 2575, 2546, 14539, {39339, 0, 0, 0}, 266, 266, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x1C09, 0x0009, 257, 134, 14542, 14548, 14548, 14571, 2854, 2839, 8489, {36880, 0, 0, 0}, 267, 267, { 1252, 500, 10000, 437, 0, ',' }}, + {0x1C0A, 0x000A, 257, 32, 14575, 14581, 14610, 14643, 2882, 2858, 14647, {36899, 0, 0, 0}, 268, 268, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x1C1A, 0x6C1A, 257, 8, 14650, 14661, 14423, 14702, 14479, 14483, 13740, {39477, 0, 0, 0}, 269, 269, { 1251, 21025, 10007, 855, 0, ';' }}, + {0x2001, 0x0001, 257, 96, 14706, 14712, 14726, 14754, 2575, 2546, 14758, {39339, 0, 0, 0}, 270, 270, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x2009, 0x0009, 257, 61, 14761, 14767, 14767, 14785, 2854, 2839, 14789, {36880, 0, 0, 0}, 271, 271, { 1252, 500, 10000, 850, 0, ',' }}, + {0x200A, 0x000A, 257, 131, 14792, 14798, 14818, 14839, 2882, 2858, 14843, {36899, 0, 0, 0}, 272, 272, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x200C, 0x000C, 257, 106, 14846, 14852, 14870, 14894, 2935, 2911, 14898, {36946, 0, 0, 0}, 273, 273, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x201A, 0x641A, 257, 8, 14901, 14912, 14147, 14953, 14182, 14186, 13740, {37712, 0, 0, 0}, 274, 274, { 1251, 870, 10082, 855, 0, ';' }}, + {0x2401, 0x0001, 257, 133, 14957, 14963, 14978, 15006, 2575, 2546, 15010, {39339, 0, 0, 0}, 275, 275, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x240A, 0x000A, 257, 26, 15013, 15019, 15038, 15058, 2882, 2858, 15062, {36899, 0, 0, 0}, 276, 276, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x240C, 0x000C, 257, 20, 15065, 15071, 15097, 15124, 2935, 2911, 15128, {36946, 0, 0, 0}, 277, 277, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x241A, 0x701A, 257, 108, 15131, 15142, 15166, 15194, 14479, 14483, 15198, {37251, 0, 0, 0}, 278, 278, { 1250, 500, 10029, 852, 0, ';' }}, + {0x243B, 0x703B, 257, 40, 15201, 15208, 15229, 15253, 15257, 15257, 6551, {0, 0, 0, 0}, 279, 279, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x2801, 0x0001, 257, 119, 15261, 15267, 15282, 15310, 2575, 2546, 15314, {39339, 0, 0, 0}, 280, 280, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x2809, 0x0009, 257, 18, 15317, 15323, 15323, 15340, 2854, 2839, 15344, {36880, 0, 0, 0}, 281, 281, { 1252, 500, 10000, 850, 0, ',' }}, + {0x280A, 0x000A, 257, 98, 15347, 15353, 15368, 15385, 2882, 2858, 15389, {36899, 0, 0, 0}, 282, 282, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x280C, 0x000C, 257, 116, 15392, 15398, 15415, 15437, 2935, 2911, 15441, {36946, 0, 0, 0}, 283, 283, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x281A, 0x6C1A, 257, 108, 15444, 15455, 15166, 15482, 14479, 14483, 15198, {39477, 0, 0, 0}, 284, 284, { 1251, 21025, 10007, 855, 0, ';' }}, + {0x2C01, 0x0001, 257, 62, 15486, 15492, 15508, 15538, 2575, 2546, 15542, {39339, 0, 0, 0}, 285, 285, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x2C09, 0x0009, 257, 125, 15545, 15551, 15551, 15579, 2854, 2839, 15583, {36880, 0, 0, 0}, 286, 286, { 1252, 500, 10000, 850, 0, ',' }}, + {0x2C0A, 0x000A, 257, 4, 15586, 15592, 15612, 15633, 2882, 2858, 15637, {36899, 0, 0, 0}, 287, 287, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x2C0C, 0x000C, 257, 24, 15640, 15646, 15664, 15685, 2935, 2911, 15689, {36946, 0, 0, 0}, 288, 288, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x2C1A, 0x701A, 257, 81, 15692, 15703, 15731, 15764, 14479, 14483, 15768, {37251, 0, 0, 0}, 289, 289, { 1250, 500, 10029, 852, 0, ';' }}, + {0x3001, 0x0001, 257, 71, 15771, 15777, 15794, 15822, 2575, 2546, 15826, {39339, 0, 0, 0}, 290, 290, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x3009, 0x0009, 257, 135, 15829, 15835, 15835, 15854, 2854, 2839, 15858, {36880, 0, 0, 0}, 291, 291, { 1252, 500, 10000, 437, 0, ',' }}, + {0x300A, 0x000A, 257, 34, 15861, 15867, 15885, 15904, 2882, 2858, 15908, {36899, 0, 0, 0}, 292, 292, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x300C, 0x000C, 257, 22, 15911, 15917, 15943, 15972, 2935, 2911, 15976, {36946, 0, 0, 0}, 293, 293, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x301A, 0x6C1A, 257, 81, 15979, 15990, 15731, 16021, 14479, 14483, 15768, {39477, 0, 0, 0}, 294, 294, { 1251, 21025, 10007, 855, 0, ';' }}, + {0x3401, 0x0001, 257, 68, 16025, 16031, 16047, 16077, 2575, 2546, 16081, {39339, 0, 0, 0}, 295, 295, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x3409, 0x0009, 257, 99, 16084, 16090, 16090, 16112, 2854, 2839, 10686, {36880, 0, 0, 0}, 296, 296, { 1252, 500, 10000, 437, 0, ',' }}, + {0x340A, 0x000A, 257, 23, 16116, 16122, 16138, 16155, 2882, 2858, 16159, {36899, 0, 0, 0}, 297, 297, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x340C, 0x000C, 257, 83, 16162, 16168, 16182, 16199, 2935, 2911, 16203, {36946, 0, 0, 0}, 298, 298, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x3801, 0x0001, 257, 0, 16206, 16212, 16242, 16306, 2575, 2546, 16310, {39339, 0, 0, 0}, 299, 299, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x380A, 0x000A, 257, 129, 16313, 16319, 16337, 16356, 2882, 2858, 16360, {36899, 0, 0, 0}, 300, 300, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x380C, 0x000C, 257, 78, 16363, 16369, 16386, 16404, 2935, 2911, 14246, {36946, 0, 0, 0}, 301, 301, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x3C01, 0x0001, 257, 12, 16408, 16414, 16431, 16463, 2575, 2546, 16467, {39339, 0, 0, 0}, 302, 302, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x3C09, 0x0009, 257, 48, 16470, 16476, 16476, 16506, 2854, 2839, 13125, {36880, 0, 0, 0}, 303, 303, { 1252, 500, 10000, 850, 0, ',' }}, + {0x3C0A, 0x000A, 257, 104, 16510, 16516, 16535, 16555, 2882, 2858, 16559, {36899, 0, 0, 0}, 304, 304, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x3C0C, 0x000C, 257, 51, 16562, 16568, 16583, 16602, 2935, 2911, 16606, {36946, 0, 0, 0}, 305, 305, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x4001, 0x0001, 257, 105, 16609, 16615, 16630, 16654, 2575, 2546, 16658, {39339, 0, 0, 0}, 306, 306, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x4009, 0x0009, 257, 56, 16661, 16667, 16667, 16683, 2854, 2839, 8872, {36880, 0, 0, 0}, 307, 307, { 1252, 37, 10000, 437, 0, ',' }}, + {0x400A, 0x000A, 257, 14, 16687, 16693, 16711, 16730, 2882, 2858, 16734, {36899, 0, 0, 0}, 308, 308, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x4409, 0x0009, 257, 89, 16737, 16743, 16743, 16762, 2854, 2839, 9016, {36880, 0, 0, 0}, 309, 309, { 1252, 37, 10000, 437, 0, ',' }}, + {0x440A, 0x000A, 257, 118, 16766, 16772, 16794, 16817, 2882, 2858, 16821, {36899, 0, 0, 0}, 310, 310, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x4809, 0x0009, 257, 113, 16824, 16830, 16830, 16850, 2854, 2839, 13483, {36880, 0, 0, 0}, 311, 311, { 1252, 37, 10000, 437, 0, ',' }}, + {0x480A, 0x000A, 257, 49, 16854, 16860, 16879, 16899, 2882, 2858, 16903, {36899, 0, 0, 0}, 312, 312, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x4C0A, 0x000A, 257, 91, 16906, 16912, 16932, 16953, 2882, 2858, 16957, {36899, 0, 0, 0}, 313, 313, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x500A, 0x000A, 257, 102, 16960, 16966, 16988, 17011, 2882, 2858, 17015, {36899, 0, 0, 0}, 314, 314, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x540A, 0x000A, 257, 128, 17018, 17024, 17048, 17074, 2882, 2858, 6510, {36899, 0, 0, 0}, 315, 315, { 1252, 20284, 10000, 850, 0, ',' }}, + {0x5C0A, 0x000A, 257, 28, 17078, 17084, 17099, 17115, 2882, 2858, 17119, {36899, 0, 0, 0}, 316, 316, { 1252, 20284, 10000, 850, 0, ';' }}, + {0x641A, 0x781A, 257, -1, 17122, 17130, 17149, 14953, 14182, 14186, 0, {37712, 0, 0, 0}, 317, 317, { 1251, 870, 10082, 855, 0, ';' }}, + {0x681A, 0x781A, 257, -1, 17158, 17166, 17149, 14178, 14182, 14186, 0, {37251, 0, 0, 0}, 318, 318, { 1250, 870, 10082, 852, 0, ';' }}, + {0x6C1A, 0x7C1A, 257, -1, 17182, 17190, 17209, 15482, 14479, 14483, 0, {39477, 0, 0, 0}, 319, 319, { 1251, 21025, 10007, 855, 0, ';' }}, + {0x701A, 0x7C1A, 257, -1, 17222, 17230, 17209, 15194, 14479, 14483, 0, {37251, 0, 0, 0}, 320, 320, { 1250, 500, 10029, 852, 0, ';' }}, + {0x703B, 0x003B, 257, -1, 15257, 17246, 17257, 15253, 15257, 15257, 0, {0, 0, 0, 0}, 321, 321, { 1252, 20278, 10000, 850, 0, ';' }}, + {0x742C, 0x002C, 257, -1, 17272, 17280, 3898, 12342, 3914, 3883, 0, {37652, 0, 0, 0}, 322, 322, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x7804, 0x007F, 257, -1, 2690, 2654, 2675, 2682, 2686, 2690, 0, {36759, 0, 0, 0}, 323, 323, { 936, 500, 10008, 936, 0, ',' }}, + {0x7814, 0x0014, 257, -1, 12028, 17303, 17321, 12020, 12024, 12028, 0, {36792, 0, 0, 0}, 324, 324, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x781A, 0x007F, 257, -1, 14186, 17329, 17149, 14178, 14182, 14186, 0, {37251, 0, 0, 0}, 325, 325, { 1250, 870, 10082, 852, 0, ';' }}, + {0x782C, 0x002C, 257, -1, 17337, 17345, 3898, 3910, 3914, 3883, 0, {37652, 0, 0, 0}, 326, 326, { 1254, 20905, 10081, 857, 0, ';' }}, + {0x7843, 0x0043, 257, -1, 17365, 17373, 4558, 12635, 4571, 4549, 0, {39417, 0, 0, 0}, 327, 327, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x7850, 0x0050, 257, -1, 17390, 17398, 4953, 9900, 4970, 4940, 0, {38692, 0, 0, 0}, 328, 328, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x7C04, 0x7804, 257, -1, 17419, 6227, 2675, 6265, 2686, 2690, 0, {39332, 0, 0, 0}, 329, 329, { 950, 500, 10002, 950, 0, ',' }}, + {0x7C04, 0x7C04, 257, -1, 17427, 17434, 2675, 6265, 2686, 2690, 0, {39332, 0, 0, 0}, 330, 330, { 950, 500, 10002, 950, 0, ',' }}, + {0x7C14, 0x0014, 257, -1, 3168, 17463, 17481, 3160, 3164, 3168, 0, {36792, 0, 0, 0}, 331, 331, { 1252, 20277, 10000, 850, 0, ';' }}, + {0x7C1A, 0x007F, 257, -1, 14483, 17495, 17209, 17503, 14479, 14483, 0, {39477, 0, 0, 0}, 332, 332, { 1250, 500, 10029, 852, 0, ';' }}, + {0x7C28, 0x0028, 257, -1, 17507, 17515, 3760, 3773, 3777, 3751, 0, {0, 0, 0, 0}, 333, 333, { 1251, 20880, 10007, 866, 0, ';' }}, + {0x7C2E, 0x002E, 257, -1, 12407, 17532, 17546, 12403, 12407, 12407, 0, {39394, 0, 0, 0}, 334, 334, { 1252, 870, 10000, 850, 0, ';' }}, + {0x7C43, 0x0043, 257, -1, 17563, 17571, 4558, 4567, 4571, 4549, 0, {38146, 0, 0, 0}, 335, 335, { 1254, 500, 10029, 857, 0, ';' }}, + {0x7C46, 0x0046, 257, -1, 17585, 17593, 4620, 12799, 4643, 4609, 0, {38235, 0, 0, 0}, 336, 336, { 1256, 20420, 10004, 720, 1, ';' }}, + {0x7C5F, 0x005F, 257, -1, 17610, 17619, 5320, 5343, 5292, 5292, 0, {0, 0, 0, 0}, 337, 337, { 1252, 20297, 10000, 850, 0, ';' }}, + {0x7C68, 0x0068, 257, -1, 17651, 17659, 5493, 5499, 5503, 5490, 0, {0, 0, 0, 0}, 338, 338, { 1252, 37, 10000, 437, 0, ';' }} +}; + + +static const CultureInfoNameEntry culture_name_entries [] = { + {4165, 53}, /* af */ + {17673, 161}, /* af-za */ + {5, 86}, /* am */ + {17679, 191}, /* am-et */ + {2546, 0}, /* ar */ + {17685, 299}, /* ar-ae */ + {17691, 302}, /* ar-bh */ + {17697, 254}, /* ar-dz */ + {17703, 240}, /* ar-eg */ + {17709, 213}, /* ar-iq */ + {17715, 285}, /* ar-jo */ + {17721, 295}, /* ar-kw */ + {17727, 290}, /* ar-lb */ + {17733, 247}, /* ar-ly */ + {17739, 261}, /* ar-ma */ + {17745, 270}, /* ar-om */ + {17751, 306}, /* ar-qa */ + {17757, 110}, /* ar-sa */ + {17763, 280}, /* ar-sy */ + {17769, 266}, /* ar-tn */ + {17775, 275}, /* ar-ye */ + {4863, 74}, /* as */ + {17781, 180}, /* as-in */ + {3883, 44}, /* az */ + {17787, 322}, /* az-cyrl */ + {17795, 228}, /* az-cyrl-az */ + {17806, 326}, /* az-latn */ + {17814, 152}, /* az-latn-az */ + {3586, 35}, /* be */ + {17825, 143}, /* be-by */ + {2579, 1}, /* bg */ + {17831, 111}, /* bg-bg */ + {4575, 66}, /* bn */ + {17837, 235}, /* bn-bd */ + {17843, 173}, /* bn-in */ + {4974, 77}, /* bo */ + {17849, 183}, /* bo-cn */ + {5823, 104}, /* br */ + {17855, 207}, /* br-fr */ + {14186, 325}, /* bs */ + {17861, 317}, /* bs-cyrl */ + {17869, 274}, /* bs-cyrl-ba */ + {17880, 318}, /* bs-latn */ + {17888, 260}, /* bs-latn-ba */ + {2619, 2}, /* ca */ + {17899, 112}, /* ca-es */ + {17905, 214}, /* ca-es-valencia */ + {5236, 85}, /* chr */ + {2728, 5}, /* cs */ + {17920, 114}, /* cs-cz */ + {5018, 78}, /* cy */ + {17926, 184}, /* cy-gb */ + {2755, 6}, /* da */ + {17932, 115}, /* da-dk */ + {2779, 7}, /* de */ + {17938, 242}, /* de-at */ + {17944, 216}, /* de-ch */ + {17950, 116}, /* de-de */ + {17956, 256}, /* de-li */ + {17962, 249}, /* de-lu */ + {12407, 334}, /* dsb */ + {17968, 229}, /* dsb-de */ + {2805, 8}, /* el */ + {17975, 117}, /* el-gr */ + {2839, 9}, /* en */ + {17981, 243}, /* en-au */ + {17987, 281}, /* en-bz */ + {17993, 250}, /* en-ca */ + {17999, 217}, /* en-gb */ + {18005, 303}, /* en-hk */ + {18011, 262}, /* en-ie */ + {18017, 307}, /* en-in */ + {18023, 271}, /* en-jm */ + {18029, 309}, /* en-my */ + {18035, 257}, /* en-nz */ + {18041, 296}, /* en-ph */ + {18047, 311}, /* en-sg */ + {18053, 286}, /* en-tt */ + {18059, 118}, /* en-us */ + {18065, 267}, /* en-za */ + {18071, 291}, /* en-zw */ + {2858, 10}, /* es */ + {18077, 287}, /* es-ar */ + {18083, 308}, /* es-bo */ + {18089, 297}, /* es-cl */ + {18095, 276}, /* es-co */ + {18101, 258}, /* es-cr */ + {18107, 316}, /* es-cu */ + {18113, 268}, /* es-do */ + {18119, 292}, /* es-ec */ + {18125, 244}, /* es-es */ + {18131, 251}, /* es-gt */ + {18137, 312}, /* es-hn */ + {18143, 218}, /* es-mx */ + {18149, 313}, /* es-ni */ + {18155, 263}, /* es-pa */ + {18161, 282}, /* es-pe */ + {18167, 314}, /* es-pr */ + {18173, 304}, /* es-py */ + {18179, 310}, /* es-sv */ + {18185, 315}, /* es-us */ + {18191, 300}, /* es-uy */ + {18197, 272}, /* es-ve */ + {3664, 37}, /* et */ + {18203, 145}, /* et-ee */ + {3918, 45}, /* eu */ + {18209, 153}, /* eu-es */ + {3781, 41}, /* fa */ + {18215, 149}, /* fa-ir */ + {5466, 92}, /* ff */ + {2886, 11}, /* fi */ + {18221, 119}, /* fi-fi */ + {5449, 91}, /* fil */ + {18227, 195}, /* fil-ph */ + {4228, 55}, /* fo */ + {18234, 163}, /* fo-fo */ + {2911, 12}, /* fr */ + {18240, 219}, /* fr-be */ + {18246, 245}, /* fr-ca */ + {18252, 277}, /* fr-cd */ + {18258, 252}, /* fr-ch */ + {18264, 293}, /* fr-ci */ + {18270, 288}, /* fr-cm */ + {18276, 120}, /* fr-fr */ + {18282, 305}, /* fr-ht */ + {18288, 259}, /* fr-lu */ + {18294, 301}, /* fr-ma */ + {18300, 264}, /* fr-mc */ + {18306, 298}, /* fr-ml */ + {18312, 273}, /* fr-re */ + {18318, 283}, /* fr-sn */ + {5384, 89}, /* fy */ + {18324, 193}, /* fy-nl */ + {4360, 59}, /* ga */ + {18330, 232}, /* ga-ie */ + {5981, 109}, /* gd */ + {18336, 212}, /* gd-gb */ + {5139, 82}, /* gl */ + {18342, 188}, /* gl-es */ + {5886, 106}, /* gsw */ + {18348, 209}, /* gsw-fr */ + {4647, 68}, /* gu */ + {18355, 174}, /* gu-in */ + {5490, 93}, /* ha */ + {18361, 338}, /* ha-latn */ + {18369, 196}, /* ha-latn-ng */ + {5729, 101}, /* haw */ + {18380, 204}, /* haw-us */ + {2939, 13}, /* he */ + {18387, 121}, /* he-il */ + {4257, 56}, /* hi */ + {18393, 164}, /* hi-in */ + {3321, 26}, /* hr */ + {18399, 253}, /* hr-ba */ + {18405, 134}, /* hr-hr */ + {3944, 46}, /* hsb */ + {18411, 154}, /* hsb-de */ + {2968, 14}, /* hu */ + {18418, 122}, /* hu-hu */ + {3848, 43}, /* hy */ + {18424, 151}, /* hy-am */ + {3512, 33}, /* id */ + {18430, 141}, /* id-id */ + {5656, 98}, /* ig */ + {18436, 201}, /* ig-ng */ + {5791, 103}, /* ii */ + {18442, 206}, /* ii-cn */ + {2996, 15}, /* is */ + {18448, 123}, /* is-is */ + {3027, 16}, /* it */ + {18454, 220}, /* it-ch */ + {18460, 124}, /* it-it */ + {3055, 17}, /* ja */ + {18466, 125}, /* ja-jp */ + {4186, 54}, /* ka */ + {18472, 162}, /* ka-ge */ + {4416, 61}, /* kk */ + {18478, 168}, /* kk-kz */ + {5621, 97}, /* kl */ + {18484, 200}, /* kl-gl */ + {5043, 79}, /* km */ + {18490, 185}, /* km-kh */ + {1715, 72}, /* kn */ + {18496, 178}, /* kn-in */ + {3085, 18}, /* ko */ + {18502, 126}, /* ko-kr */ + {5166, 83}, /* kok */ + {18508, 189}, /* kok-in */ + {4454, 62}, /* ky */ + {18515, 169}, /* ky-kg */ + {5580, 96}, /* lb */ + {18521, 199}, /* lb-lu */ + {5076, 80}, /* lo */ + {18527, 186}, /* lo-la */ + {3719, 39}, /* lt */ + {18533, 147}, /* lt-lt */ + {3690, 38}, /* lv */ + {18539, 146}, /* lv-lv */ + {3984, 47}, /* mk */ + {18545, 155}, /* mk-mk */ + {4823, 73}, /* ml */ + {18551, 179}, /* ml-in */ + {4940, 76}, /* mn */ + {18557, 328}, /* mn-cyrl */ + {18565, 182}, /* mn-mn */ + {4905, 75}, /* mr */ + {18571, 181}, /* mr-in */ + {4385, 60}, /* ms */ + {18577, 233}, /* ms-bn */ + {18583, 167}, /* ms-my */ + {4293, 57}, /* mt */ + {18589, 165}, /* mt-mt */ + {5101, 81}, /* my */ + {18595, 187}, /* my-mm */ + {3168, 331}, /* nb */ + {18601, 128}, /* nb-no */ + {5347, 88}, /* ne */ + {18607, 238}, /* ne-in */ + {18613, 192}, /* ne-np */ + {3113, 19}, /* nl */ + {18619, 221}, /* nl-be */ + {18625, 127}, /* nl-nl */ + {12028, 324}, /* nn */ + {18631, 222}, /* nn-no */ + {3141, 20}, /* no */ + {5540, 95}, /* nso */ + {18637, 198}, /* nso-za */ + {5672, 99}, /* om */ + {18644, 202}, /* om-et */ + {4689, 69}, /* or */ + {18650, 175}, /* or-in */ + {4609, 67}, /* pa */ + {18656, 336}, /* pa-arab */ + {18664, 236}, /* pa-arab-pk */ + {3171, 21}, /* pl */ + {18675, 129}, /* pl-pl */ + {5422, 90}, /* ps */ + {18681, 194}, /* ps-af */ + {3196, 22}, /* pt */ + {18687, 130}, /* pt-br */ + {18693, 223}, /* pt-pt */ + {3229, 23}, /* rm */ + {18699, 131}, /* rm-ch */ + {3258, 24}, /* ro */ + {18705, 224}, /* ro-md */ + {18711, 132}, /* ro-ro */ + {3287, 25}, /* ru */ + {18717, 225}, /* ru-md */ + {18723, 133}, /* ru-ru */ + {5958, 108}, /* rw */ + {18729, 211}, /* rw-rw */ + {5926, 107}, /* sah */ + {18735, 210}, /* sah-ru */ + {4318, 58}, /* se */ + {18742, 246}, /* se-fi */ + {18748, 166}, /* se-no */ + {18754, 231}, /* se-se */ + {5201, 84}, /* si */ + {18760, 190}, /* si-lk */ + {3350, 27}, /* sk */ + {18766, 135}, /* sk-sk */ + {3629, 36}, /* sl */ + {18772, 144}, /* sl-si */ + {15257, 321}, /* smn */ + {18778, 279}, /* smn-fi */ + {5764, 102}, /* so */ + {18785, 205}, /* so-so */ + {3380, 28}, /* sq */ + {18791, 136}, /* sq-al */ + {14483, 332}, /* sr */ + {18797, 319}, /* sr-cyrl */ + {18805, 269}, /* sr-cyrl-ba */ + {18816, 294}, /* sr-cyrl-me */ + {18827, 284}, /* sr-cyrl-rs */ + {18838, 320}, /* sr-latn */ + {18846, 265}, /* sr-latn-ba */ + {18857, 289}, /* sr-latn-me */ + {18868, 278}, /* sr-latn-rs */ + {4027, 48}, /* st */ + {18879, 156}, /* st-za */ + {3406, 29}, /* sv */ + {18885, 226}, /* sv-fi */ + {18891, 137}, /* sv-se */ + {4489, 63}, /* sw */ + {18897, 170}, /* sw-ke */ + {4721, 70}, /* ta */ + {18903, 176}, /* ta-in */ + {18909, 237}, /* ta-lk */ + {4754, 71}, /* te */ + {18915, 177}, /* te-in */ + {3751, 40}, /* tg */ + {18921, 333}, /* tg-cyrl */ + {18929, 148}, /* tg-cyrl-tj */ + {3433, 30}, /* th */ + {18940, 138}, /* th-th */ + {5696, 100}, /* ti */ + {18946, 239}, /* ti-er */ + {18952, 203}, /* ti-et */ + {4518, 64}, /* tk */ + {18958, 171}, /* tk-tm */ + {4088, 50}, /* tn */ + {18964, 230}, /* tn-bw */ + {18970, 158}, /* tn-za */ + {3459, 31}, /* tr */ + {18976, 139}, /* tr-tr */ + {4061, 49}, /* ts */ + {18982, 157}, /* ts-za */ + {5292, 87}, /* tzm */ + {18988, 337}, /* tzm-latn */ + {5851, 105}, /* ug */ + {18997, 208}, /* ug-cn */ + {3544, 34}, /* uk */ + {19003, 142}, /* uk-ua */ + {3487, 32}, /* ur */ + {19009, 227}, /* ur-in */ + {19015, 140}, /* ur-pk */ + {4549, 65}, /* uz */ + {19021, 327}, /* uz-cyrl */ + {19029, 234}, /* uz-cyrl-uz */ + {19040, 335}, /* uz-latn */ + {19048, 172}, /* uz-latn-uz */ + {3811, 42}, /* vi */ + {19059, 150}, /* vi-vn */ + {4115, 51}, /* xh */ + {19065, 159}, /* xh-za */ + {5507, 94}, /* yo */ + {19071, 197}, /* yo-ng */ + {2690, 323}, /* zh */ + {19077, 4}, /* zh-chs */ + {19084, 330}, /* zh-cht */ + {19091, 215}, /* zh-cn */ + {19097, 3}, /* zh-hans */ + {19105, 329}, /* zh-hant */ + {19113, 241}, /* zh-hk */ + {19119, 255}, /* zh-mo */ + {19125, 248}, /* zh-sg */ + {19131, 113}, /* zh-tw */ + {4141, 52}, /* zu */ + {19137, 160} /* zu-za */ +}; + + +static const RegionInfoEntry region_entries [] = { + { 224,16310,13028,13028,19143,19164,2487,19211,19215,19243}, + { 3,10632,19267,19267,19271,19283,2158,19302,19306,19321}, + { 6,7384,19334,19334,19338,19346,1718,19356,19360,19373}, + { 7,49,14242,14242,19387,19395,1856,19412,19416,19430}, + { 11,15637,13798,13798,19456,19456,1462,15310,19466,19481}, + { 14,13177,19496,19496,19500,19508,1357,19520,19524,19524}, + { 12,13210,19529,19529,19533,19533,1462,19543,19547,19547}, + { 5,8275,3910,3910,19565,19576,2221,19588,19592,19610}, + { 25,13740,19630,19630,19634,19655,2341,19675,19679,19715}, + { 23,12712,19735,19735,19739,19750,2304,19775,19779,19796}, + { 21,11869,3621,3621,19837,19845,1357,19520,19524,19854}, + { 35,6175,2611,2611,19859,19868,1339,19885,19889,19903}, + { 17,16467,19929,19929,19933,19941,2501,19956,19960,19975}, + { 37,12592,19999,19999,20003,20003,1462,20010,20014,20028}, + { 26,16734,20041,20041,20045,20045,2527,5010,20053,20072}, + { 32,7088,20082,20082,20086,20093,1606,20100,20104,20119}, + { 19,12439,20135,20135,20139,0,2262,20148,20152,0}, + { 29,7763,20167,20167,20171,20179,1766,20196,20200,20217}, + { 24,15344,20249,20249,20253,20253,1462,20260,20264,20264}, + { 39,13303,20278,20278,20282,20282,1462,20289,20293,20309}, + { 44,15128,20325,20325,20329,20346,2420,20361,20365,20381}, + { 223,314,20397,20397,20401,20413,1613,1613,20420,20432}, + { 119,15976,20446,20446,20450,20450,2448,20467,20471,20494}, + { 46,16159,20512,20512,20516,20516,1462,20522,20526,20539}, + { 49,15689,20552,20552,20556,20565,2462,20574,20578,20604}, + { 45,9975,20621,20621,20625,20631,1378,20650,20654,20667}, + { 51,15062,20686,20686,20690,20690,1462,20699,20703,20718}, + { 54,14042,20734,20734,20738,20738,2359,20749,20753,20772}, + { 56,17119,20793,20793,20797,20797,1462,20802,20806,20817}, + { 75,6331,20829,20829,20833,20848,1381,20866,20870,20892}, + { 94,6421,2797,2797,20907,20915,1357,19520,19524,19524}, + { 61,6373,20927,20927,20931,20939,1409,20947,20951,20964}, + { 65,14647,20976,20976,20980,20999,2387,21021,21025,21040}, + { 4,13802,21056,21056,21060,21068,2344,21083,21087,21102}, + { 66,15908,21126,21126,21130,21130,1462,21138,21142,21152}, + { 70,7861,17074,17074,21174,21182,1357,19520,19524,19854}, + { 67,13032,21188,21188,21192,21198,2315,21205,21209,21224}, + { 71,12980,21242,21242,21246,21254,2169,21267,21271,0}, + { 217,6218,2878,2878,21286,21292,1357,19520,19524,19854}, + { 73,10452,21300,21300,21304,21313,2144,21329,21333,21348}, + { 77,6551,2903,2903,21374,21382,1357,19520,19524,19854}, + { 81,8815,16404,16404,21388,21402,1724,20947,20951,21411}, + { 84,6595,2931,2931,21424,21424,1357,19520,19524,19854}, + { 242,10034,21431,21431,21435,21450,2037,21467,21471,21485}, + { 88,8761,21498,21498,21502,21510,1894,21541,21545,21559}, + { 93,10976,21594,21594,21598,21608,1409,20947,20951,21625}, + { 98,6477,21645,21645,21649,21656,1357,19520,19524,21669}, + { 99,13614,21678,21678,21682,21682,2339,21692,21696,21715}, + { 104,13125,21723,21723,21727,21747,2325,21775,21779,21796}, + { 106,16903,21803,21803,21807,21807,2260,21816,21820,21837}, + { 108,7287,3342,3342,21856,21864,2217,2217,21873,21887}, + { 103,16606,21901,21901,21905,21911,2515,21918,21922,21937}, + { 109,6696,2988,2988,21955,21963,1520,21977,21981,21998}, + { 111,7626,22012,22012,3526,3526,1759,22016,22020,22038}, + { 68,12541,22055,22055,22059,22067,1357,19520,19524,19524}, + { 117,6644,22073,22073,22077,22084,1511,22095,22099,22118}, + { 113,8872,3536,3536,22132,22138,1939,22151,22155,22168}, + { 121,11644,22203,22203,22207,22212,2248,22225,22229,22241}, + { 116,8086,22263,22263,22267,22272,1843,22283,22287,22300}, + { 110,6745,3019,3019,22320,22328,1523,1523,22336,22353}, + { 118,6788,3047,3047,22369,22375,1357,19520,19524,19854}, + { 124,14789,22382,22382,22386,22386,1462,22394,22398,22398}, + { 126,15542,22414,22414,22418,22425,2452,22438,22442,22458}, + { 122,6833,3077,3077,22480,22486,1537,22493,22497,22510}, + { 129,9198,22520,22520,22524,22524,1991,22530,22534,22550}, + { 130,9155,22568,22568,22572,22583,1967,22604,22608,22623}, + { 40,10100,5068,5068,22653,22662,2040,22684,22688,22703}, + { 134,6888,3105,3105,22737,22749,1541,22762,22766,22783}, + { 136,16081,22800,22800,22804,22811,2477,22824,22828,22842}, + { 137,9086,22864,22864,22868,22879,1946,22898,22902,22920}, + { 138,10142,5093,5093,22954,5083,2044,22959,22963,22975}, + { 139,15826,22995,22995,22999,23007,2467,23018,23022,23037}, + { 145,13951,23059,23059,23063,23063,1613,1613,20420,23077}, + { 42,10393,23095,23095,23099,23109,2136,23141,23145,23162}, + { 141,7959,23210,23210,23214,23224,1357,19520,19524,23232}, + { 147,10912,23238,23238,23242,23253,1357,19520,19524,19524}, + { 140,7907,23265,23265,23269,23276,1357,19520,19524,23284}, + { 148,13419,23289,23289,23293,23299,2329,23310,23314,23327}, + { 159,14246,4932,4932,23347,23355,2363,2497,23368,23384}, + { 158,14371,23404,23404,23408,23408,1357,19520,19524,19854}, + { 152,12142,23415,23415,23419,23427,2260,23445,23449,23462}, + { 270,15768,23478,23478,23482,23493,1357,19520,19524,23511}, + { 19618,8450,23516,23516,23520,23530,1885,23516,23551,23568}, + { 157,16203,23600,23600,23604,23604,2448,20467,20471,20494}, + { 27,10217,23609,23609,23613,5112,2094,23629,23633,23646}, + { 154,9904,23677,23677,23681,23690,2231,23703,23707,23724}, + { 151,13891,23737,23737,23741,23757,2354,23785,23789,23805}, + { 163,8911,4310,4310,23815,23815,1357,19520,19524,23821}, + { 166,11818,23826,23826,23830,23837,1462,23845,23849,23862}, + { 167,9016,23876,23876,23880,23880,1943,23889,23893,23911}, + { 175,10740,23928,23928,23932,23940,2165,23949,23953,23968}, + { 182,16957,23974,23974,23978,23978,2530,23988,23992,24012}, + { 176,6940,3133,3133,24035,24047,1357,19520,19524,19524}, + { 177,6998,3160,3160,24057,24064,1724,24070,24074,24090}, + { 178,10513,24104,24104,24108,24114,2235,24130,24134,24149}, + { 183,13986,24190,24190,24194,24194,1462,24206,24210,24210}, + { 164,14758,24229,24229,24233,24238,2396,24249,24253,24264}, + { 192,14323,4639,4639,24284,24291,2373,24299,24303,24321}, + { 187,15389,24338,24338,24342,24347,2445,24353,24357,24370}, + { 201,10686,24388,24388,24392,24404,2161,24414,24418,24434}, + { 190,7572,24452,24452,24456,24465,1748,24480,24484,24500}, + { 191,7039,24528,24528,24532,24539,1564,24546,24550,24563}, + { 202,17015,24577,24577,24581,24581,1462,21138,21142,21152}, + { 193,12081,24593,24593,24597,24597,1357,19520,19524,19524}, + { 185,16559,24606,24606,24610,24610,2511,24619,24623,24642}, + { 197,16658,24661,24661,24665,24671,2517,24678,24682,24694}, + { 198,14898,24712,24712,24716,24725,1357,19520,19524,19854}, + { 200,7183,24737,24737,24741,24749,1635,1635,24758,24771}, + { 271,15198,17503,17503,24785,24792,2423,2423,24805,24819}, + { 203,7239,3313,3313,24832,24839,1639,24852,24856,24870}, + { 204,11512,24902,24902,24906,24906,2204,24913,24917,0}, + { 205,311,24931,24931,24935,24948,1280,24995,24999,25011}, + { 221,7428,25031,25031,25035,25042,1724,25050,25054,25068}, + { 215,13483,25081,25081,25085,25095,1462,25105,25109,25126}, + { 212,7819,25139,25139,25143,25152,1357,19520,19524,25162}, + { 143,7338,25167,25167,25171,25180,1357,19520,19524,19854}, + { 210,15441,25190,25190,25194,25202,2448,20467,20471,20494}, + { 216,11224,5783,5783,25212,25220,2173,25231,25235,25251}, + { 72,16821,3656,3656,25267,25267,1462,21138,21142,21152}, + { 222,15314,25279,25279,25283,25289,2435,25300,25304,25317}, + { 227,7475,3451,3451,25337,3441,1740,1740,25346,25356}, + { 228,8038,25375,25375,25379,25390,1967,25411,25415,25434}, + { 238,9258,25447,25447,25451,25464,1995,1995,25478,25498}, + { 234,14539,25514,25514,25518,25526,2377,25535,25539,25554}, + { 235,7521,25576,25576,25580,25587,1744,25596,25600,25613}, + { 225,15583,25627,25627,25631,25631,1462,25649,25653,25653}, + { 237,6269,25678,25678,25682,25689,1462,25696,25700,25718}, + { 241,7693,3578,3578,25728,25736,1762,25751,25755,25773}, + { 244,6510,25807,25807,25811,25811,1462,21138,21142,21142}, + { 246,16360,25825,25825,25829,25829,1462,25837,25841,25856}, + { 247,9322,4567,4567,25870,25881,2225,25894,25898,25914}, + { 249,14843,25936,25936,25940,25940,2406,25950,25954,25974}, + { 251,8144,25994,25994,25998,26006,1852,26017,26021,26037}, + { 261,15010,26056,26056,26060,26066,2410,26077,26081,26093}, + { 209,8489,26111,26111,26115,0,1892,26128,26132,0}, + { 264,15858,26151,26151,26155,26155,1462,21138,21142,21142} +}; + + +static const RegionInfoNameEntry region_name_entries [] = { + {16310, 0}, /* AE */ + {10632, 1}, /* AF */ + {7384, 2}, /* AL */ + {49, 3}, /* AM */ + {15637, 4}, /* AR */ + {13177, 5}, /* AT */ + {13210, 6}, /* AU */ + {8275, 7}, /* AZ */ + {13740, 8}, /* BA */ + {12712, 9}, /* BD */ + {11869, 10}, /* BE */ + {6175, 11}, /* BG */ + {16467, 12}, /* BH */ + {12592, 13}, /* BN */ + {16734, 14}, /* BO */ + {7088, 15}, /* BR */ + {12439, 16}, /* BW */ + {7763, 17}, /* BY */ + {15344, 18}, /* BZ */ + {13303, 19}, /* CA */ + {15128, 20}, /* CD */ + {314, 21}, /* CH */ + {15976, 22}, /* CI */ + {16159, 23}, /* CL */ + {15689, 24}, /* CM */ + {9975, 25}, /* CN */ + {15062, 26}, /* CO */ + {14042, 27}, /* CR */ + {17119, 28}, /* CU */ + {6331, 29}, /* CZ */ + {6421, 30}, /* DE */ + {6373, 31}, /* DK */ + {14647, 32}, /* DO */ + {13802, 33}, /* DZ */ + {15908, 34}, /* EC */ + {7861, 35}, /* EE */ + {13032, 36}, /* EG */ + {12980, 37}, /* ER */ + {6218, 38}, /* ES */ + {10452, 39}, /* ET */ + {6551, 40}, /* FI */ + {8815, 41}, /* FO */ + {6595, 42}, /* FR */ + {10034, 43}, /* GB */ + {8761, 44}, /* GE */ + {10976, 45}, /* GL */ + {6477, 46}, /* GR */ + {13614, 47}, /* GT */ + {13125, 48}, /* HK */ + {16903, 49}, /* HN */ + {7287, 50}, /* HR */ + {16606, 51}, /* HT */ + {6696, 52}, /* HU */ + {7626, 53}, /* ID */ + {12541, 54}, /* IE */ + {6644, 55}, /* IL */ + {8872, 56}, /* IN */ + {11644, 57}, /* IQ */ + {8086, 58}, /* IR */ + {6745, 59}, /* IS */ + {6788, 60}, /* IT */ + {14789, 61}, /* JM */ + {15542, 62}, /* JO */ + {6833, 63}, /* JP */ + {9198, 64}, /* KE */ + {9155, 65}, /* KG */ + {10100, 66}, /* KH */ + {6888, 67}, /* KR */ + {16081, 68}, /* KW */ + {9086, 69}, /* KZ */ + {10142, 70}, /* LA */ + {15826, 71}, /* LB */ + {13951, 72}, /* LI */ + {10393, 73}, /* LK */ + {7959, 74}, /* LT */ + {10912, 75}, /* LU */ + {7907, 76}, /* LV */ + {13419, 77}, /* LY */ + {14246, 78}, /* MA */ + {14371, 79}, /* MC */ + {12142, 80}, /* MD */ + {15768, 81}, /* ME */ + {8450, 82}, /* MK */ + {16203, 83}, /* ML */ + {10217, 84}, /* MM */ + {9904, 85}, /* MN */ + {13891, 86}, /* MO */ + {8911, 87}, /* MT */ + {11818, 88}, /* MX */ + {9016, 89}, /* MY */ + {10740, 90}, /* NG */ + {16957, 91}, /* NI */ + {6940, 92}, /* NL */ + {6998, 93}, /* NO */ + {10513, 94}, /* NP */ + {13986, 95}, /* NZ */ + {14758, 96}, /* OM */ + {14323, 97}, /* PA */ + {15389, 98}, /* PE */ + {10686, 99}, /* PH */ + {7572, 100}, /* PK */ + {7039, 101}, /* PL */ + {17015, 102}, /* PR */ + {12081, 103}, /* PT */ + {16559, 104}, /* PY */ + {16658, 105}, /* QA */ + {14898, 106}, /* RE */ + {7183, 107}, /* RO */ + {15198, 108}, /* RS */ + {7239, 109}, /* RU */ + {11512, 110}, /* RW */ + {311, 111}, /* SA */ + {7428, 112}, /* SE */ + {13483, 113}, /* SG */ + {7819, 114}, /* SI */ + {7338, 115}, /* SK */ + {15441, 116}, /* SN */ + {11224, 117}, /* SO */ + {16821, 118}, /* SV */ + {15314, 119}, /* SY */ + {7475, 120}, /* TH */ + {8038, 121}, /* TJ */ + {9258, 122}, /* TM */ + {14539, 123}, /* TN */ + {7521, 124}, /* TR */ + {15583, 125}, /* TT */ + {6269, 126}, /* TW */ + {7693, 127}, /* UA */ + {6510, 128}, /* US */ + {16360, 129}, /* UY */ + {9322, 130}, /* UZ */ + {14843, 131}, /* VE */ + {8144, 132}, /* VN */ + {15010, 133}, /* YE */ + {8489, 134}, /* ZA */ + {15858, 135} /* ZW */ +}; + + +static const char locale_strings [] = { + "\0" + "/\0" + ":\0" + "am\0" + "pm\0" + ".\0" + "a. m.\0" + "p. m.\0" + "\xe4\xb8\x8a\xe5\x8d\x88\0" + "\xe4\xb8\x8b\xe5\x8d\x88\0" + "dop.\0" + "odp.\0" + "AM\0" + "PM\0" + "-\0" + "vorm.\0" + "nachm.\0" + "\xcf\x80.\xce\xbc.\0" + "\xce\xbc.\xce\xbc.\0" + "ap.\0" + "ip.\0" + "\xd7\x9c\xd7\xa4\xd7\xa0\xd7\x94\xd7\xb4\xd7\xa6\0" + "\xd7\x90\xd7\x97\xd7\x94\xd7\xb4\xd7\xa6\0" + "de.\0" + "du.\0" + ". \0" + "f.h.\0" + "e.h.\0" + "\xe5\x8d\x88\xe5\x89\x8d\0" + "\xe5\x8d\x88\xe5\xbe\x8c\0" + "\xec\x98\xa4\xec\xa0\x84\0" + "\xec\x98\xa4\xed\x9b\x84\0" + "a.m.\0" + "p.m.\0" + "\xd0\x94\xd0\x9f\0" + "\xd0\x9f\xd0\x9f\0" + "e paradites\0" + "e pasdites\0" + "fm\0" + "em\0" + "\xc3\x96\xc3\x96\0" + "\xc3\x96S\0" + "\xd0\xb4\xd0\xbf\0" + "\xd0\xbf\xd0\xbf\0" + "pop.\0" + "priek\xc5\xa1p.\0" + "p\xc4\x93\x63p.\0" + "prie\xc5\xa1piet\0" + "popiet\0" + "\xd0\xbf\xd0\xb5. \xd1\x87\xd0\xbe.\0" + "\xd0\xbf\xd0\xb0. \xd1\x87\xd0\xbe.\0" + "\xd9\x82.\xd8\xb8.\0" + "\xd8\xa8.\xd8\xb8.\0" + "SA\0" + "CH\0" + "\xd4\xbf\xd4\xb1\0" + "\xd4\xbf\xd5\x80\0" + "dopo\xc5\x82\x64nja\0" + "popo\xc5\x82\x64nju\0" + "\xd0\xbf\xd1\x80\xd0\xb5\xd1\x82\xd0\xbf\xd0\xbb.\0" + "\xd0\xbf\xd0\xbe\xd0\xbf\xd0\xbb.\0" + "vm.\0" + "nm.\0" + "\xe0\xa4\xaa\xe0\xa5\x82\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb9\xe0\xa5\x8d\xe0\xa4\xa8\0" + "\xe0\xa4\x85\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa4\xbe\xe0\xa4\xb9\xe0\xa5\x8d\xe0\xa4\xa8\0" + "i.b.\0" + "e.b.\0" + "PG\0" + "PTG\0" + "\xd1\x82\xd2\xa3\0" + "\xd1\x82\xd0\xba\0" + "TO\0" + "TK\0" + "\xe0\xa8\xaa\xe0\xa9\x82.\xe0\xa8\xa6\xe0\xa9\x81.\0" + "\xe0\xa8\xac\xe0\xa8\xbe.\xe0\xa8\xa6\xe0\xa9\x81.\0" + "\xe0\xae\xae\xe0\xaf\x81\xe0\xae\xb1\xe0\xaf\x8d\xe0\xae\xaa\xe0\xae\x95\xe0\xae\xb2\xe0\xaf\x8d\0" + "\xe0\xae\xaa\xe0\xae\xbf\xe0\xae\xb1\xe0\xaf\x8d\xe0\xae\xaa\xe0\xae\x95\xe0\xae\xb2\xe0\xaf\x8d\0" + "\xe0\xb2\xaa\xe0\xb3\x82\xe0\xb2\xb0\xe0\xb3\x8d\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb9\xe0\xb3\x8d\xe0\xb2\xa8\0" + "\xe0\xb2\x85\xe0\xb2\xaa\xe0\xb2\xb0\xe0\xb2\xbe\xe0\xb2\xb9\xe0\xb3\x8d\xe0\xb2\xa8\0" + "\xe0\xa6\xaa\xe0\xa7\x82\xe0\xa7\xb0\xe0\xa7\x8d\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb9\xe0\xa7\x8d\xe0\xa6\xa3\0" + "\xe0\xa6\x85\xe0\xa6\xaa\xe0\xa7\xb0\xe0\xa6\xbe\xe0\xa6\xb9\xe0\xa7\x8d\xe0\xa6\xa3\0" + "\xe0\xa4\xae.\xe0\xa4\xaa\xe0\xa5\x82.\0" + "\xe0\xa4\xae.\xe0\xa4\x89.\0" + "\xd2\xae\xd3\xa8\0" + "\xd2\xae\xd0\xa5\0" + "\xe0\xbd\xa6\xe0\xbe\x94\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbe\xb2\xe0\xbd\xbc\xe0\xbc\x8b\0" + "\xe0\xbd\x95\xe0\xbe\xb1\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbe\xb2\xe0\xbd\xbc\xe0\xbc\x8b\0" + "yb\0" + "yh\0" + "\xe0\xba\x81\xe0\xbb\x88\xe0\xba\xad\xe0\xba\x99\xe0\xba\x97\xe0\xbb\x88\xe0\xba\xbd\xe0\xba\x87\0" + "\xe0\xba\xab\xe0\xba\xbc\xe0\xba\xb1\xe0\xba\x87\xe0\xba\x97\xe0\xbb\x88\xe0\xba\xbd\xe0\xba\x87\0" + "\xe1\x80\x94\xe1\x80\xb6\xe1\x80\x94\xe1\x80\x80\xe1\x80\xba\0" + "\xe1\x80\x8a\xe1\x80\x94\xe1\x80\xb1\0" + "\xe0\xa4\xae.\xe0\xa4\xa8\xe0\xa4\x82.\0" + "\xe0\xb6\xb4\xe0\xb7\x99.\xe0\xb7\x80.\0" + "\xe0\xb6\xb4.\xe0\xb7\x80.\0" + "\xe1\x8f\x8c\xe1\x8e\xbe\xe1\x8e\xb4\0" + "\xe1\x8f\x92\xe1\x8e\xaf\xe1\x8f\xb1\xe1\x8e\xa2\xe1\x8f\x97\xe1\x8f\xa2\0" + "\xe1\x8c\xa5\xe1\x8b\x8b\xe1\x89\xb5\0" + "\xe1\x8a\xa8\xe1\x88\xb0\xe1\x8b\x93\xe1\x89\xb5\0" + "Zdat azal\0" + "\xe1\xb8\x8c\x65\x66\x66ir aza\0" + "subaka\0" + "kikii\xc9\x97\x65\0" + "\xc3\x80\xc3\xa1r\xe1\xbb\x8d\xcc\x80\0" + "\xe1\xbb\x8c\xcc\x80s\xc3\xa1n\0" + "moies\0" + "nom\xc3\xabttes\0" + "u.t.\0" + "u.k.\0" + "A.M.\0" + "P.M.\0" + "WD\0" + "WB\0" + "\xe1\x8a\x95\xe1\x8c\x89\xe1\x88\x86 \xe1\x88\xb0\xe1\x8b\x93\xe1\x89\xb0\0" + "\xe1\x8b\xb5\xe1\x88\x95\xe1\x88\xad \xe1\x88\xb0\xe1\x8b\x93\xe1\x89\xb5\0" + "sn.\0" + "gn.\0" + "\xea\x8e\xb8\xea\x84\x91\0" + "\xea\x81\xaf\xea\x8b\x92\0" + "G.M.\0" + "\xda\x86.\xd8\xa8\0" + "\xda\x86.\xd9\x83\0" + "v.m.\0" + "n.m.\0" + "\xd0\xad\xd0\x98\0" + "\xd0\xad\xd0\x9a\0" + "m\0" + "f\0" + "\xd8\xb5\0" + "\xd9\x85\0" + "f.m.\0" + "e.m.\0" + "\xd0\x90\xd0\x9c\0" + "\xd0\x9f\xd0\x9c\0" + "w\xc3\xb3tpo\xc5\x82\x64nja\0" + "\xd0\xa2\xd0\x9e\0" + "\xd0\xa2\xd0\x9a\0" + "prijepodne\0" + "popodne\0" + "prije podne\0" + "po podne\0" + "\xd0\xbf\xd1\x80\xd0\xb8\xd1\x98\xd0\xb5 \xd0\xbf\xd0\xbe\xd0\xb4\xd0\xbd\xd0\xb5\0" + "\xd0\xbf\xd0\xbe \xd0\xbf\xd0\xbe\xd0\xb4\xd0\xbd\xd0\xb5\0" + "\xd0\xbf\xd1\x80\xd0\xb5 \xd0\xbf\xd0\xbe\xd0\xb4\xd0\xbd\xd0\xb5\0" + "\xd0\xbf\xd0\xbe\xd0\xbf\xd0\xbe\xd0\xb4\xd0\xbd\xd0\xb5\0" + "pre podne\0" + "ep.\0" + "mat.\0" + "soir\0" + ",\0" + "\xd8\xb1.\xd8\xb3.\xe2\x80\x8f\0" + "\xd9\xaa\xd8\x9c\0" + "\xd9\x84\xd9\x8a\xd8\xb3\xc2\xa0\xd8\xb1\xd9\x82\xd9\x85\0" + "\xd8\x89\0" + "-Infinity\0" + "Infinity\0" + "\xd8\x9c+\0" + "\xc2\xa0\0" + "\xd0\xbb\xd0\xb2.\0" + "%\0" + "NaN\0" + "\xe2\x80\xb0\0" + "+\0" + "\xe2\x82\xac\0" + "-Infinit\0" + "Infinit\0" + "\xc2\xa5\0" + "K\xc4\x8d\0" + "-nekone\xc4\x8dno\0" + "+nekone\xc4\x8dno\0" + "kr.\0" + "-unendlich\0" + "+unendlich\0" + "-\xce\x86\xcf\x80\xce\xb5\xce\xb9\xcf\x81\xce\xbf\0" + "\xce\x86\xcf\x80\xce\xb5\xce\xb9\xcf\x81\xce\xbf\0" + "$\0" + "-Infinito\0" + "Infinito\0" + "ep\xc3\xa4luku\0" + "\xd9\xaa\0" + "-Infini\0" + "+Infini\0" + "\xe2\x82\xaa\0" + "\xe2\x80\x8e+\0" + "Ft\0" + "ISK\0" + "+Infinito\0" + "\xef\xbf\xa5\0" + "\xe2\x82\xa9\0" + "-oneindig\0" + "oneindig\0" + "z\xc5\x82\0" + "-niesko\xc5\x84\x63zono\xc5\x9b\xc4\x87\0" + "+niesko\xc5\x84\x63zono\xc5\x9b\xc4\x87\0" + "R$\0" + "\xe2\x80\x99\0" + "CHF\0" + "-infinit\0" + "+infinit\0" + "RON\0" + "\xe2\x82\xbd\0" + "\xd0\xbd\xd0\xb5\xc2\xa0\xd1\x87\xd0\xb8\xd1\x81\xd0\xbb\xd0\xbe\0" + "-\xd0\xb1\xd0\xb5\xd1\x81\xd0\xba\xd0\xbe\xd0\xbd\xd0\xb5\xd1\x87\xd0\xbd\xd0\xbe\xd1\x81\xd1\x82\xd1\x8c\0" + "\xd0\xb1\xd0\xb5\xd1\x81\xd0\xba\xd0\xbe\xd0\xbd\xd0\xb5\xd1\x87\xd0\xbd\xd0\xbe\xd1\x81\xd1\x82\xd1\x8c\0" + "kn\0" + "Lek\xc3\xab\0" + "kr\0" + "\xc2\xa4\xc2\xa4\xc2\xa4\0" + "\xd8\x89\xe2\x80\x8f\0" + "THB\0" + "\xe2\x82\xba\0" + "Rs\0" + "\xe2\x80\x8e+\xe2\x80\x8e\0" + "Rp\0" + "\xe2\x82\xb4\0" + "Br\0" + "-neskon\xc4\x8dnost\0" + "neskon\xc4\x8dnost\0" + "NS\0" + "-bezgal\xc4\xab\x62\x61\0" + "bezgal\xc4\xab\x62\x61\0" + "-begalyb\xc4\x97\0" + "begalyb\xc4\x97\0" + "\xd8\xb1\xdb\x8c\xd8\xa7\xd9\x84\0" + "\xe2\x82\xab\0" + "\xd6\x8f\0" + "\xd5\x88\xd5\xb9\xd4\xb9\0" + "-Infinitu\0" + "Infinitu\0" + "\xd0\xb4\xd0\xb5\xd0\xbd\0" + "R\0" + "\xe2\x82\xbe\0" + "\xe1\x83\x90\xe1\x83\xa0\xc2\xa0\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x98\xe1\x83\xa1\xc2\xa0\xe1\x83\xa0\xe1\x83\x98\xe1\x83\xaa\xe1\x83\xae\xe1\x83\x95\xe1\x83\x98\0" + "\xe2\x82\xb9\0" + "RM\0" + "\xe2\x82\xb8\0" + "\xd1\x81\xd0\xb0\xd0\xbd\xc2\xa0\xd0\xb5\xd0\xbc\xd0\xb5\xd1\x81\0" + "\xd1\x81\xd0\xbe\xd0\xbc\0" + "\xd1\x81\xd0\xb0\xd0\xbd\xc2\xa0\xd1\x8d\xd0\xbc\xd0\xb5\xd1\x81\0" + "Ksh\0" + "TMT\0" + "san\xc2\xa0\x64\xc3\xa4l\0" + "haqiqiy\xc2\xa0son\xc2\xa0\x65mas\0" + "\xe0\xa6\x9f\xe0\xa6\xbe\0" + "`\0" + "\xc2\xa3\0" + "\xe1\x9f\x9b\0" + "\xe2\x82\xad\0" + "\xe0\xba\x9a\xe0\xbb\x8d\xe0\xbb\x88\xe2\x80\x8b\xe0\xbb\x81\xe0\xba\xa1\xe0\xbb\x88\xe0\xba\x99\xe2\x80\x8b\xe0\xbb\x82\xe0\xba\x95\xe2\x80\x8b\xe0\xbb\x80\xe0\xba\xa5\xe0\xba\x81\0" + "K\0" + "\xe1\x80\x82\xe1\x80\x8f\xe1\x80\x94\xe1\x80\xba\xe1\x80\xb8\xe1\x80\x99\xe1\x80\x9f\xe1\x80\xaf\xe1\x80\x90\xe1\x80\xba\xe1\x80\x9e\xe1\x80\xb1\xe1\x80\xac\0" + "\xe0\xb6\xbb\xe0\xb7\x94.\0" + "\xe1\x89\xa5\xe1\x88\xad\0" + "\xe0\xa4\xb0\xe0\xa5\x81\0" + "\xd8\x8b\0" + "\xe2\x82\xb1\0" + "\xe2\x82\xa6\0" + "Nfk\0" + "S\0" + "\xd1\x87\xd1\x8b\xd1\x8b\xd2\xbb\xd1\x8b\xd0\xbb\xd0\xb0\xc2\xa0\xd0\xb1\xd1\x83\xd0\xbe\xd1\x82\xd0\xb0\xd1\x85\0" + "RF\0" + "\xe9\x9d\x9e\xe6\x95\xb8\xe5\x80\xbc\0" + "HRK\0" + "\xe2\x82\xbc\0" + "so\xca\xbbm\0" + "\xe2\x82\xae\0" + "\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xb0\xe0\xa5\x82\0" + "\xd8\xaf.\xd8\xb9.\xe2\x80\x8f\0" + "'\0" + "L\0" + "P\0" + "\xd1\x81\xd1\x9e\xd0\xbc\0" + "\xd2\xb3\xd0\xb0\xd2\x9b\xd0\xb8\xd2\x9b\xd0\xb8\xd0\xb9\xc2\xa0\xd1\x81\xd0\xbe\xd0\xbd\xc2\xa0\xd1\x8d\xd0\xbc\xd0\xb0\xd1\x81\0" + "\xe0\xa7\xb3\0" + "\xd8\xb1\0" + "Rs.\0" + "\xd8\xac.\xd9\x85.\xe2\x80\x8f\0" + "HK$\0" + "\xd8\xaf.\xd9\x84.\xe2\x80\x8f\0" + "Q\0" + "KM\0" + "\xd8\xaf.\xd8\xac.\xe2\x80\x8f\0" + "MOP$\0" + "\xe2\x82\xa1\0" + "\xd8\xaf.\xd9\x85.\xe2\x80\x8f\0" + "B/.\0" + "\xd8\xaf.\xd8\xaa.\xe2\x80\x8f\0" + "RD$\0" + "\xd0\x9a\xd0\x9c\0" + "\xd8\xb1.\xd8\xb9.\xe2\x80\x8f\0" + "Bs.\0" + "\xd8\xb1.\xd9\x8a.\xe2\x80\x8f\0" + "FC\0" + "RSD\0" + "epiloho\0" + "\xd9\x84.\xd8\xb3.\xe2\x80\x8f\0" + "S/\0" + "CFA\0" + "\xd8\xaf.\xd8\xa3.\xe2\x80\x8f\0" + "FCFA\0" + "\xd9\x84.\xd9\x84.\xe2\x80\x8f\0" + "\xd8\xaf.\xd9\x83.\xe2\x80\x8f\0" + "\xd8\xaf.\xd8\xa5.\xe2\x80\x8f\0" + "MAD\0" + "\xd8\xaf.\xd8\xa8.\xe2\x80\x8f\0" + "Gs.\0" + "G\0" + "\xd8\xb1.\xd9\x82.\xe2\x80\x8f\0" + "Bs\0" + "C$\0" + "\xd0\x94\xd0\xb8\xd0\xbd.\0" + "Din.\0" + "ar\0" + "Arabic\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9\0" + "ARA\0" + "ara\0" + "bg\0" + "Bulgarian\0" + "\xd0\xb1\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd1\x81\xd0\xba\xd0\xb8\0" + "BGR\0" + "bul\0" + "ca\0" + "Catalan\0" + "catal\xc3\xa0\0" + "CAT\0" + "cat\0" + "zh-Hans\0" + "Chinese (Simplified)\0" + "\xe4\xb8\xad\xe6\x96\x87\0" + "CHS\0" + "zho\0" + "zh\0" + "zh-CHS\0" + "Chinese (Simplified) Legacy\0" + "cs\0" + "Czech\0" + "\xc4\x8d\x65\xc5\xa1tina\0" + "CSY\0" + "ces\0" + "da\0" + "Danish\0" + "dansk\0" + "DAN\0" + "dan\0" + "de\0" + "German\0" + "Deutsch\0" + "DEU\0" + "deu\0" + "el\0" + "Greek\0" + "\xce\x95\xce\xbb\xce\xbb\xce\xb7\xce\xbd\xce\xb9\xce\xba\xce\xac\0" + "ELL\0" + "ell\0" + "en\0" + "English\0" + "ENU\0" + "eng\0" + "es\0" + "Spanish\0" + "espa\xc3\xb1ol\0" + "ESP\0" + "spa\0" + "fi\0" + "Finnish\0" + "suomi\0" + "FIN\0" + "fin\0" + "fr\0" + "French\0" + "fran\xc3\xa7\x61is\0" + "FRA\0" + "fra\0" + "he\0" + "Hebrew\0" + "\xd7\xa2\xd7\x91\xd7\xa8\xd7\x99\xd7\xaa\0" + "HEB\0" + "heb\0" + "hu\0" + "Hungarian\0" + "magyar\0" + "HUN\0" + "hun\0" + "is\0" + "Icelandic\0" + "\xc3\xadslenska\0" + "ISL\0" + "isl\0" + "it\0" + "Italian\0" + "italiano\0" + "ITA\0" + "ita\0" + "ja\0" + "Japanese\0" + "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e\0" + "JPN\0" + "jpn\0" + "ko\0" + "Korean\0" + "\xed\x95\x9c\xea\xb5\xad\xec\x96\xb4\0" + "KOR\0" + "kor\0" + "nl\0" + "Dutch\0" + "Nederlands\0" + "NLD\0" + "nld\0" + "no\0" + "Norwegian\0" + "norsk\0" + "NOR\0" + "nob\0" + "nb\0" + "pl\0" + "Polish\0" + "polski\0" + "PLK\0" + "pol\0" + "pt\0" + "Portuguese\0" + "portugu\xc3\xaas\0" + "PTB\0" + "por\0" + "rm\0" + "Romansh\0" + "rumantsch\0" + "RMC\0" + "roh\0" + "ro\0" + "Romanian\0" + "rom\xc3\xa2n\xc4\x83\0" + "ROM\0" + "ron\0" + "ru\0" + "Russian\0" + "\xd1\x80\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9\0" + "RUS\0" + "rus\0" + "hr\0" + "Croatian\0" + "hrvatski\0" + "HRV\0" + "hrv\0" + "sk\0" + "Slovak\0" + "sloven\xc4\x8dina\0" + "SKY\0" + "slk\0" + "sq\0" + "Albanian\0" + "shqip\0" + "SQI\0" + "sqi\0" + "sv\0" + "Swedish\0" + "svenska\0" + "SVE\0" + "swe\0" + "th\0" + "Thai\0" + "\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" + "THA\0" + "tha\0" + "tr\0" + "Turkish\0" + "T\xc3\xbcrk\xc3\xa7\x65\0" + "TRK\0" + "tur\0" + "ur\0" + "Urdu\0" + "\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x88\0" + "URD\0" + "urd\0" + "id\0" + "Indonesian\0" + "Indonesia\0" + "IND\0" + "ind\0" + "uk\0" + "Ukrainian\0" + "\xd1\x83\xd0\xba\xd1\x80\xd0\xb0\xd1\x97\xd0\xbd\xd1\x81\xd1\x8c\xd0\xba\xd0\xb0\0" + "UKR\0" + "ukr\0" + "be\0" + "Belarusian\0" + "\xd0\xb1\xd0\xb5\xd0\xbb\xd0\xb0\xd1\x80\xd1\x83\xd1\x81\xd0\xba\xd0\xb0\xd1\x8f\0" + "BEL\0" + "bel\0" + "sl\0" + "Slovenian\0" + "sloven\xc5\xa1\xc4\x8dina\0" + "SLV\0" + "slv\0" + "et\0" + "Estonian\0" + "eesti\0" + "ETI\0" + "est\0" + "lv\0" + "Latvian\0" + "latvie\xc5\xa1u\0" + "LVI\0" + "lav\0" + "lt\0" + "Lithuanian\0" + "lietuvi\xc5\xb3\0" + "LTH\0" + "lit\0" + "tg\0" + "Tajik\0" + "\xd0\xa2\xd0\xbe\xd2\xb7\xd0\xb8\xd0\xba\xd3\xa3\0" + "TAJ\0" + "tgk\0" + "fa\0" + "Persian\0" + "\xd9\x81\xd8\xa7\xd8\xb1\xd8\xb3\xdb\x8c\0" + "FAR\0" + "fas\0" + "vi\0" + "Vietnamese\0" + "Ti\xe1\xba\xbfng Vi\xe1\xbb\x87t\0" + "VIT\0" + "vie\0" + "hy\0" + "Armenian\0" + "\xd5\xb0\xd5\xa1\xd5\xb5\xd5\xa5\xd6\x80\xd5\xa5\xd5\xb6\0" + "HYE\0" + "hye\0" + "az\0" + "Azerbaijani\0" + "az\xc9\x99rbaycan\0" + "AZE\0" + "aze\0" + "eu\0" + "Basque\0" + "euskara\0" + "EUQ\0" + "eus\0" + "hsb\0" + "Upper Sorbian\0" + "hornjoserb\xc5\xa1\xc4\x87ina\0" + "HSB\0" + "mk\0" + "Macedonian\0" + "\xd0\xbc\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8\0" + "MKI\0" + "mkd\0" + "st\0" + "Southern Sotho\0" + "Sesotho\0" + "SOT\0" + "sot\0" + "ts\0" + "Tsonga\0" + "Xitsonga\0" + "TSO\0" + "tso\0" + "tn\0" + "Tswana\0" + "Setswana\0" + "TSN\0" + "tsn\0" + "xh\0" + "Xhosa\0" + "isiXhosa\0" + "XHO\0" + "xho\0" + "zu\0" + "Zulu\0" + "isiZulu\0" + "ZUL\0" + "zul\0" + "af\0" + "Afrikaans\0" + "AFK\0" + "afr\0" + "ka\0" + "Georgian\0" + "\xe1\x83\xa5\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x97\xe1\x83\xa3\xe1\x83\x9a\xe1\x83\x98\0" + "KAT\0" + "kat\0" + "fo\0" + "Faroese\0" + "f\xc3\xb8royskt\0" + "FOS\0" + "fao\0" + "hi\0" + "Hindi\0" + "\xe0\xa4\xb9\xe0\xa4\xbf\xe0\xa4\xa8\xe0\xa5\x8d\xe0\xa4\xa6\xe0\xa5\x80\0" + "HIN\0" + "hin\0" + "mt\0" + "Maltese\0" + "Malti\0" + "MLT\0" + "mlt\0" + "se\0" + "Northern Sami\0" + "davvis\xc3\xa1megiella\0" + "SME\0" + "sme\0" + "ga\0" + "Irish\0" + "Gaeilge\0" + "IRE\0" + "gle\0" + "ms\0" + "Malay\0" + "Bahasa Melayu\0" + "MSL\0" + "msa\0" + "kk\0" + "Kazakh\0" + "\xd2\x9b\xd0\xb0\xd0\xb7\xd0\xb0\xd2\x9b \xd1\x82\xd1\x96\xd0\xbb\xd1\x96\0" + "KKZ\0" + "kaz\0" + "ky\0" + "Kyrgyz\0" + "\xd0\xba\xd1\x8b\xd1\x80\xd0\xb3\xd1\x8b\xd0\xb7\xd1\x87\xd0\xb0\0" + "KYR\0" + "kir\0" + "sw\0" + "Swahili\0" + "Kiswahili\0" + "SWK\0" + "swa\0" + "tk\0" + "Turkmen\0" + "t\xc3\xbcrkmen\xc3\xa7\x65\0" + "TUK\0" + "tuk\0" + "uz\0" + "Uzbek\0" + "o\xe2\x80\x98zbek\0" + "UZB\0" + "uzb\0" + "bn\0" + "Bangla\0" + "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" + "BNG\0" + "ben\0" + "pa\0" + "Punjabi\0" + "\xe0\xa8\xaa\xe0\xa9\xb0\xe0\xa8\x9c\xe0\xa8\xbe\xe0\xa8\xac\xe0\xa9\x80\0" + "PAN\0" + "pan\0" + "gu\0" + "Gujarati\0" + "\xe0\xaa\x97\xe0\xab\x81\xe0\xaa\x9c\xe0\xaa\xb0\xe0\xaa\xbe\xe0\xaa\xa4\xe0\xab\x80\0" + "GUJ\0" + "guj\0" + "or\0" + "Odia\0" + "\xe0\xac\x93\xe0\xac\xa1\xe0\xac\xbc\xe0\xac\xbf\xe0\xac\x86\0" + "ORI\0" + "ori\0" + "ta\0" + "Tamil\0" + "\xe0\xae\xa4\xe0\xae\xae\xe0\xae\xbf\xe0\xae\xb4\xe0\xaf\x8d\0" + "TAI\0" + "tam\0" + "te\0" + "Telugu\0" + "\xe0\xb0\xa4\xe0\xb1\x86\xe0\xb0\xb2\xe0\xb1\x81\xe0\xb0\x97\xe0\xb1\x81\0" + "TEL\0" + "tel\0" + "Kannada\0" + "\xe0\xb2\x95\xe0\xb2\xa8\xe0\xb3\x8d\xe0\xb2\xa8\xe0\xb2\xa1\0" + "KDI\0" + "kan\0" + "ml\0" + "Malayalam\0" + "\xe0\xb4\xae\xe0\xb4\xb2\xe0\xb4\xaf\xe0\xb4\xbe\xe0\xb4\xb3\xe0\xb4\x82\0" + "MYM\0" + "mal\0" + "as\0" + "Assamese\0" + "\xe0\xa6\x85\xe0\xa6\xb8\xe0\xa6\xae\xe0\xa7\x80\xe0\xa6\xaf\xe0\xa6\xbc\xe0\xa6\xbe\0" + "ASM\0" + "asm\0" + "mr\0" + "Marathi\0" + "\xe0\xa4\xae\xe0\xa4\xb0\xe0\xa4\xbe\xe0\xa4\xa0\xe0\xa5\x80\0" + "MAR\0" + "mar\0" + "mn\0" + "Mongolian\0" + "\xd0\xbc\xd0\xbe\xd0\xbd\xd0\xb3\xd0\xbe\xd0\xbb\0" + "MON\0" + "mon\0" + "bo\0" + "Tibetan\0" + "\xe0\xbd\x96\xe0\xbd\xbc\xe0\xbd\x91\xe0\xbc\x8b\xe0\xbd\xa6\xe0\xbe\x90\xe0\xbd\x91\xe0\xbc\x8b\0" + "BOB\0" + "bod\0" + "cy\0" + "Welsh\0" + "Cymraeg\0" + "CYM\0" + "cym\0" + "km\0" + "Khmer\0" + "\xe1\x9e\x81\xe1\x9f\x92\xe1\x9e\x98\xe1\x9f\x82\xe1\x9e\x9a\0" + "KHM\0" + "khm\0" + "lo\0" + "Lao\0" + "\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7\0" + "LAO\0" + "lao\0" + "my\0" + "Burmese\0" + "\xe1\x80\x99\xe1\x80\xbc\xe1\x80\x94\xe1\x80\xba\xe1\x80\x99\xe1\x80\xac\0" + "MYA\0" + "mya\0" + "gl\0" + "Galician\0" + "galego\0" + "GLC\0" + "glg\0" + "kok\0" + "Konkani\0" + "\xe0\xa4\x95\xe0\xa5\x8b\xe0\xa4\x82\xe0\xa4\x95\xe0\xa4\xa3\xe0\xa5\x80\0" + "KNK\0" + "si\0" + "Sinhala\0" + "\xe0\xb7\x83\xe0\xb7\x92\xe0\xb6\x82\xe0\xb7\x84\xe0\xb6\xbd\0" + "SIN\0" + "sin\0" + "chr\0" + "Cherokee\0" + "\xe1\x8f\xa3\xe1\x8e\xb3\xe1\x8e\xa9\0" + "CRE\0" + "Amharic\0" + "\xe1\x8a\xa0\xe1\x88\x9b\xe1\x88\xad\xe1\x8a\x9b\0" + "AMH\0" + "amh\0" + "tzm\0" + "Central Atlas Tamazight\0" + "Tamazi\xc9\xa3t n la\xe1\xb9\xadla\xe1\xb9\xa3\0" + "TZA\0" + "ne\0" + "Nepali\0" + "\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xb2\xe0\xa5\x80\0" + "NEP\0" + "nep\0" + "fy\0" + "Western Frisian\0" + "West-Frysk\0" + "FYN\0" + "fry\0" + "ps\0" + "Pashto\0" + "\xd9\xbe\xda\x9a\xd8\xaa\xd9\x88\0" + "PAS\0" + "pus\0" + "fil\0" + "Filipino\0" + "FPO\0" + "ff\0" + "Fulah\0" + "Pulaar\0" + "FUL\0" + "ful\0" + "ha\0" + "Hausa\0" + "HAU\0" + "hau\0" + "yo\0" + "Yoruba\0" + "\xc3\x88\x64\xc3\xa8 Yor\xc3\xb9\x62\xc3\xa1\0" + "YOR\0" + "yor\0" + "nso\0" + "Northern Sotho\0" + "Sesotho sa Leboa\0" + "NSO\0" + "lb\0" + "Luxembourgish\0" + "L\xc3\xabtzebuergesch\0" + "LBX\0" + "ltz\0" + "kl\0" + "Kalaallisut\0" + "kalaallisut\0" + "KAL\0" + "kal\0" + "ig\0" + "Igbo\0" + "IBO\0" + "ibo\0" + "om\0" + "Oromo\0" + "Oromoo\0" + "ORM\0" + "orm\0" + "ti\0" + "Tigrinya\0" + "\xe1\x89\xb5\xe1\x8c\x8d\xe1\x88\xad\xe1\x8a\x9b\0" + "TIR\0" + "tir\0" + "haw\0" + "Hawaiian\0" + "\xca\xbb\xc5\x8clelo Hawai\xca\xbbi\0" + "HAW\0" + "so\0" + "Somali\0" + "Soomaali\0" + "SOM\0" + "som\0" + "ii\0" + "Sichuan Yi\0" + "\xea\x86\x88\xea\x8c\xa0\xea\x89\x99\0" + "III\0" + "iii\0" + "br\0" + "Breton\0" + "brezhoneg\0" + "BRE\0" + "bre\0" + "ug\0" + "Uyghur\0" + "\xd8\xa6\xdb\x87\xd9\x8a\xd8\xba\xdb\x87\xd8\xb1\xda\x86\xdb\x95\0" + "UIG\0" + "uig\0" + "gsw\0" + "Swiss German\0" + "Schwiizert\xc3\xbc\xc3\xbctsch\0" + "GSW\0" + "sah\0" + "Sakha\0" + "\xd1\x81\xd0\xb0\xd1\x85\xd0\xb0 \xd1\x82\xd1\x8b\xd0\xbb\xd0\xb0\0" + "SAH\0" + "rw\0" + "Kinyarwanda\0" + "KIN\0" + "kin\0" + "gd\0" + "Scottish Gaelic\0" + "G\xc3\xa0idhlig\0" + "GLA\0" + "gla\0" + "ar-SA\0" + "Arabic (Saudi Arabia)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd9\x85\xd9\x85\xd9\x84\xd9\x83\xd8\xa9 \xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 \xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9)\0" + "bg-BG\0" + "Bulgarian (Bulgaria)\0" + "\xd0\xb1\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd1\x81\xd0\xba\xd0\xb8 (\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd0\xb8\xd1\x8f)\0" + "BG\0" + "ca-ES\0" + "Catalan (Spain)\0" + "catal\xc3\xa0 (Espanya)\0" + "ES\0" + "zh-TW\0" + "Chinese (Traditional)\0" + "\xe4\xb8\xad\xe6\x96\x87 (\xe5\x8f\xb0\xe6\xb9\xbe)\0" + "CHT\0" + "TW\0" + "cs-CZ\0" + "Czech (Czech Republic)\0" + "\xc4\x8d\x65\xc5\xa1tina (\xc4\x8c\x65sk\xc3\xa1 republika)\0" + "CZ\0" + "da-DK\0" + "Danish (Denmark)\0" + "dansk (Danmark)\0" + "DK\0" + "de-DE\0" + "German (Germany)\0" + "Deutsch (Deutschland)\0" + "DE\0" + "el-GR\0" + "Greek (Greece)\0" + "\xce\x95\xce\xbb\xce\xbb\xce\xb7\xce\xbd\xce\xb9\xce\xba\xce\xac (\xce\x95\xce\xbb\xce\xbb\xce\xac\xce\xb4\xce\xb1)\0" + "GR\0" + "en-US\0" + "English (United States)\0" + "US\0" + "fi-FI\0" + "Finnish (Finland)\0" + "suomi (Suomi)\0" + "FI\0" + "fr-FR\0" + "French (France)\0" + "fran\xc3\xa7\x61is (France)\0" + "FR\0" + "he-IL\0" + "Hebrew (Israel)\0" + "\xd7\xa2\xd7\x91\xd7\xa8\xd7\x99\xd7\xaa (\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c)\0" + "IL\0" + "hu-HU\0" + "Hungarian (Hungary)\0" + "magyar (Magyarorsz\xc3\xa1g)\0" + "HU\0" + "is-IS\0" + "Icelandic (Iceland)\0" + "\xc3\xadslenska (\xc3\x8dsland)\0" + "IS\0" + "it-IT\0" + "Italian (Italy)\0" + "italiano (Italia)\0" + "IT\0" + "ja-JP\0" + "Japanese (Japan)\0" + "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (\xe6\x97\xa5\xe6\x9c\xac)\0" + "JP\0" + "ko-KR\0" + "Korean (South Korea)\0" + "\xed\x95\x9c\xea\xb5\xad\xec\x96\xb4 (\xeb\x8c\x80\xed\x95\x9c\xeb\xaf\xbc\xea\xb5\xad)\0" + "KR\0" + "nl-NL\0" + "Dutch (Netherlands)\0" + "Nederlands (Nederland)\0" + "NL\0" + "nb-NO\0" + "Norwegian Bokm\xc3\xa5l (Norway)\0" + "norsk bokm\xc3\xa5l (Norge)\0" + "NO\0" + "pl-PL\0" + "Polish (Poland)\0" + "polski (Polska)\0" + "PL\0" + "pt-BR\0" + "Portuguese (Brazil)\0" + "portugu\xc3\xaas (Brasil)\0" + "BR\0" + "rm-CH\0" + "Romansh (Switzerland)\0" + "rumantsch (Svizra)\0" + "ro-RO\0" + "Romanian (Romania)\0" + "rom\xc3\xa2n\xc4\x83 (Rom\xc3\xa2nia)\0" + "RO\0" + "ru-RU\0" + "Russian (Russia)\0" + "\xd1\x80\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9 (\xd0\xa0\xd0\xbe\xd1\x81\xd1\x81\xd0\xb8\xd1\x8f)\0" + "RU\0" + "hr-HR\0" + "Croatian (Croatia)\0" + "hrvatski (Hrvatska)\0" + "HR\0" + "sk-SK\0" + "Slovak (Slovakia)\0" + "sloven\xc4\x8dina (Slovensko)\0" + "SK\0" + "sq-AL\0" + "Albanian (Albania)\0" + "shqip (Shqip\xc3\xabri)\0" + "AL\0" + "sv-SE\0" + "Swedish (Sweden)\0" + "svenska (Sverige)\0" + "SE\0" + "th-TH\0" + "Thai (Thailand)\0" + "\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2 (\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2)\0" + "TH\0" + "tr-TR\0" + "Turkish (Turkey)\0" + "T\xc3\xbcrk\xc3\xa7\x65 (T\xc3\xbcrkiye)\0" + "TR\0" + "ur-PK\0" + "Urdu (Pakistan)\0" + "\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x88 (\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86)\0" + "PK\0" + "id-ID\0" + "Indonesian (Indonesia)\0" + "Indonesia (Indonesia)\0" + "ID\0" + "uk-UA\0" + "Ukrainian (Ukraine)\0" + "\xd1\x83\xd0\xba\xd1\x80\xd0\xb0\xd1\x97\xd0\xbd\xd1\x81\xd1\x8c\xd0\xba\xd0\xb0 (\xd0\xa3\xd0\xba\xd1\x80\xd0\xb0\xd1\x97\xd0\xbd\xd0\xb0)\0" + "UA\0" + "be-BY\0" + "Belarusian (Belarus)\0" + "\xd0\xb1\xd0\xb5\xd0\xbb\xd0\xb0\xd1\x80\xd1\x83\xd1\x81\xd0\xba\xd0\xb0\xd1\x8f (\xd0\x91\xd0\xb5\xd0\xbb\xd0\xb0\xd1\x80\xd1\x83\xd1\x81\xd1\x8c)\0" + "BY\0" + "sl-SI\0" + "Slovenian (Slovenia)\0" + "sloven\xc5\xa1\xc4\x8dina (Slovenija)\0" + "SI\0" + "et-EE\0" + "Estonian (Estonia)\0" + "eesti (Eesti)\0" + "EE\0" + "lv-LV\0" + "Latvian (Latvia)\0" + "latvie\xc5\xa1u (Latvija)\0" + "LV\0" + "lt-LT\0" + "Lithuanian (Lithuania)\0" + "lietuvi\xc5\xb3 (Lietuva)\0" + "LT\0" + "tg-Cyrl-TJ\0" + "Tajik (Cyrillic, Tajikistan)\0" + "\xd0\xa2\xd0\xbe\xd2\xb7\xd0\xb8\xd0\xba\xd3\xa3 (\xd0\xa2\xd0\xbe\xd2\xb7\xd0\xb8\xd0\xba\xd0\xb8\xd1\x81\xd1\x82\xd0\xbe\xd0\xbd)\0" + "TJ\0" + "fa-IR\0" + "Persian (Iran)\0" + "\xd9\x81\xd8\xa7\xd8\xb1\xd8\xb3\xdb\x8c (\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86)\0" + "IR\0" + "vi-VN\0" + "Vietnamese (Vietnam)\0" + "Ti\xe1\xba\xbfng Vi\xe1\xbb\x87t (Vi\xe1\xbb\x87t Nam)\0" + "VN\0" + "hy-AM\0" + "Armenian (Armenia)\0" + "\xd5\xb0\xd5\xa1\xd5\xb5\xd5\xa5\xd6\x80\xd5\xa5\xd5\xb6 (\xd5\x80\xd5\xa1\xd5\xb5\xd5\xa1\xd5\xbd\xd5\xbf\xd5\xa1\xd5\xb6)\0" + "az-Latn-AZ\0" + "Azerbaijani (Latin, Azerbaijan)\0" + "az\xc9\x99rbaycan (Az\xc9\x99rbaycan)\0" + "AZ\0" + "eu-ES\0" + "Basque (Spain)\0" + "euskara (Espainia)\0" + "hsb-DE\0" + "Upper Sorbian (Germany)\0" + "hornjoserb\xc5\xa1\xc4\x87ina (N\xc4\x9bmska)\0" + "mk-MK\0" + "Macedonian (Macedonia)\0" + "\xd0\xbc\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8 (\xd0\x9c\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd0\xb8\xd1\x98\xd0\xb0)\0" + "MK\0" + "st-ZA\0" + "Southern Sotho (South Africa)\0" + "ZA\0" + "ts-ZA\0" + "Tsonga (South Africa)\0" + "tn-ZA\0" + "Tswana (South Africa)\0" + "xh-ZA\0" + "Xhosa (South Africa)\0" + "zu-ZA\0" + "Zulu (South Africa)\0" + "isiZulu (i-South Africa)\0" + "af-ZA\0" + "Afrikaans (South Africa)\0" + "Afrikaans (Suid-Afrika)\0" + "ka-GE\0" + "Georgian (Georgia)\0" + "\xe1\x83\xa5\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x97\xe1\x83\xa3\xe1\x83\x9a\xe1\x83\x98 (\xe1\x83\xa1\xe1\x83\x90\xe1\x83\xa5\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x97\xe1\x83\x95\xe1\x83\x94\xe1\x83\x9a\xe1\x83\x9d)\0" + "GE\0" + "fo-FO\0" + "Faroese (Faroe Islands)\0" + "f\xc3\xb8royskt (F\xc3\xb8royar)\0" + "FO\0" + "hi-IN\0" + "Hindi (India)\0" + "\xe0\xa4\xb9\xe0\xa4\xbf\xe0\xa4\xa8\xe0\xa5\x8d\xe0\xa4\xa6\xe0\xa5\x80 (\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4)\0" + "IN\0" + "mt-MT\0" + "Maltese (Malta)\0" + "Malti (Malta)\0" + "MT\0" + "se-NO\0" + "Northern Sami (Norway)\0" + "davvis\xc3\xa1megiella (Norga)\0" + "ms-MY\0" + "Malay (Malaysia)\0" + "Bahasa Melayu (Malaysia)\0" + "MY\0" + "kk-KZ\0" + "Kazakh (Kazakhstan)\0" + "\xd2\x9b\xd0\xb0\xd0\xb7\xd0\xb0\xd2\x9b \xd1\x82\xd1\x96\xd0\xbb\xd1\x96 (\xd2\x9a\xd0\xb0\xd0\xb7\xd0\xb0\xd2\x9b\xd1\x81\xd1\x82\xd0\xb0\xd0\xbd)\0" + "KZ\0" + "ky-KG\0" + "Kyrgyz (Kyrgyzstan)\0" + "\xd0\xba\xd1\x8b\xd1\x80\xd0\xb3\xd1\x8b\xd0\xb7\xd1\x87\xd0\xb0 (\xd0\x9a\xd1\x8b\xd1\x80\xd0\xb3\xd1\x8b\xd0\xb7\xd1\x81\xd1\x82\xd0\xb0\xd0\xbd)\0" + "KG\0" + "sw-KE\0" + "Swahili (Kenya)\0" + "Kiswahili (Kenya)\0" + "KE\0" + "tk-TM\0" + "Turkmen (Turkmenistan)\0" + "t\xc3\xbcrkmen\xc3\xa7\x65 (T\xc3\xbcrkmenistan)\0" + "TM\0" + "uz-Latn-UZ\0" + "Uzbek (Latin, Uzbekistan)\0" + "o\xe2\x80\x98zbek (O\xca\xbbzbekiston)\0" + "UZ\0" + "bn-IN\0" + "Bangla (India)\0" + "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe (\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4)\0" + "gu-IN\0" + "Gujarati (India)\0" + "\xe0\xaa\x97\xe0\xab\x81\xe0\xaa\x9c\xe0\xaa\xb0\xe0\xaa\xbe\xe0\xaa\xa4\xe0\xab\x80 (\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4)\0" + "or-IN\0" + "Odia (India)\0" + "\xe0\xac\x93\xe0\xac\xa1\xe0\xac\xbc\xe0\xac\xbf\xe0\xac\x86 (\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4)\0" + "ta-IN\0" + "Tamil (India)\0" + "\xe0\xae\xa4\xe0\xae\xae\xe0\xae\xbf\xe0\xae\xb4\xe0\xaf\x8d (\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe)\0" + "te-IN\0" + "Telugu (India)\0" + "\xe0\xb0\xa4\xe0\xb1\x86\xe0\xb0\xb2\xe0\xb1\x81\xe0\xb0\x97\xe0\xb1\x81 (\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4 \xe0\xb0\xa6\xe0\xb1\x87\xe0\xb0\xb6\xe0\xb0\x82)\0" + "kn-IN\0" + "Kannada (India)\0" + "\xe0\xb2\x95\xe0\xb2\xa8\xe0\xb3\x8d\xe0\xb2\xa8\xe0\xb2\xa1 (\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4)\0" + "ml-IN\0" + "Malayalam (India)\0" + "\xe0\xb4\xae\xe0\xb4\xb2\xe0\xb4\xaf\xe0\xb4\xbe\xe0\xb4\xb3\xe0\xb4\x82 (\xe0\xb4\x87\xe0\xb4\xa8\xe0\xb5\x8d\xe0\xb4\xa4\xe0\xb5\x8d\xe0\xb4\xaf)\0" + "as-IN\0" + "Assamese (India)\0" + "\xe0\xa6\x85\xe0\xa6\xb8\xe0\xa6\xae\xe0\xa7\x80\xe0\xa6\xaf\xe0\xa6\xbc\xe0\xa6\xbe (\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4)\0" + "mr-IN\0" + "Marathi (India)\0" + "\xe0\xa4\xae\xe0\xa4\xb0\xe0\xa4\xbe\xe0\xa4\xa0\xe0\xa5\x80 (\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4)\0" + "mn-MN\0" + "Mongolian (Mongolia)\0" + "\xd0\xbc\xd0\xbe\xd0\xbd\xd0\xb3\xd0\xbe\xd0\xbb (\xd0\x9c\xd0\xbe\xd0\xbd\xd0\xb3\xd0\xbe\xd0\xbb)\0" + "MNN\0" + "MN\0" + "bo-CN\0" + "Tibetan (China)\0" + "\xe0\xbd\x96\xe0\xbd\xbc\xe0\xbd\x91\xe0\xbc\x8b\xe0\xbd\xa6\xe0\xbe\x90\xe0\xbd\x91\xe0\xbc\x8b (\xe0\xbd\xa2\xe0\xbe\x92\xe0\xbe\xb1\xe0\xbc\x8b\xe0\xbd\x93\xe0\xbd\x82)\0" + "CN\0" + "cy-GB\0" + "Welsh (United Kingdom)\0" + "Cymraeg (Y Deyrnas Unedig)\0" + "GB\0" + "km-KH\0" + "Khmer (Cambodia)\0" + "\xe1\x9e\x81\xe1\x9f\x92\xe1\x9e\x98\xe1\x9f\x82\xe1\x9e\x9a (\xe1\x9e\x80\xe1\x9e\x98\xe1\x9f\x92\xe1\x9e\x96\xe1\x9e\xbb\xe1\x9e\x87\xe1\x9e\xb6)\0" + "KH\0" + "lo-LA\0" + "Lao (Laos)\0" + "\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7 (\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7)\0" + "LA\0" + "my-MM\0" + "Burmese (Myanmar (Burma))\0" + "\xe1\x80\x99\xe1\x80\xbc\xe1\x80\x94\xe1\x80\xba\xe1\x80\x99\xe1\x80\xac (\xe1\x80\x99\xe1\x80\xbc\xe1\x80\x94\xe1\x80\xba\xe1\x80\x99\xe1\x80\xac)\0" + "MM\0" + "gl-ES\0" + "Galician (Spain)\0" + "galego (Espa\xc3\xb1\x61)\0" + "kok-IN\0" + "Konkani (India)\0" + "\xe0\xa4\x95\xe0\xa5\x8b\xe0\xa4\x82\xe0\xa4\x95\xe0\xa4\xa3\xe0\xa5\x80 (\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4)\0" + "si-LK\0" + "Sinhala (Sri Lanka)\0" + "\xe0\xb7\x83\xe0\xb7\x92\xe0\xb6\x82\xe0\xb7\x84\xe0\xb6\xbd (\xe0\xb7\x81\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\xe0\xb7\x93 \xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\xe0\xb7\x80)\0" + "LK\0" + "am-ET\0" + "Amharic (Ethiopia)\0" + "\xe1\x8a\xa0\xe1\x88\x9b\xe1\x88\xad\xe1\x8a\x9b (\xe1\x8a\xa2\xe1\x89\xb5\xe1\x8b\xae\xe1\x8c\xb5\xe1\x8b\xab)\0" + "ET\0" + "ne-NP\0" + "Nepali (Nepal)\0" + "\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xb2\xe0\xa5\x80 (\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xb2)\0" + "NP\0" + "fy-NL\0" + "Western Frisian (Netherlands)\0" + "West-Frysk (Nederl\xc3\xa2n)\0" + "ps-AF\0" + "Pashto (Afghanistan)\0" + "\xd9\xbe\xda\x9a\xd8\xaa\xd9\x88 (\xd8\xa7\xd9\x81\xd8\xba\xd8\xa7\xd9\x86\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86)\0" + "AF\0" + "fil-PH\0" + "Filipino (Philippines)\0" + "Filipino (Pilipinas)\0" + "PH\0" + "ha-Latn-NG\0" + "Hausa (Latin, Nigeria)\0" + "Hausa (Najeriya)\0" + "NG\0" + "yo-NG\0" + "Yoruba (Nigeria)\0" + "\xc3\x88\x64\xc3\xa8 Yor\xc3\xb9\x62\xc3\xa1 (Or\xc3\xadl\xe1\xba\xb9\xcc\x81\xc3\xa8\x64\x65 N\xc3\xa0\xc3\xacj\xc3\xadr\xc3\xad\xc3\xa0)\0" + "nso-ZA\0" + "Northern Sotho (South Africa)\0" + "lb-LU\0" + "Luxembourgish (Luxembourg)\0" + "L\xc3\xabtzebuergesch (L\xc3\xabtzebuerg)\0" + "LU\0" + "kl-GL\0" + "Kalaallisut (Greenland)\0" + "kalaallisut (Kalaallit Nunaat)\0" + "GL\0" + "ig-NG\0" + "Igbo (Nigeria)\0" + "om-ET\0" + "Oromo (Ethiopia)\0" + "Oromoo (Itoophiyaa)\0" + "ti-ET\0" + "Tigrinya (Ethiopia)\0" + "\xe1\x89\xb5\xe1\x8c\x8d\xe1\x88\xad\xe1\x8a\x9b (\xe1\x8a\xa2\xe1\x89\xb5\xe1\x8b\xae\xe1\x8c\xb5\xe1\x8b\xab)\0" + "TIE\0" + "haw-US\0" + "Hawaiian (United States)\0" + "\xca\xbb\xc5\x8clelo Hawai\xca\xbbi (\xca\xbb\x41melika Hui P\xc5\xab \xca\xbbIa)\0" + "so-SO\0" + "Somali (Somalia)\0" + "Soomaali (Soomaaliya)\0" + "SO\0" + "ii-CN\0" + "Sichuan Yi (China)\0" + "\xea\x86\x88\xea\x8c\xa0\xea\x89\x99 (\xea\x8d\x8f\xea\x87\xa9)\0" + "br-FR\0" + "Breton (France)\0" + "brezhoneg (Fra\xc3\xb1s)\0" + "ug-CN\0" + "Uyghur (China)\0" + "\xd8\xa6\xdb\x87\xd9\x8a\xd8\xba\xdb\x87\xd8\xb1\xda\x86\xdb\x95 (\xd8\xac\xdb\x87\xda\xad\xda\xaf\xd9\x88)\0" + "gsw-FR\0" + "Swiss German (France)\0" + "Schwiizert\xc3\xbc\xc3\xbctsch (Frankriich)\0" + "sah-RU\0" + "Sakha (Russia)\0" + "\xd1\x81\xd0\xb0\xd1\x85\xd0\xb0 \xd1\x82\xd1\x8b\xd0\xbb\xd0\xb0 (\xd0\x90\xd1\x80\xd0\xb0\xd1\x81\xd1\x81\xd1\x8b\xd1\x8b\xd0\xb9\xd0\xb0)\0" + "rw-RW\0" + "Kinyarwanda (Rwanda)\0" + "RW\0" + "gd-GB\0" + "Scottish Gaelic (United Kingdom)\0" + "G\xc3\xa0idhlig (An R\xc3\xacoghachd Aonaichte)\0" + "ar-IQ\0" + "Arabic (Iraq)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82)\0" + "ARI\0" + "IQ\0" + "ca-ES-valencia\0" + "VAL\0" + "zh-CN\0" + "\xe4\xb8\xad\xe6\x96\x87 (\xe4\xb8\xad\xe5\x9b\xbd)\0" + "de-CH\0" + "German (Switzerland)\0" + "Deutsch (Schweiz)\0" + "DES\0" + "en-GB\0" + "English (United Kingdom)\0" + "ENG\0" + "es-MX\0" + "Spanish (Mexico)\0" + "espa\xc3\xb1ol (M\xc3\xa9xico)\0" + "ESM\0" + "MX\0" + "fr-BE\0" + "French (Belgium)\0" + "fran\xc3\xa7\x61is (Belgique)\0" + "FRB\0" + "BE\0" + "it-CH\0" + "Italian (Switzerland)\0" + "italiano (Svizzera)\0" + "ITS\0" + "nl-BE\0" + "Dutch (Belgium)\0" + "Nederlands (Belgi\xc3\xab)\0" + "NLB\0" + "nn-NO\0" + "Norwegian Nynorsk (Norway)\0" + "nynorsk (Noreg)\0" + "NON\0" + "nno\0" + "nn\0" + "pt-PT\0" + "Portuguese (Portugal)\0" + "portugu\xc3\xaas (Portugal)\0" + "PT\0" + "ro-MD\0" + "Romanian (Moldova)\0" + "rom\xc3\xa2n\xc4\x83 (Republica Moldova)\0" + "ROD\0" + "MD\0" + "ru-MD\0" + "Russian (Moldova)\0" + "\xd1\x80\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9 (\xd0\x9c\xd0\xbe\xd0\xbb\xd0\xb4\xd0\xbe\xd0\xb2\xd0\xb0)\0" + "RUM\0" + "sv-FI\0" + "Swedish (Finland)\0" + "svenska (Finland)\0" + "SVF\0" + "ur-IN\0" + "Urdu (India)\0" + "\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x88 (\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa)\0" + "URI\0" + "az-Cyrl-AZ\0" + "Azerbaijani (Cyrillic, Azerbaijan)\0" + "AZC\0" + "dsb-DE\0" + "Lower Sorbian (Germany)\0" + "dolnoserb\xc5\xa1\xc4\x87ina (Nimska)\0" + "DSB\0" + "dsb\0" + "tn-BW\0" + "Tswana (Botswana)\0" + "TSB\0" + "BW\0" + "se-SE\0" + "Northern Sami (Sweden)\0" + "davvis\xc3\xa1megiella (Ruo\xc5\xa7\xc5\xa7\x61)\0" + "SMF\0" + "ga-IE\0" + "Irish (Ireland)\0" + "Gaeilge (\xc3\x89ire)\0" + "IE\0" + "ms-BN\0" + "Malay (Brunei)\0" + "Bahasa Melayu (Brunei)\0" + "MSB\0" + "BN\0" + "uz-Cyrl-UZ\0" + "Uzbek (Cyrillic, Uzbekistan)\0" + "UZC\0" + "bn-BD\0" + "Bangla (Bangladesh)\0" + "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe (\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\xe0\xa6\xa6\xe0\xa7\x87\xe0\xa6\xb6)\0" + "BNB\0" + "BD\0" + "pa-Arab-PK\0" + "Punjabi (Arabic, Pakistan)\0" + "\xe0\xa8\xaa\xe0\xa9\xb0\xe0\xa8\x9c\xe0\xa8\xbe\xe0\xa8\xac\xe0\xa9\x80 (\xe0\xa8\xaa\xe0\xa8\xbe\xe0\xa8\x95\xe0\xa8\xbf\xe0\xa8\xb8\xe0\xa8\xa4\xe0\xa8\xbe\xe0\xa8\xa8)\0" + "PAP\0" + "ta-LK\0" + "Tamil (Sri Lanka)\0" + "\xe0\xae\xa4\xe0\xae\xae\xe0\xae\xbf\xe0\xae\xb4\xe0\xaf\x8d (\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88)\0" + "TAM\0" + "ne-IN\0" + "Nepali (India)\0" + "\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xb2\xe0\xa5\x80 (\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4)\0" + "NEI\0" + "ti-ER\0" + "Tigrinya (Eritrea)\0" + "\xe1\x89\xb5\xe1\x8c\x8d\xe1\x88\xad\xe1\x8a\x9b (\xe1\x8a\xa4\xe1\x88\xad\xe1\x89\xb5\xe1\x88\xab)\0" + "ER\0" + "ar-EG\0" + "Arabic (Egypt)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd9\x85\xd8\xb5\xd8\xb1)\0" + "ARE\0" + "EG\0" + "zh-HK\0" + "Chinese (Traditional, Hong Kong SAR China)\0" + "\xe4\xb8\xad\xe6\x96\x87 (\xe4\xb8\xad\xe5\x9b\xbd\xe9\xa6\x99\xe6\xb8\xaf\xe7\x89\xb9\xe5\x88\xab\xe8\xa1\x8c\xe6\x94\xbf\xe5\x8c\xba)\0" + "ZHH\0" + "HK\0" + "de-AT\0" + "German (Austria)\0" + "Deutsch (\xc3\x96sterreich)\0" + "DEA\0" + "AT\0" + "en-AU\0" + "English (Australia)\0" + "ENA\0" + "AU\0" + "es-ES\0" + "Spanish (Spain)\0" + "espa\xc3\xb1ol (Espa\xc3\xb1\x61)\0" + "ESN\0" + "fr-CA\0" + "French (Canada)\0" + "fran\xc3\xa7\x61is (Canada)\0" + "FRC\0" + "CA\0" + "se-FI\0" + "Northern Sami (Finland)\0" + "davvis\xc3\xa1megiella (Suopma)\0" + "SMG\0" + "ar-LY\0" + "Arabic (Libya)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd9\x84\xd9\x8a\xd8\xa8\xd9\x8a\xd8\xa7)\0" + "ARL\0" + "LY\0" + "zh-SG\0" + "Chinese (Simplified, Singapore)\0" + "\xe4\xb8\xad\xe6\x96\x87 (\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1)\0" + "ZHI\0" + "SG\0" + "de-LU\0" + "German (Luxembourg)\0" + "Deutsch (Luxemburg)\0" + "DEL\0" + "en-CA\0" + "English (Canada)\0" + "ENC\0" + "es-GT\0" + "Spanish (Guatemala)\0" + "espa\xc3\xb1ol (Guatemala)\0" + "ESG\0" + "GT\0" + "fr-CH\0" + "French (Switzerland)\0" + "fran\xc3\xa7\x61is (Suisse)\0" + "FRS\0" + "hr-BA\0" + "Croatian (Bosnia & Herzegovina)\0" + "hrvatski (Bosna i Hercegovina)\0" + "HRB\0" + "BA\0" + "ar-DZ\0" + "Arabic (Algeria)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1)\0" + "ARG\0" + "DZ\0" + "zh-MO\0" + "Chinese (Traditional, Macau SAR China)\0" + "\xe4\xb8\xad\xe6\x96\x87 (\xe4\xb8\xad\xe5\x9b\xbd\xe6\xbe\xb3\xe9\x97\xa8\xe7\x89\xb9\xe5\x88\xab\xe8\xa1\x8c\xe6\x94\xbf\xe5\x8c\xba)\0" + "ZHM\0" + "MO\0" + "de-LI\0" + "German (Liechtenstein)\0" + "Deutsch (Liechtenstein)\0" + "DEC\0" + "LI\0" + "en-NZ\0" + "English (New Zealand)\0" + "ENZ\0" + "NZ\0" + "es-CR\0" + "Spanish (Costa Rica)\0" + "espa\xc3\xb1ol (Costa Rica)\0" + "ESC\0" + "CR\0" + "fr-LU\0" + "French (Luxembourg)\0" + "fran\xc3\xa7\x61is (Luxembourg)\0" + "FRL\0" + "bs-Latn-BA\0" + "Bosnian (Latin, Bosnia & Herzegovina)\0" + "bosanski (Bosna i Hercegovina)\0" + "BSB\0" + "bos\0" + "bs\0" + "ar-MA\0" + "Arabic (Morocco)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8)\0" + "ARM\0" + "MA\0" + "en-IE\0" + "English (Ireland)\0" + "ENI\0" + "es-PA\0" + "Spanish (Panama)\0" + "espa\xc3\xb1ol (Panam\xc3\xa1)\0" + "ESA\0" + "PA\0" + "fr-MC\0" + "French (Monaco)\0" + "fran\xc3\xa7\x61is (Monaco)\0" + "FRM\0" + "MC\0" + "sr-Latn-BA\0" + "Serbian (Latin, Bosnia & Herzegovina)\0" + "\xd1\x81\xd1\x80\xd0\xbf\xd1\x81\xd0\xba\xd0\xb8 (\xd0\x91\xd0\xbe\xd1\x81\xd0\xbd\xd0\xb0 \xd0\xb8 \xd0\xa5\xd0\xb5\xd1\x80\xd1\x86\xd0\xb5\xd0\xb3\xd0\xbe\xd0\xb2\xd0\xb8\xd0\xbd\xd0\xb0)\0" + "SRS\0" + "srp\0" + "sr\0" + "ar-TN\0" + "Arabic (Tunisia)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3)\0" + "ART\0" + "TN\0" + "en-ZA\0" + "English (South Africa)\0" + "ENS\0" + "es-DO\0" + "Spanish (Dominican Republic)\0" + "espa\xc3\xb1ol (Rep\xc3\xba\x62lica Dominicana)\0" + "ESD\0" + "DO\0" + "sr-Cyrl-BA\0" + "Serbian (Cyrillic, Bosnia & Herzegovina)\0" + "SRN\0" + "ar-OM\0" + "Arabic (Oman)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xb9\xd9\x8f\xd9\x85\xd8\xa7\xd9\x86)\0" + "ARO\0" + "OM\0" + "en-JM\0" + "English (Jamaica)\0" + "ENJ\0" + "JM\0" + "es-VE\0" + "Spanish (Venezuela)\0" + "espa\xc3\xb1ol (Venezuela)\0" + "ESV\0" + "VE\0" + "fr-RE\0" + "French (R\xc3\xa9union)\0" + "fran\xc3\xa7\x61is (La R\xc3\xa9union)\0" + "FRR\0" + "RE\0" + "bs-Cyrl-BA\0" + "Bosnian (Cyrillic, Bosnia & Herzegovina)\0" + "BSC\0" + "ar-YE\0" + "Arabic (Yemen)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86)\0" + "ARY\0" + "YE\0" + "es-CO\0" + "Spanish (Colombia)\0" + "espa\xc3\xb1ol (Colombia)\0" + "ESO\0" + "CO\0" + "fr-CD\0" + "French (Congo - Kinshasa)\0" + "fran\xc3\xa7\x61is (Congo-Kinshasa)\0" + "FRD\0" + "CD\0" + "sr-Latn-RS\0" + "Serbian (Latin, Serbia)\0" + "\xd1\x81\xd1\x80\xd0\xbf\xd1\x81\xd0\xba\xd0\xb8 (\xd0\xa1\xd1\x80\xd0\xb1\xd0\xb8\xd1\x98\xd0\xb0)\0" + "SRM\0" + "RS\0" + "smn-FI\0" + "Inari Sami (Finland)\0" + "anar\xc3\xa2\xc5\xa1kiel\xc3\xa2 (Suom\xc3\xa2)\0" + "SMN\0" + "smn\0" + "ar-SY\0" + "Arabic (Syria)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7)\0" + "ARS\0" + "SY\0" + "en-BZ\0" + "English (Belize)\0" + "ENL\0" + "BZ\0" + "es-PE\0" + "Spanish (Peru)\0" + "espa\xc3\xb1ol (Per\xc3\xba)\0" + "ESR\0" + "PE\0" + "fr-SN\0" + "French (Senegal)\0" + "fran\xc3\xa7\x61is (S\xc3\xa9n\xc3\xa9gal)\0" + "FRN\0" + "SN\0" + "sr-Cyrl-RS\0" + "Serbian (Cyrillic, Serbia)\0" + "SRO\0" + "ar-JO\0" + "Arabic (Jordan)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd8\xa3\xd8\xb1\xd8\xaf\xd9\x86)\0" + "ARJ\0" + "JO\0" + "en-TT\0" + "English (Trinidad & Tobago)\0" + "ENT\0" + "TT\0" + "es-AR\0" + "Spanish (Argentina)\0" + "espa\xc3\xb1ol (Argentina)\0" + "ESS\0" + "AR\0" + "fr-CM\0" + "French (Cameroon)\0" + "fran\xc3\xa7\x61is (Cameroun)\0" + "FRE\0" + "CM\0" + "sr-Latn-ME\0" + "Serbian (Latin, Montenegro)\0" + "\xd1\x81\xd1\x80\xd0\xbf\xd1\x81\xd0\xba\xd0\xb8 (\xd0\xa6\xd1\x80\xd0\xbd\xd0\xb0 \xd0\x93\xd0\xbe\xd1\x80\xd0\xb0)\0" + "SRP\0" + "ME\0" + "ar-LB\0" + "Arabic (Lebanon)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd9\x84\xd8\xa8\xd9\x86\xd8\xa7\xd9\x86)\0" + "ARB\0" + "LB\0" + "en-ZW\0" + "English (Zimbabwe)\0" + "ENW\0" + "ZW\0" + "es-EC\0" + "Spanish (Ecuador)\0" + "espa\xc3\xb1ol (Ecuador)\0" + "ESF\0" + "EC\0" + "fr-CI\0" + "French (C\xc3\xb4te d\xe2\x80\x99Ivoire)\0" + "fran\xc3\xa7\x61is (C\xc3\xb4te d\xe2\x80\x99Ivoire)\0" + "FRI\0" + "CI\0" + "sr-Cyrl-ME\0" + "Serbian (Cyrillic, Montenegro)\0" + "SRQ\0" + "ar-KW\0" + "Arabic (Kuwait)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd9\x83\xd9\x88\xd9\x8a\xd8\xaa)\0" + "ARK\0" + "KW\0" + "en-PH\0" + "English (Philippines)\0" + "ENP\0" + "es-CL\0" + "Spanish (Chile)\0" + "espa\xc3\xb1ol (Chile)\0" + "ESL\0" + "CL\0" + "fr-ML\0" + "French (Mali)\0" + "fran\xc3\xa7\x61is (Mali)\0" + "FRF\0" + "ML\0" + "ar-AE\0" + "Arabic (United Arab Emirates)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd8\xa5\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa \xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 \xd8\xa7\xd9\x84\xd9\x85\xd8\xaa\xd8\xad\xd8\xaf\xd8\xa9)\0" + "ARU\0" + "AE\0" + "es-UY\0" + "Spanish (Uruguay)\0" + "espa\xc3\xb1ol (Uruguay)\0" + "ESY\0" + "UY\0" + "fr-MA\0" + "French (Morocco)\0" + "fran\xc3\xa7\x61is (Maroc)\0" + "FRO\0" + "ar-BH\0" + "Arabic (Bahrain)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd8\xa8\xd8\xad\xd8\xb1\xd9\x8a\xd9\x86)\0" + "ARH\0" + "BH\0" + "en-HK\0" + "English (Hong Kong SAR China)\0" + "ENH\0" + "es-PY\0" + "Spanish (Paraguay)\0" + "espa\xc3\xb1ol (Paraguay)\0" + "ESZ\0" + "PY\0" + "fr-HT\0" + "French (Haiti)\0" + "fran\xc3\xa7\x61is (Ha\xc3\xafti)\0" + "FRH\0" + "HT\0" + "ar-QA\0" + "Arabic (Qatar)\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd9\x82\xd8\xb7\xd8\xb1)\0" + "ARQ\0" + "QA\0" + "en-IN\0" + "English (India)\0" + "ENN\0" + "es-BO\0" + "Spanish (Bolivia)\0" + "espa\xc3\xb1ol (Bolivia)\0" + "ESB\0" + "BO\0" + "en-MY\0" + "English (Malaysia)\0" + "ENM\0" + "es-SV\0" + "Spanish (El Salvador)\0" + "espa\xc3\xb1ol (El Salvador)\0" + "ESE\0" + "SV\0" + "en-SG\0" + "English (Singapore)\0" + "ENE\0" + "es-HN\0" + "Spanish (Honduras)\0" + "espa\xc3\xb1ol (Honduras)\0" + "ESH\0" + "HN\0" + "es-NI\0" + "Spanish (Nicaragua)\0" + "espa\xc3\xb1ol (Nicaragua)\0" + "ESI\0" + "NI\0" + "es-PR\0" + "Spanish (Puerto Rico)\0" + "espa\xc3\xb1ol (Puerto Rico)\0" + "ESU\0" + "PR\0" + "es-US\0" + "Spanish (United States)\0" + "espa\xc3\xb1ol (Estados Unidos)\0" + "EST\0" + "es-CU\0" + "Spanish (Cuba)\0" + "espa\xc3\xb1ol (Cuba)\0" + "ESK\0" + "CU\0" + "bs-Cyrl\0" + "Bosnian (Cyrillic)\0" + "bosanski\0" + "bs-Latn\0" + "Bosnian (Latin)\0" + "sr-Cyrl\0" + "Serbian (Cyrillic)\0" + "\xd1\x81\xd1\x80\xd0\xbf\xd1\x81\xd0\xba\xd0\xb8\0" + "sr-Latn\0" + "Serbian (Latin)\0" + "Inari Sami\0" + "anar\xc3\xa2\xc5\xa1kiel\xc3\xa2\0" + "az-Cyrl\0" + "Azerbaijani (Cyrillic)\0" + "Norwegian Nynorsk\0" + "nynorsk\0" + "Bosnian\0" + "az-Latn\0" + "Azerbaijani (Latin)\0" + "uz-Cyrl\0" + "Uzbek (Cyrillic)\0" + "mn-Cyrl\0" + "Mongolian (Cyrillic)\0" + "zh-Hant\0" + "zh-CHT\0" + "Chinese (Traditional) Legacy\0" + "Norwegian Bokm\xc3\xa5l\0" + "norsk bokm\xc3\xa5l\0" + "Serbian\0" + "SRB\0" + "tg-Cyrl\0" + "Tajik (Cyrillic)\0" + "Lower Sorbian\0" + "dolnoserb\xc5\xa1\xc4\x87ina\0" + "uz-Latn\0" + "Uzbek (Latin)\0" + "pa-Arab\0" + "Punjabi (Arabic)\0" + "tzm-Latn\0" + "Central Atlas Tamazight (Latin)\0" + "ha-Latn\0" + "Hausa (Latin)\0" + "af-za\0" + "am-et\0" + "ar-ae\0" + "ar-bh\0" + "ar-dz\0" + "ar-eg\0" + "ar-iq\0" + "ar-jo\0" + "ar-kw\0" + "ar-lb\0" + "ar-ly\0" + "ar-ma\0" + "ar-om\0" + "ar-qa\0" + "ar-sa\0" + "ar-sy\0" + "ar-tn\0" + "ar-ye\0" + "as-in\0" + "az-cyrl\0" + "az-cyrl-az\0" + "az-latn\0" + "az-latn-az\0" + "be-by\0" + "bg-bg\0" + "bn-bd\0" + "bn-in\0" + "bo-cn\0" + "br-fr\0" + "bs-cyrl\0" + "bs-cyrl-ba\0" + "bs-latn\0" + "bs-latn-ba\0" + "ca-es\0" + "ca-es-valencia\0" + "cs-cz\0" + "cy-gb\0" + "da-dk\0" + "de-at\0" + "de-ch\0" + "de-de\0" + "de-li\0" + "de-lu\0" + "dsb-de\0" + "el-gr\0" + "en-au\0" + "en-bz\0" + "en-ca\0" + "en-gb\0" + "en-hk\0" + "en-ie\0" + "en-in\0" + "en-jm\0" + "en-my\0" + "en-nz\0" + "en-ph\0" + "en-sg\0" + "en-tt\0" + "en-us\0" + "en-za\0" + "en-zw\0" + "es-ar\0" + "es-bo\0" + "es-cl\0" + "es-co\0" + "es-cr\0" + "es-cu\0" + "es-do\0" + "es-ec\0" + "es-es\0" + "es-gt\0" + "es-hn\0" + "es-mx\0" + "es-ni\0" + "es-pa\0" + "es-pe\0" + "es-pr\0" + "es-py\0" + "es-sv\0" + "es-us\0" + "es-uy\0" + "es-ve\0" + "et-ee\0" + "eu-es\0" + "fa-ir\0" + "fi-fi\0" + "fil-ph\0" + "fo-fo\0" + "fr-be\0" + "fr-ca\0" + "fr-cd\0" + "fr-ch\0" + "fr-ci\0" + "fr-cm\0" + "fr-fr\0" + "fr-ht\0" + "fr-lu\0" + "fr-ma\0" + "fr-mc\0" + "fr-ml\0" + "fr-re\0" + "fr-sn\0" + "fy-nl\0" + "ga-ie\0" + "gd-gb\0" + "gl-es\0" + "gsw-fr\0" + "gu-in\0" + "ha-latn\0" + "ha-latn-ng\0" + "haw-us\0" + "he-il\0" + "hi-in\0" + "hr-ba\0" + "hr-hr\0" + "hsb-de\0" + "hu-hu\0" + "hy-am\0" + "id-id\0" + "ig-ng\0" + "ii-cn\0" + "is-is\0" + "it-ch\0" + "it-it\0" + "ja-jp\0" + "ka-ge\0" + "kk-kz\0" + "kl-gl\0" + "km-kh\0" + "kn-in\0" + "ko-kr\0" + "kok-in\0" + "ky-kg\0" + "lb-lu\0" + "lo-la\0" + "lt-lt\0" + "lv-lv\0" + "mk-mk\0" + "ml-in\0" + "mn-cyrl\0" + "mn-mn\0" + "mr-in\0" + "ms-bn\0" + "ms-my\0" + "mt-mt\0" + "my-mm\0" + "nb-no\0" + "ne-in\0" + "ne-np\0" + "nl-be\0" + "nl-nl\0" + "nn-no\0" + "nso-za\0" + "om-et\0" + "or-in\0" + "pa-arab\0" + "pa-arab-pk\0" + "pl-pl\0" + "ps-af\0" + "pt-br\0" + "pt-pt\0" + "rm-ch\0" + "ro-md\0" + "ro-ro\0" + "ru-md\0" + "ru-ru\0" + "rw-rw\0" + "sah-ru\0" + "se-fi\0" + "se-no\0" + "se-se\0" + "si-lk\0" + "sk-sk\0" + "sl-si\0" + "smn-fi\0" + "so-so\0" + "sq-al\0" + "sr-cyrl\0" + "sr-cyrl-ba\0" + "sr-cyrl-me\0" + "sr-cyrl-rs\0" + "sr-latn\0" + "sr-latn-ba\0" + "sr-latn-me\0" + "sr-latn-rs\0" + "st-za\0" + "sv-fi\0" + "sv-se\0" + "sw-ke\0" + "ta-in\0" + "ta-lk\0" + "te-in\0" + "tg-cyrl\0" + "tg-cyrl-tj\0" + "th-th\0" + "ti-er\0" + "ti-et\0" + "tk-tm\0" + "tn-bw\0" + "tn-za\0" + "tr-tr\0" + "ts-za\0" + "tzm-latn\0" + "ug-cn\0" + "uk-ua\0" + "ur-in\0" + "ur-pk\0" + "uz-cyrl\0" + "uz-cyrl-uz\0" + "uz-latn\0" + "uz-latn-uz\0" + "vi-vn\0" + "xh-za\0" + "yo-ng\0" + "zh-chs\0" + "zh-cht\0" + "zh-cn\0" + "zh-hans\0" + "zh-hant\0" + "zh-hk\0" + "zh-mo\0" + "zh-sg\0" + "zh-tw\0" + "zu-za\0" + "United Arab Emirates\0" + "\xd8\xa7\xd9\x84\xd8\xa5\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa \xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 \xd8\xa7\xd9\x84\xd9\x85\xd8\xaa\xd8\xad\xd8\xaf\xd8\xa9\0" + "AED\0" + "United Arab Emirates Dirham\0" + "\xd8\xaf\xd8\xb1\xd9\x87\xd9\x85 \xd8\xa5\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\xd9\x8a\0" + "AFG\0" + "Afghanistan\0" + "\xd8\xa7\xd9\x81\xd8\xba\xd8\xa7\xd9\x86\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" + "AFN\0" + "Afghan Afghani\0" + "\xd8\xa7\xd9\x81\xd8\xba\xd8\xa7\xd9\x86\xdb\x8d\0" + "ALB\0" + "Albania\0" + "Shqip\xc3\xabri\0" + "ALL\0" + "Albanian Lek\0" + "Leku shqiptar\0" + "Armenia\0" + "\xd5\x80\xd5\xa1\xd5\xb5\xd5\xa1\xd5\xbd\xd5\xbf\xd5\xa1\xd5\xb6\0" + "AMD\0" + "Armenian Dram\0" + "\xd5\x80\xd5\xa1\xd5\xb5\xd5\xaf\xd5\xa1\xd5\xaf\xd5\xa1\xd5\xb6 \xd5\xa4\xd6\x80\xd5\xa1\xd5\xb4\0" + "Argentina\0" + "Argentine Peso\0" + "peso argentino\0" + "AUT\0" + "Austria\0" + "\xc3\x96sterreich\0" + "EUR\0" + "Euro\0" + "AUS\0" + "Australia\0" + "AUD\0" + "Australian Dollar\0" + "Azerbaijan\0" + "Az\xc9\x99rbaycan\0" + "AZN\0" + "Azerbaijani Manat\0" + "Az\xc9\x99rbaycan Manat\xc4\xb1\0" + "BIH\0" + "Bosnia & Herzegovina\0" + "Bosna i Hercegovina\0" + "BAM\0" + "Bosnia-Herzegovina Convertible Mark\0" + "konvertibilna marka\0" + "BGD\0" + "Bangladesh\0" + "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\xe0\xa6\xa6\xe0\xa7\x87\xe0\xa6\xb6\0" + "BDT\0" + "Bangladeshi Taka\0" + "\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\xe0\xa6\xa6\xe0\xa7\x87\xe0\xa6\xb6\xe0\xa7\x80 \xe0\xa6\x9f\xe0\xa6\xbe\xe0\xa6\x95\xe0\xa6\xbe\0" + "Belgium\0" + "Belgique\0" + "euro\0" + "Bulgaria\0" + "\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd0\xb8\xd1\x8f\0" + "BGN\0" + "Bulgarian Lev\0" + "\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd1\x81\xd0\xba\xd0\xb8 \xd0\xbb\xd0\xb5\xd0\xb2\0" + "BHR\0" + "Bahrain\0" + "\xd8\xa7\xd9\x84\xd8\xa8\xd8\xad\xd8\xb1\xd9\x8a\xd9\x86\0" + "BHD\0" + "Bahraini Dinar\0" + "\xd8\xaf\xd9\x8a\xd9\x86\xd8\xa7\xd8\xb1 \xd8\xa8\xd8\xad\xd8\xb1\xd9\x8a\xd9\x86\xd9\x8a\0" + "BRN\0" + "Brunei\0" + "BND\0" + "Brunei Dollar\0" + "Dolar Brunei\0" + "BOL\0" + "Bolivia\0" + "Bolivian Boliviano\0" + "boliviano\0" + "BRA\0" + "Brazil\0" + "Brasil\0" + "BRL\0" + "Brazilian Real\0" + "Real brasileiro\0" + "BWA\0" + "Botswana\0" + "BWP\0" + "Botswanan Pula\0" + "BLR\0" + "Belarus\0" + "\xd0\x91\xd0\xb5\xd0\xbb\xd0\xb0\xd1\x80\xd1\x83\xd1\x81\xd1\x8c\0" + "BYN\0" + "Belarusian Ruble\0" + "\xd0\xb1\xd0\xb5\xd0\xbb\xd0\xb0\xd1\x80\xd1\x83\xd1\x81\xd0\xba\xd1\x96 \xd1\x80\xd1\x83\xd0\xb1\xd0\xb5\xd0\xbb\xd1\x8c\0" + "BLZ\0" + "Belize\0" + "BZD\0" + "Belize Dollar\0" + "CAN\0" + "Canada\0" + "CAD\0" + "Canadian Dollar\0" + "dollar canadien\0" + "COD\0" + "Congo - Kinshasa\0" + "Congo-Kinshasa\0" + "CDF\0" + "Congolese Franc\0" + "franc congolais\0" + "CHE\0" + "Switzerland\0" + "Svizra\0" + "Swiss Franc\0" + "franc svizzer\0" + "CIV\0" + "C\xc3\xb4te d\xe2\x80\x99Ivoire\0" + "XOF\0" + "West African CFA Franc\0" + "franc CFA (BCEAO)\0" + "CHL\0" + "Chile\0" + "CLP\0" + "Chilean Peso\0" + "Peso chileno\0" + "CMR\0" + "Cameroon\0" + "Cameroun\0" + "XAF\0" + "Central African CFA Franc\0" + "franc CFA (BEAC)\0" + "CHN\0" + "China\0" + "\xe0\xbd\xa2\xe0\xbe\x92\xe0\xbe\xb1\xe0\xbc\x8b\xe0\xbd\x93\xe0\xbd\x82\0" + "CNY\0" + "Chinese Yuan\0" + "\xe0\xbd\xa1\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\xa8\xe0\xbd\x93\xe0\xbc\x8b\0" + "COL\0" + "Colombia\0" + "COP\0" + "Colombian Peso\0" + "peso colombiano\0" + "CRI\0" + "Costa Rica\0" + "CRC\0" + "Costa Rican Col\xc3\xb3n\0" + "col\xc3\xb3n costarricense\0" + "CUB\0" + "Cuba\0" + "CUP\0" + "Cuban Peso\0" + "peso cubano\0" + "CZE\0" + "Czech Republic\0" + "\xc4\x8c\x65sk\xc3\xa1 republika\0" + "CZK\0" + "Czech Republic Koruna\0" + "\xc4\x8d\x65sk\xc3\xa1 koruna\0" + "Germany\0" + "Deutschland\0" + "DNK\0" + "Denmark\0" + "Danmark\0" + "DKK\0" + "Danish Krone\0" + "dansk krone\0" + "DOM\0" + "Dominican Republic\0" + "Rep\xc3\xba\x62lica Dominicana\0" + "DOP\0" + "Dominican Peso\0" + "peso dominicano\0" + "DZA\0" + "Algeria\0" + "\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" + "DZD\0" + "Algerian Dinar\0" + "\xd8\xaf\xd9\x8a\xd9\x86\xd8\xa7\xd8\xb1 \xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\xd9\x8a\0" + "ECU\0" + "Ecuador\0" + "USD\0" + "US Dollar\0" + "d\xc3\xb3lar estadounidense\0" + "Estonia\0" + "Eesti\0" + "EGY\0" + "Egypt\0" + "\xd9\x85\xd8\xb5\xd8\xb1\0" + "EGP\0" + "Egyptian Pound\0" + "\xd8\xac\xd9\x86\xd9\x8a\xd9\x87 \xd9\x85\xd8\xb5\xd8\xb1\xd9\x8a\0" + "ERI\0" + "Eritrea\0" + "\xe1\x8a\xa4\xe1\x88\xad\xe1\x89\xb5\xe1\x88\xab\0" + "ERN\0" + "Eritrean Nakfa\0" + "Spain\0" + "Espanya\0" + "ETH\0" + "Ethiopia\0" + "\xe1\x8a\xa2\xe1\x89\xb5\xe1\x8b\xae\xe1\x8c\xb5\xe1\x8b\xab\0" + "ETB\0" + "Ethiopian Birr\0" + "\xe1\x8b\xa8\xe1\x8a\xa2\xe1\x89\xb5\xe1\x8b\xae\xe1\x8c\xb5\xe1\x8b\xab \xe1\x89\xa5\xe1\x88\xad\0" + "Finland\0" + "Suomi\0" + "Faroe Islands\0" + "F\xc3\xb8royar\0" + "donsk kr\xc3\xb3na\0" + "France\0" + "GBR\0" + "United Kingdom\0" + "Y Deyrnas Unedig\0" + "GBP\0" + "British Pound\0" + "Punt Prydain\0" + "GEO\0" + "Georgia\0" + "\xe1\x83\xa1\xe1\x83\x90\xe1\x83\xa5\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x97\xe1\x83\x95\xe1\x83\x94\xe1\x83\x9a\xe1\x83\x9d\0" + "GEL\0" + "Georgian Lari\0" + "\xe1\x83\xa5\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x97\xe1\x83\xa3\xe1\x83\x9a\xe1\x83\x98 \xe1\x83\x9a\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x98\0" + "GRL\0" + "Greenland\0" + "Kalaallit Nunaat\0" + "danmarkimut koruuni\0" + "GRC\0" + "Greece\0" + "\xce\x95\xce\xbb\xce\xbb\xce\xac\xce\xb4\xce\xb1\0" + "\xce\x95\xcf\x85\xcf\x81\xcf\x8e\0" + "GTM\0" + "Guatemala\0" + "GTQ\0" + "Guatemalan Quetzal\0" + "quetzal\0" + "HKG\0" + "Hong Kong SAR China\0" + "\xe4\xb8\xad\xe5\x9b\xbd\xe9\xa6\x99\xe6\xb8\xaf\xe7\x89\xb9\xe5\x88\xab\xe8\xa1\x8c\xe6\x94\xbf\xe5\x8c\xba\0" + "HKD\0" + "Hong Kong Dollar\0" + "\xe6\xb8\xaf\xe5\x85\x83\0" + "HND\0" + "Honduras\0" + "HNL\0" + "Honduran Lempira\0" + "lempira hondure\xc3\xb1o\0" + "Croatia\0" + "Hrvatska\0" + "Croatian Kuna\0" + "hrvatska kuna\0" + "HTI\0" + "Haiti\0" + "Ha\xc3\xafti\0" + "HTG\0" + "Haitian Gourde\0" + "gourde ha\xc3\xaftienne\0" + "Hungary\0" + "Magyarorsz\xc3\xa1g\0" + "HUF\0" + "Hungarian Forint\0" + "magyar forint\0" + "IDN\0" + "IDR\0" + "Indonesian Rupiah\0" + "Rupiah Indonesia\0" + "IRL\0" + "Ireland\0" + "\xc3\x89ire\0" + "ISR\0" + "Israel\0" + "\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0" + "ILS\0" + "Israeli New Shekel\0" + "\xd7\xa9\xd7\xa7\xd7\x9c \xd7\x97\xd7\x93\xd7\xa9\0" + "India\0" + "\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0" + "INR\0" + "Indian Rupee\0" + "\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa5\x80\xe0\xa4\xaf \xe0\xa4\xb0\xe0\xa5\x81\xe0\xa4\xaa\xe0\xa4\xaf\xe0\xa4\xbe\0" + "IRQ\0" + "Iraq\0" + "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" + "IQD\0" + "Iraqi Dinar\0" + "\xd8\xaf\xd9\x8a\xd9\x86\xd8\xa7\xd8\xb1 \xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\xd9\x8a\0" + "IRN\0" + "Iran\0" + "\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" + "IRR\0" + "Iranian Rial\0" + "\xd8\xb1\xdb\x8c\xd8\xa7\xd9\x84 \xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" + "Iceland\0" + "\xc3\x8dsland\0" + "Icelandic Kr\xc3\xb3na\0" + "\xc3\xadslensk kr\xc3\xb3na\0" + "Italy\0" + "Italia\0" + "JAM\0" + "Jamaica\0" + "JMD\0" + "Jamaican Dollar\0" + "JOR\0" + "Jordan\0" + "\xd8\xa7\xd9\x84\xd8\xa3\xd8\xb1\xd8\xaf\xd9\x86\0" + "JOD\0" + "Jordanian Dinar\0" + "\xd8\xaf\xd9\x8a\xd9\x86\xd8\xa7\xd8\xb1 \xd8\xa3\xd8\xb1\xd8\xaf\xd9\x86\xd9\x8a\0" + "Japan\0" + "\xe6\x97\xa5\xe6\x9c\xac\0" + "JPY\0" + "Japanese Yen\0" + "\xe6\x97\xa5\xe6\x9c\xac\xe5\x86\x86\0" + "KEN\0" + "Kenya\0" + "KES\0" + "Kenyan Shilling\0" + "Shilingi ya Kenya\0" + "KGZ\0" + "Kyrgyzstan\0" + "\xd0\x9a\xd1\x8b\xd1\x80\xd0\xb3\xd1\x8b\xd0\xb7\xd1\x81\xd1\x82\xd0\xb0\xd0\xbd\0" + "KGS\0" + "Kyrgystani Som\0" + "\xd0\x9a\xd1\x8b\xd1\x80\xd0\xb3\xd1\x8b\xd0\xb7\xd1\x81\xd1\x82\xd0\xb0\xd0\xbd \xd1\x81\xd0\xbe\xd0\xbc\xd1\x83\0" + "Cambodia\0" + "\xe1\x9e\x80\xe1\x9e\x98\xe1\x9f\x92\xe1\x9e\x96\xe1\x9e\xbb\xe1\x9e\x87\xe1\x9e\xb6\0" + "KHR\0" + "Cambodian Riel\0" + "\xe1\x9e\x9a\xe1\x9f\x80\xe1\x9e\x9b\xe2\x80\x8b\xe1\x9e\x80\xe1\x9e\x98\xe1\x9f\x92\xe1\x9e\x96\xe1\x9e\xbb\xe1\x9e\x87\xe1\x9e\xb6\0" + "South Korea\0" + "\xeb\x8c\x80\xed\x95\x9c\xeb\xaf\xbc\xea\xb5\xad\0" + "KRW\0" + "South Korean Won\0" + "\xeb\x8c\x80\xed\x95\x9c\xeb\xaf\xbc\xea\xb5\xad \xec\x9b\x90\0" + "KWT\0" + "Kuwait\0" + "\xd8\xa7\xd9\x84\xd9\x83\xd9\x88\xd9\x8a\xd8\xaa\0" + "KWD\0" + "Kuwaiti Dinar\0" + "\xd8\xaf\xd9\x8a\xd9\x86\xd8\xa7\xd8\xb1 \xd9\x83\xd9\x88\xd9\x8a\xd8\xaa\xd9\x8a\0" + "KAZ\0" + "Kazakhstan\0" + "\xd2\x9a\xd0\xb0\xd0\xb7\xd0\xb0\xd2\x9b\xd1\x81\xd1\x82\xd0\xb0\xd0\xbd\0" + "KZT\0" + "Kazakhstani Tenge\0" + "\xd2\x9a\xd0\xb0\xd0\xb7\xd0\xb0\xd2\x9b\xd1\x81\xd1\x82\xd0\xb0\xd0\xbd \xd1\x82\xd0\xb5\xd2\xa3\xd0\xb3\xd0\xb5\xd1\x81\xd1\x96\0" + "Laos\0" + "LAK\0" + "Laotian Kip\0" + "\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7 \xe0\xba\x81\xe0\xba\xb5\xe0\xba\x9a\0" + "LBN\0" + "Lebanon\0" + "\xd9\x84\xd8\xa8\xd9\x86\xd8\xa7\xd9\x86\0" + "LBP\0" + "Lebanese Pound\0" + "\xd8\xac\xd9\x86\xd9\x8a\xd9\x87 \xd9\x84\xd8\xa8\xd9\x86\xd8\xa7\xd9\x86\xd9\x8a\0" + "LIE\0" + "Liechtenstein\0" + "Schweizer Franken\0" + "LKA\0" + "Sri Lanka\0" + "\xe0\xb7\x81\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\xe0\xb7\x93 \xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\xe0\xb7\x80\0" + "LKR\0" + "Sri Lankan Rupee\0" + "\xe0\xb7\x81\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\xe0\xb7\x93 \xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f \xe0\xb6\xbb\xe0\xb7\x94\xe0\xb6\xb4\xe0\xb7\x92\xe0\xb6\xba\xe0\xb6\xbd\0" + "LTU\0" + "Lithuania\0" + "Lietuva\0" + "Euras\0" + "LUX\0" + "Luxembourg\0" + "L\xc3\xabtzebuerg\0" + "LVA\0" + "Latvia\0" + "Latvija\0" + "eiro\0" + "LBY\0" + "Libya\0" + "\xd9\x84\xd9\x8a\xd8\xa8\xd9\x8a\xd8\xa7\0" + "LYD\0" + "Libyan Dinar\0" + "\xd8\xaf\xd9\x8a\xd9\x86\xd8\xa7\xd8\xb1 \xd9\x84\xd9\x8a\xd8\xa8\xd9\x8a\0" + "Morocco\0" + "\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0" + "Moroccan Dirham\0" + "\xd8\xaf\xd8\xb1\xd9\x87\xd9\x85 \xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\xd9\x8a\0" + "MCO\0" + "Monaco\0" + "MDA\0" + "Moldova\0" + "Republica Moldova\0" + "MDL\0" + "Moldovan Leu\0" + "leu moldovenesc\0" + "MNE\0" + "Montenegro\0" + "\xd0\xa6\xd1\x80\xd0\xbd\xd0\xb0 \xd0\x93\xd0\xbe\xd1\x80\xd0\xb0\0" + "Evro\0" + "MKD\0" + "Macedonia\0" + "\xd0\x9c\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd0\xb8\xd1\x98\xd0\xb0\0" + "Macedonian Denar\0" + "\xd0\x9c\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8 \xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb0\xd1\x80\0" + "MLI\0" + "Mali\0" + "MMR\0" + "Myanmar (Burma)\0" + "MMK\0" + "Myanmar Kyat\0" + "\xe1\x80\x99\xe1\x80\xbc\xe1\x80\x94\xe1\x80\xba\xe1\x80\x99\xe1\x80\xac\xe1\x80\x80\xe1\x80\xbb\xe1\x80\x95\xe1\x80\xba\0" + "MNG\0" + "Mongolia\0" + "\xd0\x9c\xd0\xbe\xd0\xbd\xd0\xb3\xd0\xbe\xd0\xbb\0" + "MNT\0" + "Mongolian Tugrik\0" + "\xd1\x82\xd3\xa9\xd0\xb3\xd1\x80\xd3\xa9\xd0\xb3\0" + "MAC\0" + "Macau SAR China\0" + "\xe4\xb8\xad\xe5\x9b\xbd\xe6\xbe\xb3\xe9\x97\xa8\xe7\x89\xb9\xe5\x88\xab\xe8\xa1\x8c\xe6\x94\xbf\xe5\x8c\xba\0" + "MOP\0" + "Macanese Pataca\0" + "\xe6\xbe\xb3\xe9\x96\x80\xe5\x85\x83\0" + "Malta\0" + "ewro\0" + "MEX\0" + "Mexico\0" + "M\xc3\xa9xico\0" + "MXN\0" + "Mexican Peso\0" + "peso mexicano\0" + "MYS\0" + "Malaysia\0" + "MYR\0" + "Malaysian Ringgit\0" + "Ringgit Malaysia\0" + "NGA\0" + "Nigeria\0" + "Najeriya\0" + "NGN\0" + "Nigerian Naira\0" + "Naira\0" + "NIC\0" + "Nicaragua\0" + "NIO\0" + "Nicaraguan C\xc3\xb3rdoba\0" + "c\xc3\xb3rdoba nicarag\xc3\xbc\x65nse\0" + "Netherlands\0" + "Nederland\0" + "Norway\0" + "Norge\0" + "NOK\0" + "Norwegian Krone\0" + "norske kroner\0" + "NPL\0" + "Nepal\0" + "\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xb2\0" + "NPR\0" + "Nepalese Rupee\0" + "\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xb2\xe0\xa5\x80 \xe0\xa4\xb0\xe0\xa5\x82\xe0\xa4\xaa\xe0\xa5\x88\xe0\xa4\xaf\xe0\xa4\xbe\xe0\xa4\x81\0" + "NZL\0" + "New Zealand\0" + "NZD\0" + "New Zealand Dollar\0" + "OMN\0" + "Oman\0" + "\xd8\xb9\xd9\x8f\xd9\x85\xd8\xa7\xd9\x86\0" + "OMR\0" + "Omani Rial\0" + "\xd8\xb1\xd9\x8a\xd8\xa7\xd9\x84 \xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\xd9\x8a\0" + "Panama\0" + "Panam\xc3\xa1\0" + "PAB\0" + "Panamanian Balboa\0" + "balboa paname\xc3\xb1o\0" + "PER\0" + "Peru\0" + "Per\xc3\xba\0" + "PEN\0" + "Peruvian Sol\0" + "nuevo sol peruano\0" + "PHL\0" + "Philippines\0" + "Pilipinas\0" + "PHP\0" + "Philippine Peso\0" + "Piso ng Pilipinas\0" + "PAK\0" + "Pakistan\0" + "\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" + "PKR\0" + "Pakistani Rupee\0" + "\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\xdb\x8c \xd8\xb1\xd9\x88\xd9\xbe\xdb\x8c\xdb\x81\0" + "POL\0" + "Poland\0" + "Polska\0" + "PLN\0" + "Polish Zloty\0" + "z\xc5\x82oty polski\0" + "PRI\0" + "Puerto Rico\0" + "PRT\0" + "Portugal\0" + "PRY\0" + "Paraguay\0" + "PYG\0" + "Paraguayan Guarani\0" + "guaran\xc3\xad paraguayo\0" + "QAT\0" + "Qatar\0" + "\xd9\x82\xd8\xb7\xd8\xb1\0" + "QAR\0" + "Qatari Rial\0" + "\xd8\xb1\xd9\x8a\xd8\xa7\xd9\x84 \xd9\x82\xd8\xb7\xd8\xb1\xd9\x8a\0" + "REU\0" + "R\xc3\xa9union\0" + "La R\xc3\xa9union\0" + "ROU\0" + "Romania\0" + "Rom\xc3\xa2nia\0" + "Romanian Leu\0" + "leu rom\xc3\xa2nesc\0" + "Serbia\0" + "\xd0\xa1\xd1\x80\xd0\xb1\xd0\xb8\xd1\x98\xd0\xb0\0" + "Serbian Dinar\0" + "Srpski dinar\0" + "Russia\0" + "\xd0\xa0\xd0\xbe\xd1\x81\xd1\x81\xd0\xb8\xd1\x8f\0" + "RUB\0" + "Russian Ruble\0" + "\xd0\xa0\xd0\xbe\xd1\x81\xd1\x81\xd0\xb8\xd0\xb9\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9 \xd1\x80\xd1\x83\xd0\xb1\xd0\xbb\xd1\x8c\0" + "RWA\0" + "Rwanda\0" + "RWF\0" + "Rwandan Franc\0" + "SAU\0" + "Saudi Arabia\0" + "\xd8\xa7\xd9\x84\xd9\x85\xd9\x85\xd9\x84\xd9\x83\xd8\xa9 \xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 \xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" + "SAR\0" + "Saudi Riyal\0" + "\xd8\xb1\xd9\x8a\xd8\xa7\xd9\x84 \xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\0" + "SWE\0" + "Sweden\0" + "Sverige\0" + "SEK\0" + "Swedish Krona\0" + "svensk krona\0" + "SGP\0" + "Singapore\0" + "\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" + "SGD\0" + "Singapore Dollar\0" + "\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\xe5\x85\x83\0" + "SVN\0" + "Slovenia\0" + "Slovenija\0" + "evro\0" + "SVK\0" + "Slovakia\0" + "Slovensko\0" + "SEN\0" + "Senegal\0" + "S\xc3\xa9n\xc3\xa9gal\0" + "Somalia\0" + "Soomaaliya\0" + "SOS\0" + "Somali Shilling\0" + "Shilin soomaali\0" + "El Salvador\0" + "SYR\0" + "Syria\0" + "\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0" + "SYP\0" + "Syrian Pound\0" + "\xd9\x84\xd9\x8a\xd8\xb1\xd8\xa9 \xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0" + "Thailand\0" + "Thai Baht\0" + "\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\x97\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" + "TJK\0" + "Tajikistan\0" + "\xd0\xa2\xd0\xbe\xd2\xb7\xd0\xb8\xd0\xba\xd0\xb8\xd1\x81\xd1\x82\xd0\xbe\xd0\xbd\0" + "TJS\0" + "Tajikistani Somoni\0" + "\xd0\xa1\xd0\xbe\xd0\xbc\xd0\xbe\xd0\xbd\xd3\xa3\0" + "TKM\0" + "Turkmenistan\0" + "T\xc3\xbcrkmenistan\0" + "Turkmenistani Manat\0" + "T\xc3\xbcrkmen manaty\0" + "TUN\0" + "Tunisia\0" + "\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" + "TND\0" + "Tunisian Dinar\0" + "\xd8\xaf\xd9\x8a\xd9\x86\xd8\xa7\xd8\xb1 \xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\xd9\x8a\0" + "TUR\0" + "Turkey\0" + "T\xc3\xbcrkiye\0" + "TRY\0" + "Turkish Lira\0" + "T\xc3\xbcrk Liras\xc4\xb1\0" + "TTO\0" + "Trinidad & Tobago\0" + "TTD\0" + "Trinidad & Tobago Dollar\0" + "TWN\0" + "Taiwan\0" + "\xe5\x8f\xb0\xe6\xb9\xbe\0" + "TWD\0" + "New Taiwan Dollar\0" + "\xe6\x96\xb0\xe5\x8f\xb0\xe5\xb9\xa3\0" + "Ukraine\0" + "\xd0\xa3\xd0\xba\xd1\x80\xd0\xb0\xd1\x97\xd0\xbd\xd0\xb0\0" + "UAH\0" + "Ukrainian Hryvnia\0" + "\xd1\x83\xd0\xba\xd1\x80\xd0\xb0\xd1\x97\xd0\xbd\xd1\x81\xd1\x8c\xd0\xba\xd0\xb0 \xd0\xb3\xd1\x80\xd0\xb8\xd0\xb2\xd0\xbd\xd1\x8f\0" + "USA\0" + "United States\0" + "URY\0" + "Uruguay\0" + "UYU\0" + "Uruguayan Peso\0" + "peso uruguayo\0" + "Uzbekistan\0" + "O\xca\xbbzbekiston\0" + "UZS\0" + "Uzbekistani Som\0" + "O\xe2\x80\x98zbekiston so\xe2\x80\x98mi\0" + "VEN\0" + "Venezuela\0" + "VEF\0" + "Venezuelan Bol\xc3\xadvar\0" + "bol\xc3\xadvar venezolano\0" + "VNM\0" + "Vietnam\0" + "Vi\xe1\xbb\x87t Nam\0" + "VND\0" + "Vietnamese Dong\0" + "\xc4\x90\xe1\xbb\x93ng Vi\xe1\xbb\x87t Nam\0" + "YEM\0" + "Yemen\0" + "\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0" + "YER\0" + "Yemeni Rial\0" + "\xd8\xb1\xd9\x8a\xd8\xa7\xd9\x84 \xd9\x8a\xd9\x85\xd9\x86\xd9\x8a\0" + "ZAF\0" + "South Africa\0" + "ZAR\0" + "South African Rand\0" + "ZWE\0" + "Zimbabwe\0" +}; + + +static const char patterns [] = { + "\0" + "dd MMMM\0" + "dd/MM/yy\0" + "dd/MM/yyyy\0" + "dd/MMMM/yyyy\0" + "dddd, dd MMMM, yyyy\0" + "hh:mm tt\0" + "HH:mm\0" + "hh:mm:ss tt\0" + "HH:mm:ss\0" + "MMMM, yyyy\0" + "d MMMM\0" + "d.M.yyyy '\xd0\xb3.'\0" + "dd.M.yyyy '\xd0\xb3.'\0" + "d.MM.yyyy '\xd0\xb3.'\0" + "dd.MM.yyyy '\xd0\xb3.'\0" + "dd MMMM yyyy '\xd0\xb3.'\0" + "d MMMM yyyy '\xd0\xb3.'\0" + "dddd, dd MMMM yyyy '\xd0\xb3.'\0" + "dddd, d MMMM yyyy '\xd0\xb3.'\0" + "H:mm\0" + "H:mm:ss\0" + "MMMM yyyy '\xd0\xb3.'\0" + "d/M/yyyy\0" + "d MMM yyyy\0" + "dddd, d MMMM 'de' yyyy\0" + "d MMMM 'de' yyyy\0" + "MMMM 'de' yyyy\0" + "M\xe6\x9c\x88\x64\xe6\x97\xa5\0" + "yyyy/M/d\0" + "yyyy-M-d\0" + "yyyy.M.d\0" + "yyyy/MM/dd\0" + "yyyy-MM-dd\0" + "yyyy.MM.dd\0" + "yy/M/d\0" + "yy-M-d\0" + "yy.M.d\0" + "yy/MM/dd\0" + "yyyy'\xe5\xb9\xb4'M'\xe6\x9c\x88'd'\xe6\x97\xa5'\0" + "yyyy'\xe5\xb9\xb4'M'\xe6\x9c\x88'd'\xe6\x97\xa5', dddd\0" + "dddd, yyyy'\xe5\xb9\xb4'M'\xe6\x9c\x88'd'\xe6\x97\xa5'\0" + "yyyy\xe5\xb9\xb4MMMd\xe6\x97\xa5\0" + "yyyy\xe5\xb9\xb4MMMd\xe6\x97\xa5, dddd\0" + "tt h:mm\0" + "tt hh:mm\0" + "tt h:mm:ss\0" + "tt hh:mm:ss\0" + "yyyy'\xe5\xb9\xb4'M'\xe6\x9c\x88'\0" + "yyyy'\xe5\xb9\xb4'MMM\0" + "yyyy'\xe5\xb9\xb4'MMMM\0" + "yyyy.M\0" + "d. MMMM\0" + "dd.MM.yyyy\0" + "d. M. yyyy\0" + "dddd d. MMMM yyyy\0" + "d. MMMM yyyy\0" + "MMMM yyyy\0" + "dd-MM-yyyy\0" + "dd-MM-yy\0" + "yyyy MM dd\0" + "dd.MM.yy\0" + "dd. MMM. yyyy\0" + "dddd, d. MMMM yyyy\0" + "d. MMM. yyyy\0" + "HH:mm' Uhr'\0" + "HH:mm:ss' Uhr'\0" + "d/M/yy\0" + "dd/MMM/yyyy\0" + "dddd, d MMMM yyyy\0" + "d MMMM yyyy\0" + "h:mm tt\0" + "h:mm:ss tt\0" + "MMMM d\0" + "M/d/yyyy\0" + "M/d/yy\0" + "MM/dd/yy\0" + "MM/dd/yyyy\0" + "dd-MMM-yy\0" + "dddd, MMMM d, yyyy\0" + "MMMM d, yyyy\0" + "dddd, d MMMM, yyyy\0" + "d MMMM, yyyy\0" + "d 'de' MMMM\0" + "d/MM/yy\0" + "d-M-yy\0" + "dddd, d' de 'MMMM' de 'yyyy\0" + "dddd d' de 'MMMM' de 'yyyy\0" + "d' de 'MMMM' de 'yyyy\0" + "H.mm\0" + "HH.mm\0" + "HH'H'mm\0" + "H.mm.ss\0" + "HH.mm.ss\0" + "HH'H'mm.ss\0" + "MMMM' de 'yyyy\0" + "d.M.yyyy\0" + "dddd d MMMM yyyy\0" + "d MMM yy\0" + "HH' h 'mm\0" + "HH'h'mm\0" + "dd MMMM yyyy\0" + "dd-MMMM-yyyy\0" + "dd '\xd7\x91'MMMM yyyy\0" + "dd MMM yy\0" + "dddd dd MMMM yyyy\0" + "dddd dd '\xd7\x91'MMMM yyyy\0" + "ddd dd '\xd7\x91'MMMM yyyy\0" + "MMMM d.\0" + "yyyy. MM. dd.\0" + "yyyy. MMM d.\0" + "yyyy. MMMM d., dddd\0" + "yyyy. MMMM d.\0" + "yyyy. MMMM\0" + "d. MMM yyyy\0" + "dd.M.yy\0" + "d-MMM-yy\0" + "yyyy'\xe5\xb9\xb4'MM'\xe6\x9c\x88'dd'\xe6\x97\xa5'\0" + "yyyy'\xe5\xb9\xb4'M'\xe6\x9c\x88'd'\xe6\x97\xa5 'dddd\0" + "yyyy'\xe5\xb9\xb4'MM'\xe6\x9c\x88'dd'\xe6\x97\xa5 'dddd\0" + "yyyy'\xe5\xb9\xb4'MMM'\xe6\x9c\x88'd'\xe6\x97\xa5'\0" + "yyyy'\xe5\xb9\xb4'MMM'\xe6\x9c\x88'd'\xe6\x97\xa5 'dddd\0" + "yyyy'\xe5\xb9\xb4'MMMMd'\xe6\x97\xa5'\0" + "yyyy'\xe5\xb9\xb4'MMMMd'\xe6\x97\xa5 'dddd\0" + "yyyy'\xe5\xb9\xb4'MMM'\xe6\x9c\x88'\0" + "M\xec\x9b\x94 d\xec\x9d\xbc\0" + "yy-MM-dd\0" + "yyyy'\xeb\x85\x84' M'\xec\x9b\x94' d'\xec\x9d\xbc' dddd\0" + "yyyy'\xeb\x85\x84' M'\xec\x9b\x94' d'\xec\x9d\xbc'\0" + "yy'\xeb\x85\x84' M'\xec\x9b\x94' d'\xec\x9d\xbc' dddd\0" + "yy'\xeb\x85\x84' M'\xec\x9b\x94' d'\xec\x9d\xbc'\0" + "yyyy'\xeb\x85\x84' MM'\xec\x9b\x94' dd'\xec\x9d\xbc' dddd\0" + "yyyy'\xeb\x85\x84' MM'\xec\x9b\x94' dd'\xec\x9d\xbc'\0" + "yyyy'\xeb\x85\x84 'MMM'\xec\x9b\x94 'd'\xec\x9d\xbc 'dddd\0" + "yyyy'\xeb\x85\x84 'MMM'\xec\x9b\x94 'd'\xec\x9d\xbc'\0" + "yyyy'\xeb\x85\x84 'MMMM d'\xec\x9d\xbc 'dddd\0" + "yyyy'\xeb\x85\x84 'MMMM d'\xec\x9d\xbc'\0" + "yyyy'\xeb\x85\x84' M'\xec\x9b\x94'\0" + "yyyy'\xeb\x85\x84' MMM'\xec\x9b\x94'\0" + "yyyy'\xeb\x85\x84' MMMM\0" + "d-M-yyyy\0" + "dd.MMM.yyyy\0" + "HH.mm' uur'\0" + "HH:mm' uur'\0" + "HH.mm.ss' uur'\0" + "HH:mm:ss' uur'\0" + "d.MMMM.\0" + "d.M.yy\0" + "dddd, 'ils' d 'da' MMMM yyyy\0" + "d 'da' MMMM yyyy\0" + "d.M.yyyy.\0" + "d.M.yy.\0" + "d. M. yyyy.\0" + "dd.MM.yyyy.\0" + "d. M. yy.\0" + "dd.MM.yy.\0" + "dd. MM. yy.\0" + "d. MMMM yyyy.\0" + "dd. MMMM yyyy.\0" + "dddd, d. MMMM yyyy.\0" + "'den 'd MMMM\0" + "'den 'd MMMM yyyy\0" + "dddd' den 'd MMMM yyyy\0" + "'kl 'H:mm\0" + "'kl 'H:mm:ss\0" + "dd MMM yyyy\0" + "ddd d MMMM yyyy\0" + "'\xe0\xb8\xa7\xe0\xb8\xb1\xe0\xb8\x99'dddd'\xe0\xb8\x97\xe0\xb8\xb5\xe0\xb9\x88' d MMMM gg yyyy\0" + "d.MM.yyyy\0" + "d MMMM yyyy dddd\0" + "dd MMMM, yyyy\0" + "dddd, dd MMMM yyyy\0" + "d MMMM yyyy' \xd1\x80.'\0" + "MMMM yyyy' \xd1\x80.'\0" + "MMMM yyyy \xd0\xb3.\0" + "d. MM. yyyy\0" + "dddd, dd. MMMM yyyy\0" + "dd. MMMM yyyy\0" + "H:mm.ss\0" + "yyyy. 'gada' d. MMM\0" + "dddd, yyyy. 'gada' d. MMMM\0" + "yyyy. 'gada' d. MMMM\0" + "yyyy. 'g'. MMMM\0" + "yyyy 'm'. MMMM d 'd'., dddd\0" + "yyyy 'm'. MMMM d 'd'.\0" + "yyyy MMMM\0" + "d MMMM yyyy' \xd1\x81.'\0" + "dd MMMM yyyy' \xd1\x81.'\0" + "d/MM/yyyy\0" + "d/MMM/yyyy\0" + "d-MMM-yyyy\0" + "dd-MMM-yyyy\0" + "ddd, d-MMMM-yyyy\0" + "ddd, dd-MMMM-yyyy\0" + "d MMMM yyyy, dddd\0" + "yyyy MMM d\0" + "yyyy('e')'ko' MMMM d, dddd\0" + "yyyy('e')'ko' MMMM d\0" + "yyyy('e')'ko' MMMM\0" + "H:mm 'hod\xc5\xba'.\0" + "dd.M.yyyy\0" + "MMMM yyyy '\xd0\xb3'.\0" + "yyyy MMMM d, dddd\0" + "yyyy MMMM d\0" + "MMM d, yyyy\0" + "d MMM, yyyy\0" + "d 'ta'\xe2\x80\x99 MMMM\0" + "dddd, d 'ta'\xe2\x80\x99 MMMM yyyy\0" + "d 'ta'\xe2\x80\x99 MMMM yyyy\0" + "MMMM 'ta'\xe2\x80\x99 yyyy\0" + "yyyy, dd-MMM\0" + "d-MMMM\0" + "d-MMM yy\0" + "dd-MMMM yyyy'-\xd0\xb6.'\0" + "MMMM yyyy'-\xd0\xb6.'\0" + "dd.MM.yy '\xc3\xbd.'\0" + "yyyy'-nji \xc3\xbdyly\xc5\x88 'd'-nji 'MMMM\0" + "yyyy '\xc3\xbd.' MMMM\0" + "dddd, yyyy MMMM dd\0" + "tt hh.mm\0" + "tt h.mm\0" + "tt hh.mm.ss\0" + "tt h.mm.ss\0" + "dd MMMM yyyy dddd\0" + "MMMM dd\0" + "yyyy,MMMM dd, dddd\0" + "MMMM,yy\0" + "MMMM,yyyy\0" + "dddd, yyyy '\xd0\xbe\xd0\xbd\xd1\x8b' MM '\xd1\x81\xd0\xb0\xd1\x80\xd1\x8b\xd0\xbd' d\0" + "yyyy '\xd0\xbe\xd0\xbd\xd1\x8b' MM '\xd1\x81\xd0\xb0\xd1\x80\xd1\x8b\xd0\xbd' d\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8bM\xe0\xbd\x9a\xe0\xbd\xba\xe0\xbd\xa6\xe0\xbc\x8b\x64\0" + "yyyy'\xe0\xbd\xa3\xe0\xbd\xbc\xe0\xbd\xa0\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x9f\xe0\xbe\xb3' M'\xe0\xbd\x9a\xe0\xbd\xba\xe0\xbd\xa6' d\0" + "yyyy'\xe0\xbd\xa3\xe0\xbd\xbc\xe0\xbd\xa0\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x9f\xe0\xbe\xb3' M'\xe0\xbd\x9a\xe0\xbd\xba\xe0\xbd\xa6' d dddd\0" + "yyyy\xe0\xbd\xa3\xe0\xbd\xbc\xe0\xbd\xa0\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x9f\xe0\xbe\xb3 MMM d\0" + "yyyy\xe0\xbd\xa3\xe0\xbd\xbc\xe0\xbd\xa0\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x9f\xe0\xbe\xb3 MMM d dddd\0" + "yyyy'\xe0\xbd\xa3\xe0\xbd\xbc\xe0\xbd\xa0\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b' M\0" + "'\xe1\x9e\x81\xe1\x9f\x82' MM '\xe1\x9e\x86\xe1\x9f\x92\xe1\x9e\x93\xe1\x9e\xb6\xe1\x9f\x86' yyyy\0" + "dddd \xe0\xba\x97\xe0\xba\xb5 d MMMM gg yyyy\0" + "dddd\xe1\x81\x8a dd MMMM yyyy\0" + "dddd, MMMM dd,yyyy\0" + "MMMM dd,yyyy\0" + "dddd, MMMM dd, yyyy\0" + "MMMM dd, yyyy\0" + "dd. MMMM\0" + "dd. MMMMyyyy\0" + "dddd,' den 'd. MMMM yyyy\0" + "dddd,' den 'dd. MMMM yyyy\0" + "H.mm' Auer'\0" + "H:mm:ss' Auer'\0" + "HH:mm:ss' Auer'\0" + "MMMM d'.-at'\0" + "MMMM d'.-at, 'yyyy\0" + "dddd\xe1\x8d\xa1 dd MMMM \xe1\x88\x98\xe1\x8b\x93\xe1\x88\x8d\xe1\x89\xb2 yyyy gg\0" + "M\xe2\x80\x99 \xea\x86\xaa\xe2\x80\x99\x64\xe2\x80\x99 \xea\x91\x8d\xe2\x80\x99\0" + "yyyy'\xea\x88\x8e' M'\xea\x86\xaa' d'\xea\x91\x8d'\0" + "dddd, yyyy'\xea\x88\x8e' M'\xea\x86\xaa' d'\xea\x91\x8d'\0" + "yyyy'\xea\x88\x8e' M'\xea\x86\xaa' d'\xea\x91\x8d', dddd\0" + "yyyy\xea\x88\x8e MMM d\xea\x91\x8d\0" + "dddd, yyyy\xea\x88\x8e MMM d\xea\x91\x8d\0" + "yyyy'\xea\x88\x8e' M'\xea\x86\xaa'\0" + "yyyy-'\xd9\x8a\xd9\x89\xd9\x84' d-MMMM\0" + "yyyy-'\xd9\x8a\xd9\x89\xd9\x84' d-MMMM dddd\0" + "yyyy-'\xd9\x8a\xd9\x89\xd9\x84\xd9\x89' MMM'\xd9\x86\xd9\x89\xda\xad' d'-\xd9\x83\xdb\x88\xd9\x86\xd9\x89'\0" + "yyyy-'\xd9\x8a\xd9\x89\xd9\x84\xd9\x89' MMM'\xd9\x86\xd9\x89\xda\xad' d'-\xd9\x83\xdb\x88\xd9\x86\xd9\x89' dddd\0" + "yyyy-M-d dddd\0" + "yyyy-'\xd9\x8a\xd9\x89\xd9\x84\xd9\x89' MMMM\0" + "MMMM d \xd0\xba\xd2\xaf\xd0\xbd\xd1\x8d\0" + "yyyy MM d\0" + "dd yyyy MM d\0" + "dddd, yyyy '\xd1\x81.' MMMM d '\xd0\xba\xd2\xaf\xd0\xbd\xd1\x8d'\0" + "yyyy '\xd1\x81.' MMMM d '\xd0\xba\xd2\xaf\xd0\xbd\xd1\x8d'\0" + "dddd, MMMM d '\xd0\xba\xd2\xaf\xd0\xbd\xd1\x8d' yyyy '\xd1\x81.'\0" + "yyyy '\xd1\x81.' MMMM\0" + "d'mh' MMMM\0" + "dddd, d'mh' MMMM yyyy\0" + "d'mh' MMMM yyyy\0" + "dddd yyyy\xe5\xb9\xb4MMMd\xe6\x97\xa5\0" + "dddd\xe1\x8d\xa3 dd MMMM \xe1\x88\x98\xe1\x8b\x93\xe1\x88\x8d\xe1\x89\xb2 yyyy gg\0" + "dd.MMMM.\0" + "dd.MMMM\0" + "MMMM.yyyy\0" + "H.mm' u.'\0" + "yy.MM.dd\0" + "d MMM yyyy '\xd0\xb3'.\0" + "dddd, d MMMM yyyy '\xd0\xb3'.\0" + "d MMMM yyyy '\xd0\xb3'.\0" + "d. M. yy\0" + "H:mm' g\xc3\xb3\xc5\xba.'\0" + "'zeger 'H:mm\0" + "H:mm:ss' g\xc3\xb3\xc5\xba.'\0" + "'zeger 'H:mm:ss\0" + "MMMM d'. b.'\0" + "dddd, MMMM d'. b. 'yyyy\0" + "MMMM d'. b. 'yyyy\0" + "h.mm tt\0" + "h.mm.ss tt\0" + "yy MM dd\0" + "dddd', 'MMMM d'. b. 'yyyy\0" + "M/dd/yy\0" + "MMMM-dd-yy\0" + "dd-MMMM\0" + "dddd, d 'de' MMMM 'de' yyyy\0" + "d 'de' MMMM 'de' yyyy\0" + "d. MMM yyyy.\0" + "MMMM yyyy.\0" + "dddd yyyy'\xe5\xb9\xb4'M'\xe6\x9c\x88'd'\xe6\x97\xa5'\0" + "dddd yyyy MM dd\0" + "d/MMMM\0" + "MMMM/yyyy\0" + "dd. MMM. yyyy.\0" + "dddd, dd. MMMM yyyy.\0" + "MMMM/dd\0" + "dd. MM. yy\0" + "MMMM d'. p. '\0" + "MMMM d'. p. 'yyyy\0" + "MMMM-yyyy\0" + "dd MMM,yyyy\0" + "yyyy-MM-dd.\0" + "dddd dd 'de' MMMM 'de' yyyy\0" + "dd 'de' MMMM 'de' yyyy\0" +}; + + +static const char datetime_strings [] = { + "\0" + "\xd9\x85\xd8\xad\xd8\xb1\xd9\x85\0" + "\xd8\xb5\xd9\x81\xd8\xb1\0" + "\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xb9 \xd8\xa7\xd9\x84\xd8\xa3\xd9\x88\xd9\x84\0" + "\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xb9 \xd8\xa7\xd9\x84\xd8\xa2\xd8\xae\xd8\xb1\0" + "\xd8\xac\xd9\x85\xd8\xa7\xd8\xaf\xd9\x89 \xd8\xa7\xd9\x84\xd8\xa3\xd9\x88\xd9\x84\xd9\x89\0" + "\xd8\xac\xd9\x85\xd8\xa7\xd8\xaf\xd9\x89 \xd8\xa7\xd9\x84\xd8\xa2\xd8\xae\xd8\xb1\xd8\xa9\0" + "\xd8\xb1\xd8\xac\xd8\xa8\0" + "\xd8\xb4\xd8\xb9\xd8\xa8\xd8\xa7\xd9\x86\0" + "\xd8\xb1\xd9\x85\xd8\xb6\xd8\xa7\xd9\x86\0" + "\xd8\xb4\xd9\x88\xd8\xa7\xd9\x84\0" + "\xd8\xb0\xd9\x88 \xd8\xa7\xd9\x84\xd9\x82\xd8\xb9\xd8\xaf\xd8\xa9\0" + "\xd8\xb0\xd9\x88 \xd8\xa7\xd9\x84\xd8\xad\xd8\xac\xd8\xa9\0" + "\xd0\xbd\xd0\xb5\xd0\xb4\xd0\xb5\xd0\xbb\xd1\x8f\0" + "\xd0\xbf\xd0\xbe\xd0\xbd\xd0\xb5\xd0\xb4\xd0\xb5\xd0\xbb\xd0\xbd\xd0\xb8\xd0\xba\0" + "\xd0\xb2\xd1\x82\xd0\xbe\xd1\x80\xd0\xbd\xd0\xb8\xd0\xba\0" + "\xd1\x81\xd1\x80\xd1\x8f\xd0\xb4\xd0\xb0\0" + "\xd1\x87\xd0\xb5\xd1\x82\xd0\xb2\xd1\x8a\xd1\x80\xd1\x82\xd1\x8a\xd0\xba\0" + "\xd0\xbf\xd0\xb5\xd1\x82\xd1\x8a\xd0\xba\0" + "\xd1\x81\xd1\x8a\xd0\xb1\xd0\xbe\xd1\x82\xd0\xb0\0" + "\xd0\xbd\xd0\xb4\0" + "\xd0\xbf\xd0\xbd\0" + "\xd0\xb2\xd1\x82\0" + "\xd1\x81\xd1\x80\0" + "\xd1\x87\xd1\x82\0" + "\xd0\xbf\xd1\x82\0" + "\xd1\x81\xd0\xb1\0" + "\xd0\xbd\0" + "\xd0\xbf\0" + "\xd0\xb2\0" + "\xd1\x81\0" + "\xd1\x87\0" + "\xd1\x8f\xd0\xbd\xd1\x83\xd0\xb0\xd1\x80\xd0\xb8\0" + "\xd1\x84\xd0\xb5\xd0\xb2\xd1\x80\xd1\x83\xd0\xb0\xd1\x80\xd0\xb8\0" + "\xd0\xbc\xd0\xb0\xd1\x80\xd1\x82\0" + "\xd0\xb0\xd0\xbf\xd1\x80\xd0\xb8\xd0\xbb\0" + "\xd0\xbc\xd0\xb0\xd0\xb9\0" + "\xd1\x8e\xd0\xbd\xd0\xb8\0" + "\xd1\x8e\xd0\xbb\xd0\xb8\0" + "\xd0\xb0\xd0\xb2\xd0\xb3\xd1\x83\xd1\x81\xd1\x82\0" + "\xd1\x81\xd0\xb5\xd0\xbf\xd1\x82\xd0\xb5\xd0\xbc\xd0\xb2\xd1\x80\xd0\xb8\0" + "\xd0\xbe\xd0\xba\xd1\x82\xd0\xbe\xd0\xbc\xd0\xb2\xd1\x80\xd0\xb8\0" + "\xd0\xbd\xd0\xbe\xd0\xb5\xd0\xbc\xd0\xb2\xd1\x80\xd0\xb8\0" + "\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb5\xd0\xbc\xd0\xb2\xd1\x80\xd0\xb8\0" + "\xd1\x8f\xd0\xbd\xd1\x83\0" + "\xd1\x84\xd0\xb5\xd0\xb2\0" + "\xd0\xb0\xd0\xbf\xd1\x80\0" + "\xd0\xb0\xd0\xb2\xd0\xb3\0" + "\xd1\x81\xd0\xb5\xd0\xbf\0" + "\xd0\xbe\xd0\xba\xd1\x82\0" + "\xd0\xbd\xd0\xbe\xd0\xb5\0" + "\xd0\xb4\xd0\xb5\xd0\xba\0" + "diumenge\0" + "dilluns\0" + "dimarts\0" + "dimecres\0" + "dijous\0" + "divendres\0" + "dissabte\0" + "dg.\0" + "dl.\0" + "dt.\0" + "dc.\0" + "dj.\0" + "dv.\0" + "ds.\0" + "dg\0" + "dl\0" + "dt\0" + "dc\0" + "dj\0" + "dv\0" + "ds\0" + "gener\0" + "febrer\0" + "mar\xc3\xa7\0" + "abril\0" + "maig\0" + "juny\0" + "juliol\0" + "agost\0" + "setembre\0" + "octubre\0" + "novembre\0" + "desembre\0" + "de gener\0" + "de febrer\0" + "de mar\xc3\xa7\0" + "d\xe2\x80\x99\x61\x62ril\0" + "de maig\0" + "de juny\0" + "de juliol\0" + "d\xe2\x80\x99\x61gost\0" + "de setembre\0" + "d\xe2\x80\x99octubre\0" + "de novembre\0" + "de desembre\0" + "gen.\0" + "febr.\0" + "abr.\0" + "jul.\0" + "ag.\0" + "set.\0" + "oct.\0" + "nov.\0" + "des.\0" + "\xe6\x98\x9f\xe6\x9c\x9f\xe6\x97\xa5\0" + "\xe6\x98\x9f\xe6\x9c\x9f\xe4\xb8\x80\0" + "\xe6\x98\x9f\xe6\x9c\x9f\xe4\xba\x8c\0" + "\xe6\x98\x9f\xe6\x9c\x9f\xe4\xb8\x89\0" + "\xe6\x98\x9f\xe6\x9c\x9f\xe5\x9b\x9b\0" + "\xe6\x98\x9f\xe6\x9c\x9f\xe4\xba\x94\0" + "\xe6\x98\x9f\xe6\x9c\x9f\xe5\x85\xad\0" + "\xe5\x91\xa8\xe6\x97\xa5\0" + "\xe5\x91\xa8\xe4\xb8\x80\0" + "\xe5\x91\xa8\xe4\xba\x8c\0" + "\xe5\x91\xa8\xe4\xb8\x89\0" + "\xe5\x91\xa8\xe5\x9b\x9b\0" + "\xe5\x91\xa8\xe4\xba\x94\0" + "\xe5\x91\xa8\xe5\x85\xad\0" + "\xe6\x97\xa5\0" + "\xe4\xb8\x80\0" + "\xe4\xba\x8c\0" + "\xe4\xb8\x89\0" + "\xe5\x9b\x9b\0" + "\xe4\xba\x94\0" + "\xe5\x85\xad\0" + "\xe4\xb8\x80\xe6\x9c\x88\0" + "\xe4\xba\x8c\xe6\x9c\x88\0" + "\xe4\xb8\x89\xe6\x9c\x88\0" + "\xe5\x9b\x9b\xe6\x9c\x88\0" + "\xe4\xba\x94\xe6\x9c\x88\0" + "\xe5\x85\xad\xe6\x9c\x88\0" + "\xe4\xb8\x83\xe6\x9c\x88\0" + "\xe5\x85\xab\xe6\x9c\x88\0" + "\xe4\xb9\x9d\xe6\x9c\x88\0" + "\xe5\x8d\x81\xe6\x9c\x88\0" + "\xe5\x8d\x81\xe4\xb8\x80\xe6\x9c\x88\0" + "\xe5\x8d\x81\xe4\xba\x8c\xe6\x9c\x88\0" + "1\xe6\x9c\x88\0" + "2\xe6\x9c\x88\0" + "3\xe6\x9c\x88\0" + "4\xe6\x9c\x88\0" + "5\xe6\x9c\x88\0" + "6\xe6\x9c\x88\0" + "7\xe6\x9c\x88\0" + "8\xe6\x9c\x88\0" + "9\xe6\x9c\x88\0" + "10\xe6\x9c\x88\0" + "11\xe6\x9c\x88\0" + "12\xe6\x9c\x88\0" + "ned\xc4\x9ble\0" + "pond\xc4\x9bl\xc3\xad\0" + "\xc3\xbater\xc3\xbd\0" + "st\xc5\x99\x65\x64\x61\0" + "\xc4\x8dtvrtek\0" + "p\xc3\xa1tek\0" + "sobota\0" + "ne\0" + "po\0" + "\xc3\xbat\0" + "st\0" + "\xc4\x8dt\0" + "p\xc3\xa1\0" + "so\0" + "N\0" + "P\0" + "\xc3\x9a\0" + "S\0" + "\xc4\x8c\0" + "leden\0" + "\xc3\xbanor\0" + "b\xc5\x99\x65zen\0" + "duben\0" + "kv\xc4\x9bten\0" + "\xc4\x8d\x65rven\0" + "\xc4\x8d\x65rvenec\0" + "srpen\0" + "z\xc3\xa1\xc5\x99\xc3\xad\0" + "\xc5\x99\xc3\xadjen\0" + "listopad\0" + "prosinec\0" + "ledna\0" + "\xc3\xbanora\0" + "b\xc5\x99\x65zna\0" + "dubna\0" + "kv\xc4\x9btna\0" + "\xc4\x8d\x65rvna\0" + "\xc4\x8d\x65rvence\0" + "srpna\0" + "\xc5\x99\xc3\xadjna\0" + "listopadu\0" + "prosince\0" + "led\0" + "\xc3\xbano\0" + "b\xc5\x99\x65\0" + "dub\0" + "kv\xc4\x9b\0" + "\xc4\x8dvn\0" + "\xc4\x8dvc\0" + "srp\0" + "z\xc3\xa1\xc5\x99\0" + "\xc5\x99\xc3\xadj\0" + "lis\0" + "pro\0" + "s\xc3\xb8ndag\0" + "mandag\0" + "tirsdag\0" + "onsdag\0" + "torsdag\0" + "fredag\0" + "l\xc3\xb8rdag\0" + "s\xc3\xb8n\0" + "man\0" + "tir\0" + "ons\0" + "tor\0" + "fre\0" + "l\xc3\xb8r\0" + "M\0" + "T\0" + "O\0" + "F\0" + "L\0" + "januar\0" + "februar\0" + "marts\0" + "april\0" + "maj\0" + "juni\0" + "juli\0" + "august\0" + "september\0" + "oktober\0" + "november\0" + "december\0" + "jan.\0" + "feb.\0" + "mar.\0" + "apr.\0" + "jun.\0" + "aug.\0" + "sep.\0" + "okt.\0" + "dec.\0" + "Sonntag\0" + "Montag\0" + "Dienstag\0" + "Mittwoch\0" + "Donnerstag\0" + "Freitag\0" + "Samstag\0" + "So\0" + "Mo\0" + "Di\0" + "Mi\0" + "Do\0" + "Fr\0" + "Sa\0" + "D\0" + "Januar\0" + "Februar\0" + "M\xc3\xa4rz\0" + "April\0" + "Mai\0" + "Juni\0" + "Juli\0" + "August\0" + "September\0" + "Oktober\0" + "November\0" + "Dezember\0" + "Jan\0" + "Feb\0" + "M\xc3\xa4r\0" + "Apr\0" + "Jun\0" + "Jul\0" + "Aug\0" + "Sep\0" + "Okt\0" + "Nov\0" + "Dez\0" + "\xce\x9a\xcf\x85\xcf\x81\xce\xb9\xce\xb1\xce\xba\xce\xae\0" + "\xce\x94\xce\xb5\xcf\x85\xcf\x84\xce\xad\xcf\x81\xce\xb1\0" + "\xce\xa4\xcf\x81\xce\xaf\xcf\x84\xce\xb7\0" + "\xce\xa4\xce\xb5\xcf\x84\xce\xac\xcf\x81\xcf\x84\xce\xb7\0" + "\xce\xa0\xce\xad\xce\xbc\xcf\x80\xcf\x84\xce\xb7\0" + "\xce\xa0\xce\xb1\xcf\x81\xce\xb1\xcf\x83\xce\xba\xce\xb5\xcf\x85\xce\xae\0" + "\xce\xa3\xce\xac\xce\xb2\xce\xb2\xce\xb1\xcf\x84\xce\xbf\0" + "\xce\x9a\xcf\x85\xcf\x81\0" + "\xce\x94\xce\xb5\xcf\x85\0" + "\xce\xa4\xcf\x81\xce\xaf\0" + "\xce\xa4\xce\xb5\xcf\x84\0" + "\xce\xa0\xce\xad\xce\xbc\0" + "\xce\xa0\xce\xb1\xcf\x81\0" + "\xce\xa3\xce\xac\xce\xb2\0" + "\xce\x9a\0" + "\xce\x94\0" + "\xce\xa4\0" + "\xce\xa0\0" + "\xce\xa3\0" + "\xce\x99\xce\xb1\xce\xbd\xce\xbf\xcf\x85\xce\xac\xcf\x81\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\xa6\xce\xb5\xce\xb2\xcf\x81\xce\xbf\xcf\x85\xce\xac\xcf\x81\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x9c\xce\xac\xcf\x81\xcf\x84\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x91\xcf\x80\xcf\x81\xce\xaf\xce\xbb\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x9c\xce\xac\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x99\xce\xbf\xcf\x8d\xce\xbd\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x99\xce\xbf\xcf\x8d\xce\xbb\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x91\xcf\x8d\xce\xb3\xce\xbf\xcf\x85\xcf\x83\xcf\x84\xce\xbf\xcf\x82\0" + "\xce\xa3\xce\xb5\xcf\x80\xcf\x84\xce\xad\xce\xbc\xce\xb2\xcf\x81\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x9f\xce\xba\xcf\x84\xcf\x8e\xce\xb2\xcf\x81\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x9d\xce\xbf\xce\xad\xce\xbc\xce\xb2\xcf\x81\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x94\xce\xb5\xce\xba\xce\xad\xce\xbc\xce\xb2\xcf\x81\xce\xb9\xce\xbf\xcf\x82\0" + "\xce\x99\xce\xb1\xce\xbd\xce\xbf\xcf\x85\xce\xb1\xcf\x81\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\xa6\xce\xb5\xce\xb2\xcf\x81\xce\xbf\xcf\x85\xce\xb1\xcf\x81\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x9c\xce\xb1\xcf\x81\xcf\x84\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x91\xcf\x80\xcf\x81\xce\xb9\xce\xbb\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x9c\xce\xb1\xce\x90\xce\xbf\xcf\x85\0" + "\xce\x99\xce\xbf\xcf\x85\xce\xbd\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x99\xce\xbf\xcf\x85\xce\xbb\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x91\xcf\x85\xce\xb3\xce\xbf\xcf\x8d\xcf\x83\xcf\x84\xce\xbf\xcf\x85\0" + "\xce\xa3\xce\xb5\xcf\x80\xcf\x84\xce\xb5\xce\xbc\xce\xb2\xcf\x81\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x9f\xce\xba\xcf\x84\xcf\x89\xce\xb2\xcf\x81\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x9d\xce\xbf\xce\xb5\xce\xbc\xce\xb2\xcf\x81\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x94\xce\xb5\xce\xba\xce\xb5\xce\xbc\xce\xb2\xcf\x81\xce\xaf\xce\xbf\xcf\x85\0" + "\xce\x99\xce\xb1\xce\xbd\0" + "\xce\xa6\xce\xb5\xce\xb2\0" + "\xce\x9c\xce\xac\xcf\x81\0" + "\xce\x91\xcf\x80\xcf\x81\0" + "\xce\x9c\xce\xac\xce\xb9\0" + "\xce\x99\xce\xbf\xcf\x8d\xce\xbd\0" + "\xce\x99\xce\xbf\xcf\x8d\xce\xbb\0" + "\xce\x91\xcf\x8d\xce\xb3\0" + "\xce\xa3\xce\xb5\xcf\x80\0" + "\xce\x9f\xce\xba\xcf\x84\0" + "\xce\x9d\xce\xbf\xce\xad\0" + "\xce\x94\xce\xb5\xce\xba\0" + "Sunday\0" + "Monday\0" + "Tuesday\0" + "Wednesday\0" + "Thursday\0" + "Friday\0" + "Saturday\0" + "Sun\0" + "Mon\0" + "Tue\0" + "Wed\0" + "Thu\0" + "Fri\0" + "Sat\0" + "W\0" + "January\0" + "February\0" + "March\0" + "May\0" + "June\0" + "July\0" + "October\0" + "December\0" + "Mar\0" + "Oct\0" + "Dec\0" + "domingo\0" + "lunes\0" + "martes\0" + "mi\xc3\xa9rcoles\0" + "jueves\0" + "viernes\0" + "s\xc3\xa1\x62\x61\x64o\0" + "dom.\0" + "lun.\0" + "mi\xc3\xa9.\0" + "jue.\0" + "vie.\0" + "s\xc3\xa1\x62.\0" + "X\0" + "J\0" + "V\0" + "enero\0" + "febrero\0" + "marzo\0" + "mayo\0" + "junio\0" + "julio\0" + "agosto\0" + "septiembre\0" + "noviembre\0" + "diciembre\0" + "ene.\0" + "may.\0" + "ago.\0" + "sept.\0" + "dic.\0" + "sunnuntaina\0" + "maanantaina\0" + "tiistaina\0" + "keskiviikkona\0" + "torstaina\0" + "perjantaina\0" + "lauantaina\0" + "su\0" + "ma\0" + "ti\0" + "ke\0" + "to\0" + "pe\0" + "la\0" + "K\0" + "tammikuu\0" + "helmikuu\0" + "maaliskuu\0" + "huhtikuu\0" + "toukokuu\0" + "kes\xc3\xa4kuu\0" + "hein\xc3\xa4kuu\0" + "elokuu\0" + "syyskuu\0" + "lokakuu\0" + "marraskuu\0" + "joulukuu\0" + "tammikuuta\0" + "helmikuuta\0" + "maaliskuuta\0" + "huhtikuuta\0" + "toukokuuta\0" + "kes\xc3\xa4kuuta\0" + "hein\xc3\xa4kuuta\0" + "elokuuta\0" + "syyskuuta\0" + "lokakuuta\0" + "marraskuuta\0" + "joulukuuta\0" + "tammi\0" + "helmi\0" + "maalis\0" + "huhti\0" + "touko\0" + "kes\xc3\xa4\0" + "hein\xc3\xa4\0" + "elo\0" + "syys\0" + "loka\0" + "marras\0" + "joulu\0" + "dimanche\0" + "lundi\0" + "mardi\0" + "mercredi\0" + "jeudi\0" + "vendredi\0" + "samedi\0" + "dim.\0" + "mer.\0" + "jeu.\0" + "ven.\0" + "sam.\0" + "janvier\0" + "f\xc3\xa9vrier\0" + "mars\0" + "avril\0" + "mai\0" + "juin\0" + "juillet\0" + "ao\xc3\xbbt\0" + "septembre\0" + "octobre\0" + "d\xc3\xa9\x63\x65mbre\0" + "janv.\0" + "f\xc3\xa9vr.\0" + "avr.\0" + "juil.\0" + "d\xc3\xa9\x63.\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\xa8\xd7\x90\xd7\xa9\xd7\x95\xd7\x9f\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\xa9\xd7\xa0\xd7\x99\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\xa9\xd7\x9c\xd7\x99\xd7\xa9\xd7\x99\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\xa8\xd7\x91\xd7\x99\xd7\xa2\xd7\x99\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\x97\xd7\x9e\xd7\x99\xd7\xa9\xd7\x99\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\xa9\xd7\x99\xd7\xa9\xd7\x99\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\xa9\xd7\x91\xd7\xaa\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\x90\xd7\xb3\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\x91\xd7\xb3\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\x92\xd7\xb3\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\x93\xd7\xb3\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\x94\xd7\xb3\0" + "\xd7\x99\xd7\x95\xd7\x9d \xd7\x95\xd7\xb3\0" + "\xd7\xa9\xd7\x91\xd7\xaa\0" + "\xd7\x90\xd7\xb3\0" + "\xd7\x91\xd7\xb3\0" + "\xd7\x92\xd7\xb3\0" + "\xd7\x93\xd7\xb3\0" + "\xd7\x94\xd7\xb3\0" + "\xd7\x95\xd7\xb3\0" + "\xd7\xa9\xd7\xb3\0" + "\xd7\x99\xd7\xa0\xd7\x95\xd7\x90\xd7\xa8\0" + "\xd7\xa4\xd7\x91\xd7\xa8\xd7\x95\xd7\x90\xd7\xa8\0" + "\xd7\x9e\xd7\xa8\xd7\xa5\0" + "\xd7\x90\xd7\xa4\xd7\xa8\xd7\x99\xd7\x9c\0" + "\xd7\x9e\xd7\x90\xd7\x99\0" + "\xd7\x99\xd7\x95\xd7\xa0\xd7\x99\0" + "\xd7\x99\xd7\x95\xd7\x9c\xd7\x99\0" + "\xd7\x90\xd7\x95\xd7\x92\xd7\x95\xd7\xa1\xd7\x98\0" + "\xd7\xa1\xd7\xa4\xd7\x98\xd7\x9e\xd7\x91\xd7\xa8\0" + "\xd7\x90\xd7\x95\xd7\xa7\xd7\x98\xd7\x95\xd7\x91\xd7\xa8\0" + "\xd7\xa0\xd7\x95\xd7\x91\xd7\x9e\xd7\x91\xd7\xa8\0" + "\xd7\x93\xd7\xa6\xd7\x9e\xd7\x91\xd7\xa8\0" + "\xd7\x99\xd7\xa0\xd7\x95\xd7\xb3\0" + "\xd7\xa4\xd7\x91\xd7\xa8\xd7\xb3\0" + "\xd7\x90\xd7\xa4\xd7\xa8\xd7\xb3\0" + "\xd7\x90\xd7\x95\xd7\x92\xd7\xb3\0" + "\xd7\xa1\xd7\xa4\xd7\x98\xd7\xb3\0" + "\xd7\x90\xd7\x95\xd7\xa7\xd7\xb3\0" + "\xd7\xa0\xd7\x95\xd7\x91\xd7\xb3\0" + "\xd7\x93\xd7\xa6\xd7\x9e\xd7\xb3\0" + "vas\xc3\xa1rnap\0" + "h\xc3\xa9tf\xc5\x91\0" + "kedd\0" + "szerda\0" + "cs\xc3\xbct\xc3\xb6rt\xc3\xb6k\0" + "p\xc3\xa9ntek\0" + "szombat\0" + "H\0" + "Sze\0" + "Cs\0" + "Szo\0" + "Sz\0" + "janu\xc3\xa1r\0" + "febru\xc3\xa1r\0" + "m\xc3\xa1rcius\0" + "\xc3\xa1prilis\0" + "m\xc3\xa1jus\0" + "j\xc3\xbanius\0" + "j\xc3\xbalius\0" + "augusztus\0" + "szeptember\0" + "okt\xc3\xb3\x62\x65r\0" + "m\xc3\xa1rc.\0" + "\xc3\xa1pr.\0" + "m\xc3\xa1j.\0" + "j\xc3\xban.\0" + "j\xc3\xbal.\0" + "szept.\0" + "sunnudagur\0" + "m\xc3\xa1nudagur\0" + "\xc3\xberi\xc3\xb0judagur\0" + "mi\xc3\xb0vikudagur\0" + "fimmtudagur\0" + "f\xc3\xb6studagur\0" + "laugardagur\0" + "sun.\0" + "m\xc3\xa1n.\0" + "\xc3\xberi.\0" + "mi\xc3\xb0.\0" + "fim.\0" + "f\xc3\xb6s.\0" + "lau.\0" + "\xc3\x9e\0" + "jan\xc3\xba\x61r\0" + "febr\xc3\xba\x61r\0" + "apr\xc3\xadl\0" + "ma\xc3\xad\0" + "j\xc3\xban\xc3\xad\0" + "j\xc3\xbal\xc3\xad\0" + "\xc3\xa1g\xc3\xbast\0" + "n\xc3\xb3vember\0" + "desember\0" + "\xc3\xa1g\xc3\xba.\0" + "n\xc3\xb3v.\0" + "domenica\0" + "luned\xc3\xac\0" + "marted\xc3\xac\0" + "mercoled\xc3\xac\0" + "gioved\xc3\xac\0" + "venerd\xc3\xac\0" + "sabato\0" + "dom\0" + "lun\0" + "mar\0" + "mer\0" + "gio\0" + "ven\0" + "sab\0" + "G\0" + "gennaio\0" + "febbraio\0" + "aprile\0" + "maggio\0" + "giugno\0" + "luglio\0" + "settembre\0" + "ottobre\0" + "dicembre\0" + "gen\0" + "feb\0" + "apr\0" + "mag\0" + "giu\0" + "lug\0" + "ago\0" + "set\0" + "ott\0" + "nov\0" + "dic\0" + "\xe6\x97\xa5\xe6\x9b\x9c\xe6\x97\xa5\0" + "\xe6\x9c\x88\xe6\x9b\x9c\xe6\x97\xa5\0" + "\xe7\x81\xab\xe6\x9b\x9c\xe6\x97\xa5\0" + "\xe6\xb0\xb4\xe6\x9b\x9c\xe6\x97\xa5\0" + "\xe6\x9c\xa8\xe6\x9b\x9c\xe6\x97\xa5\0" + "\xe9\x87\x91\xe6\x9b\x9c\xe6\x97\xa5\0" + "\xe5\x9c\x9f\xe6\x9b\x9c\xe6\x97\xa5\0" + "\xe6\x9c\x88\0" + "\xe7\x81\xab\0" + "\xe6\xb0\xb4\0" + "\xe6\x9c\xa8\0" + "\xe9\x87\x91\0" + "\xe5\x9c\x9f\0" + "1\0" + "2\0" + "3\0" + "4\0" + "5\0" + "6\0" + "7\0" + "8\0" + "9\0" + "10\0" + "11\0" + "12\0" + "\xec\x9d\xbc\xec\x9a\x94\xec\x9d\xbc\0" + "\xec\x9b\x94\xec\x9a\x94\xec\x9d\xbc\0" + "\xed\x99\x94\xec\x9a\x94\xec\x9d\xbc\0" + "\xec\x88\x98\xec\x9a\x94\xec\x9d\xbc\0" + "\xeb\xaa\xa9\xec\x9a\x94\xec\x9d\xbc\0" + "\xea\xb8\x88\xec\x9a\x94\xec\x9d\xbc\0" + "\xed\x86\xa0\xec\x9a\x94\xec\x9d\xbc\0" + "\xec\x9d\xbc\0" + "\xec\x9b\x94\0" + "\xed\x99\x94\0" + "\xec\x88\x98\0" + "\xeb\xaa\xa9\0" + "\xea\xb8\x88\0" + "\xed\x86\xa0\0" + "1\xec\x9b\x94\0" + "2\xec\x9b\x94\0" + "3\xec\x9b\x94\0" + "4\xec\x9b\x94\0" + "5\xec\x9b\x94\0" + "6\xec\x9b\x94\0" + "7\xec\x9b\x94\0" + "8\xec\x9b\x94\0" + "9\xec\x9b\x94\0" + "10\xec\x9b\x94\0" + "11\xec\x9b\x94\0" + "12\xec\x9b\x94\0" + "zondag\0" + "maandag\0" + "dinsdag\0" + "woensdag\0" + "donderdag\0" + "vrijdag\0" + "zaterdag\0" + "zo\0" + "di\0" + "wo\0" + "do\0" + "vr\0" + "za\0" + "Z\0" + "januari\0" + "februari\0" + "maart\0" + "mei\0" + "augustus\0" + "mrt.\0" + "s\xc3\xb8n.\0" + "man.\0" + "tir.\0" + "ons.\0" + "tor.\0" + "fre.\0" + "l\xc3\xb8r.\0" + "jan\0" + "jun\0" + "jul\0" + "aug\0" + "sep\0" + "okt\0" + "des\0" + "niedziela\0" + "poniedzia\xc5\x82\x65k\0" + "wtorek\0" + "\xc5\x9broda\0" + "czwartek\0" + "pi\xc4\x85tek\0" + "niedz.\0" + "pon.\0" + "wt.\0" + "\xc5\x9br.\0" + "czw.\0" + "pt.\0" + "sob.\0" + "\xc5\x9a\0" + "C\0" + "stycze\xc5\x84\0" + "luty\0" + "marzec\0" + "kwiecie\xc5\x84\0" + "czerwiec\0" + "lipiec\0" + "sierpie\xc5\x84\0" + "wrzesie\xc5\x84\0" + "pa\xc5\xba\x64ziernik\0" + "grudzie\xc5\x84\0" + "stycznia\0" + "lutego\0" + "marca\0" + "kwietnia\0" + "maja\0" + "czerwca\0" + "lipca\0" + "sierpnia\0" + "wrze\xc5\x9bnia\0" + "pa\xc5\xba\x64ziernika\0" + "listopada\0" + "grudnia\0" + "sty\0" + "lut\0" + "kwi\0" + "cze\0" + "lip\0" + "sie\0" + "wrz\0" + "pa\xc5\xba\0" + "gru\0" + "segunda-feira\0" + "ter\xc3\xa7\x61-feira\0" + "quarta-feira\0" + "quinta-feira\0" + "sexta-feira\0" + "seg\0" + "ter\0" + "qua\0" + "qui\0" + "sex\0" + "s\xc3\xa1\x62\0" + "Q\0" + "janeiro\0" + "fevereiro\0" + "mar\xc3\xa7o\0" + "maio\0" + "junho\0" + "julho\0" + "setembro\0" + "outubro\0" + "novembro\0" + "dezembro\0" + "fev\0" + "abr\0" + "out\0" + "dez\0" + "dumengia\0" + "glindesdi\0" + "mesemna\0" + "gievgia\0" + "venderdi\0" + "sonda\0" + "du\0" + "gli\0" + "me\0" + "gie\0" + "ve\0" + "schaner\0" + "favrer\0" + "avrigl\0" + "matg\0" + "zercladur\0" + "fanadur\0" + "avust\0" + "settember\0" + "october\0" + "schan.\0" + "favr.\0" + "zercl.\0" + "fan.\0" + "sett.\0" + "duminic\xc4\x83\0" + "luni\0" + "mar\xc8\x9bi\0" + "miercuri\0" + "joi\0" + "vineri\0" + "s\xc3\xa2mb\xc4\x83t\xc4\x83\0" + "dum.\0" + "mie.\0" + "vin.\0" + "s\xc3\xa2m.\0" + "ianuarie\0" + "februarie\0" + "martie\0" + "aprilie\0" + "iunie\0" + "iulie\0" + "septembrie\0" + "octombrie\0" + "noiembrie\0" + "decembrie\0" + "ian.\0" + "iun.\0" + "iul.\0" + "\xd0\xb2\xd0\xbe\xd1\x81\xd0\xba\xd1\x80\xd0\xb5\xd1\x81\xd0\xb5\xd0\xbd\xd1\x8c\xd0\xb5\0" + "\xd0\xbf\xd0\xbe\xd0\xbd\xd0\xb5\xd0\xb4\xd0\xb5\xd0\xbb\xd1\x8c\xd0\xbd\xd0\xb8\xd0\xba\0" + "\xd1\x81\xd1\x80\xd0\xb5\xd0\xb4\xd0\xb0\0" + "\xd1\x87\xd0\xb5\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb3\0" + "\xd0\xbf\xd1\x8f\xd1\x82\xd0\xbd\xd0\xb8\xd1\x86\xd0\xb0\0" + "\xd1\x81\xd1\x83\xd0\xb1\xd0\xb1\xd0\xbe\xd1\x82\xd0\xb0\0" + "\xd0\xb2\xd1\x81\0" + "\xd0\x92\0" + "\xd0\x9f\0" + "\xd0\xa1\0" + "\xd0\xa7\0" + "\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8c\0" + "\xd1\x84\xd0\xb5\xd0\xb2\xd1\x80\xd0\xb0\xd0\xbb\xd1\x8c\0" + "\xd0\xb0\xd0\xbf\xd1\x80\xd0\xb5\xd0\xbb\xd1\x8c\0" + "\xd0\xb8\xd1\x8e\xd0\xbd\xd1\x8c\0" + "\xd0\xb8\xd1\x8e\xd0\xbb\xd1\x8c\0" + "\xd1\x81\xd0\xb5\xd0\xbd\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8c\0" + "\xd0\xbe\xd0\xba\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8c\0" + "\xd0\xbd\xd0\xbe\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8c\0" + "\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb0\xd0\xb1\xd1\x80\xd1\x8c\0" + "\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8f\0" + "\xd1\x84\xd0\xb5\xd0\xb2\xd1\x80\xd0\xb0\xd0\xbb\xd1\x8f\0" + "\xd0\xbc\xd0\xb0\xd1\x80\xd1\x82\xd0\xb0\0" + "\xd0\xb0\xd0\xbf\xd1\x80\xd0\xb5\xd0\xbb\xd1\x8f\0" + "\xd0\xbc\xd0\xb0\xd1\x8f\0" + "\xd0\xb8\xd1\x8e\xd0\xbd\xd1\x8f\0" + "\xd0\xb8\xd1\x8e\xd0\xbb\xd1\x8f\0" + "\xd0\xb0\xd0\xb2\xd0\xb3\xd1\x83\xd1\x81\xd1\x82\xd0\xb0\0" + "\xd1\x81\xd0\xb5\xd0\xbd\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8f\0" + "\xd0\xbe\xd0\xba\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8f\0" + "\xd0\xbd\xd0\xbe\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8f\0" + "\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb0\xd0\xb1\xd1\x80\xd1\x8f\0" + "\xd1\x8f\xd0\xbd\xd0\xb2.\0" + "\xd1\x84\xd0\xb5\xd0\xb2\xd1\x80.\0" + "\xd0\xb0\xd0\xbf\xd1\x80.\0" + "\xd0\xb0\xd0\xb2\xd0\xb3.\0" + "\xd1\x81\xd0\xb5\xd0\xbd\xd1\x82.\0" + "\xd0\xbe\xd0\xba\xd1\x82.\0" + "\xd0\xbd\xd0\xbe\xd1\x8f\xd0\xb1.\0" + "\xd0\xb4\xd0\xb5\xd0\xba.\0" + "nedjelja\0" + "ponedjeljak\0" + "utorak\0" + "srijeda\0" + "\xc4\x8d\x65tvrtak\0" + "petak\0" + "subota\0" + "ned\0" + "pon\0" + "uto\0" + "sri\0" + "\xc4\x8d\x65t\0" + "pet\0" + "sub\0" + "n\0" + "p\0" + "u\0" + "s\0" + "\xc4\x8d\0" + "sije\xc4\x8d\x61nj\0" + "velja\xc4\x8d\x61\0" + "o\xc5\xbeujak\0" + "travanj\0" + "svibanj\0" + "lipanj\0" + "srpanj\0" + "kolovoz\0" + "rujan\0" + "studeni\0" + "prosinac\0" + "sije\xc4\x8dnja\0" + "velja\xc4\x8d\x65\0" + "o\xc5\xbeujka\0" + "travnja\0" + "svibnja\0" + "lipnja\0" + "srpnja\0" + "kolovoza\0" + "rujna\0" + "studenoga\0" + "prosinca\0" + "sij\0" + "velj\0" + "o\xc5\xbeu\0" + "tra\0" + "svi\0" + "kol\0" + "ruj\0" + "stu\0" + "nede\xc4\xbe\x61\0" + "pondelok\0" + "utorok\0" + "streda\0" + "\xc5\xa1tvrtok\0" + "piatok\0" + "ut\0" + "\xc5\xa1t\0" + "pi\0" + "\xc5\xa1\0" + "marec\0" + "m\xc3\xa1j\0" + "j\xc3\xban\0" + "j\xc3\xbal\0" + "janu\xc3\xa1ra\0" + "febru\xc3\xa1ra\0" + "apr\xc3\xadla\0" + "m\xc3\xa1ja\0" + "j\xc3\xbana\0" + "j\xc3\xbala\0" + "augusta\0" + "septembra\0" + "okt\xc3\xb3\x62ra\0" + "novembra\0" + "decembra\0" + "dec\0" + "e diel\0" + "e h\xc3\xabn\xc3\xab\0" + "e mart\xc3\xab\0" + "e m\xc3\xabrkur\xc3\xab\0" + "e enjte\0" + "e premte\0" + "e shtun\xc3\xab\0" + "Die\0" + "H\xc3\xabn\0" + "M\xc3\xabr\0" + "Enj\0" + "Pre\0" + "Sht\0" + "E\0" + "Janar\0" + "Shkurt\0" + "Mars\0" + "Prill\0" + "Maj\0" + "Qershor\0" + "Korrik\0" + "Gusht\0" + "Shtator\0" + "Tetor\0" + "N\xc3\xabntor\0" + "Dhjetor\0" + "janar\0" + "shkurt\0" + "prill\0" + "qershor\0" + "korrik\0" + "gusht\0" + "shtator\0" + "tetor\0" + "n\xc3\xabntor\0" + "dhjetor\0" + "Shk\0" + "Pri\0" + "Qer\0" + "Kor\0" + "Gsh\0" + "Tet\0" + "N\xc3\xabn\0" + "Dhj\0" + "s\xc3\xb6ndag\0" + "m\xc3\xa5ndag\0" + "tisdag\0" + "l\xc3\xb6rdag\0" + "s\xc3\xb6n\0" + "m\xc3\xa5n\0" + "tis\0" + "tors\0" + "l\xc3\xb6r\0" + "augusti\0" + "Pazar\0" + "Pazartesi\0" + "Sal\xc4\xb1\0" + "\xc3\x87\x61r\xc5\x9f\x61mba\0" + "Per\xc5\x9f\x65mbe\0" + "Cuma\0" + "Cumartesi\0" + "Paz\0" + "Pzt\0" + "Sal\0" + "\xc3\x87\x61r\0" + "Per\0" + "Cum\0" + "Cmt\0" + "\xc3\x87\0" + "Ocak\0" + "\xc5\x9eubat\0" + "Mart\0" + "Nisan\0" + "May\xc4\xb1s\0" + "Haziran\0" + "Temmuz\0" + "A\xc4\x9fustos\0" + "Eyl\xc3\xbcl\0" + "Ekim\0" + "Kas\xc4\xb1m\0" + "Aral\xc4\xb1k\0" + "Oca\0" + "\xc5\x9eub\0" + "Nis\0" + "Haz\0" + "Tem\0" + "A\xc4\x9fu\0" + "Eyl\0" + "Eki\0" + "Kas\0" + "Ara\0" + "\xd8\xa7\xd8\xaa\xd9\x88\xd8\xa7\xd8\xb1\0" + "\xd8\xb3\xd9\x88\xd9\x85\xd9\x88\xd8\xa7\xd8\xb1\0" + "\xd9\x85\xd9\x86\xda\xaf\xd9\x84\0" + "\xd8\xa8\xd8\xaf\xda\xbe\0" + "\xd8\xac\xd9\x85\xd8\xb9\xd8\xb1\xd8\xa7\xd8\xaa\0" + "\xd8\xac\xd9\x85\xd8\xb9\xdb\x81\0" + "\xdb\x81\xd9\x81\xd8\xaa\xdb\x81\0" + "\xd8\xac\xd9\x86\xd9\x88\xd8\xb1\xdb\x8c\0" + "\xd9\x81\xd8\xb1\xd9\x88\xd8\xb1\xdb\x8c\0" + "\xd9\x85\xd8\xa7\xd8\xb1\xda\x86\0" + "\xd8\xa7\xd9\xbe\xd8\xb1\xdb\x8c\xd9\x84\0" + "\xd9\x85\xd8\xa6\xdb\x8c\0" + "\xd8\xac\xd9\x88\xd9\x86\0" + "\xd8\xac\xd9\x88\xd9\x84\xd8\xa7\xd8\xa6\xdb\x8c\0" + "\xd8\xa7\xda\xaf\xd8\xb3\xd8\xaa\0" + "\xd8\xb3\xd8\xaa\xd9\x85\xd8\xa8\xd8\xb1\0" + "\xd8\xa7\xda\xa9\xd8\xaa\xd9\x88\xd8\xa8\xd8\xb1\0" + "\xd9\x86\xd9\x88\xd9\x85\xd8\xa8\xd8\xb1\0" + "\xd8\xaf\xd8\xb3\xd9\x85\xd8\xa8\xd8\xb1\0" + "Minggu\0" + "Senin\0" + "Selasa\0" + "Rabu\0" + "Kamis\0" + "Jumat\0" + "Sabtu\0" + "Min\0" + "Sen\0" + "Sel\0" + "Rab\0" + "Kam\0" + "Jum\0" + "Sab\0" + "R\0" + "Januari\0" + "Februari\0" + "Maret\0" + "Mei\0" + "Agustus\0" + "Desember\0" + "Agt\0" + "Des\0" + "\xd0\xbd\xd0\xb5\xd0\xb4\xd1\x96\xd0\xbb\xd1\x8f\0" + "\xd0\xbf\xd0\xbe\xd0\xbd\xd0\xb5\xd0\xb4\xd1\x96\xd0\xbb\xd0\xbe\xd0\xba\0" + "\xd0\xb2\xd1\x96\xd0\xb2\xd1\x82\xd0\xbe\xd1\x80\xd0\xbe\xd0\xba\0" + "\xd1\x81\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb4\xd0\xb0\0" + "\xd1\x87\xd0\xb5\xd1\x82\xd0\xb2\xd0\xb5\xd1\x80\0" + "\xd0\xbf\xca\xbc\xd1\x8f\xd1\x82\xd0\xbd\xd0\xb8\xd1\x86\xd1\x8f\0" + "\xd1\x81\xd1\x83\xd0\xb1\xd0\xbe\xd1\x82\xd0\xb0\0" + "\xd0\x9d\0" + "\xd1\x81\xd1\x96\xd1\x87\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xbb\xd1\x8e\xd1\x82\xd0\xb8\xd0\xb9\0" + "\xd0\xb1\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb7\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xba\xd0\xb2\xd1\x96\xd1\x82\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd1\x82\xd1\x80\xd0\xb0\xd0\xb2\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd1\x87\xd0\xb5\xd1\x80\xd0\xb2\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xbb\xd0\xb8\xd0\xbf\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd1\x81\xd0\xb5\xd1\x80\xd0\xbf\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb5\xd1\x81\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xb6\xd0\xbe\xd0\xb2\xd1\x82\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xbb\xd0\xb8\xd1\x81\xd1\x82\xd0\xbe\xd0\xbf\xd0\xb0\xd0\xb4\0" + "\xd0\xb3\xd1\x80\xd1\x83\xd0\xb4\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd1\x81\xd1\x96\xd1\x87\xd0\xbd\xd1\x8f\0" + "\xd0\xbb\xd1\x8e\xd1\x82\xd0\xbe\xd0\xb3\xd0\xbe\0" + "\xd0\xb1\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb7\xd0\xbd\xd1\x8f\0" + "\xd0\xba\xd0\xb2\xd1\x96\xd1\x82\xd0\xbd\xd1\x8f\0" + "\xd1\x82\xd1\x80\xd0\xb0\xd0\xb2\xd0\xbd\xd1\x8f\0" + "\xd1\x87\xd0\xb5\xd1\x80\xd0\xb2\xd0\xbd\xd1\x8f\0" + "\xd0\xbb\xd0\xb8\xd0\xbf\xd0\xbd\xd1\x8f\0" + "\xd1\x81\xd0\xb5\xd1\x80\xd0\xbf\xd0\xbd\xd1\x8f\0" + "\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb5\xd1\x81\xd0\xbd\xd1\x8f\0" + "\xd0\xb6\xd0\xbe\xd0\xb2\xd1\x82\xd0\xbd\xd1\x8f\0" + "\xd0\xbb\xd0\xb8\xd1\x81\xd1\x82\xd0\xbe\xd0\xbf\xd0\xb0\xd0\xb4\xd0\xb0\0" + "\xd0\xb3\xd1\x80\xd1\x83\xd0\xb4\xd0\xbd\xd1\x8f\0" + "\xd1\x81\xd1\x96\xd1\x87\0" + "\xd0\xbb\xd1\x8e\xd1\x82\0" + "\xd0\xb1\xd0\xb5\xd1\x80\0" + "\xd0\xba\xd0\xb2\xd1\x96\0" + "\xd1\x82\xd1\x80\xd0\xb0\0" + "\xd1\x87\xd0\xb5\xd1\x80\0" + "\xd0\xbb\xd0\xb8\xd0\xbf\0" + "\xd1\x81\xd0\xb5\xd1\x80\0" + "\xd0\xb2\xd0\xb5\xd1\x80\0" + "\xd0\xb6\xd0\xbe\xd0\xb2\0" + "\xd0\xbb\xd0\xb8\xd1\x81\0" + "\xd0\xb3\xd1\x80\xd1\x83\0" + "\xd0\xbd\xd1\x8f\xd0\xb4\xd0\xb7\xd0\xb5\xd0\xbb\xd1\x8f\0" + "\xd0\xbf\xd0\xb0\xd0\xbd\xd1\x8f\xd0\xb4\xd0\xb7\xd0\xb5\xd0\xbb\xd0\xb0\xd0\xba\0" + "\xd0\xb0\xd1\x9e\xd1\x82\xd0\xbe\xd1\x80\xd0\xb0\xd0\xba\0" + "\xd1\x81\xd0\xb5\xd1\x80\xd0\xb0\xd0\xb4\xd0\xb0\0" + "\xd1\x87\xd0\xb0\xd1\x86\xd0\xb2\xd0\xb5\xd1\x80\0" + "\xd0\xbf\xd1\x8f\xd1\x82\xd0\xbd\xd1\x96\xd1\x86\xd0\xb0\0" + "\xd0\xb0\xd1\x9e\0" + "\xd1\x87\xd1\x86\0" + "\xd0\xb0\0" + "\xd1\x81\xd1\x82\xd1\x83\xd0\xb4\xd0\xb7\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xbb\xd1\x8e\xd1\x82\xd1\x8b\0" + "\xd1\x81\xd0\xb0\xd0\xba\xd0\xb0\xd0\xb2\xd1\x96\xd0\xba\0" + "\xd0\xba\xd1\x80\xd0\xb0\xd1\x81\xd0\xb0\xd0\xb2\xd1\x96\xd0\xba\0" + "\xd1\x87\xd1\x8d\xd1\x80\xd0\xb2\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xbb\xd1\x96\xd0\xbf\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xb6\xd0\xbd\xd1\x96\xd0\xb2\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb0\xd1\x81\xd0\xb5\xd0\xbd\xd1\x8c\0" + "\xd0\xba\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd1\x8b\xd1\x87\xd0\xbd\xd1\x96\xd0\xba\0" + "\xd0\xbb\xd1\x96\xd1\x81\xd1\x82\xd0\xb0\xd0\xbf\xd0\xb0\xd0\xb4\0" + "\xd1\x81\xd0\xbd\xd0\xb5\xd0\xb6\xd0\xb0\xd0\xbd\xd1\x8c\0" + "\xd1\x81\xd1\x82\xd1\x83\xd0\xb4\xd0\xb7\xd0\xb5\xd0\xbd\xd1\x8f\0" + "\xd0\xbb\xd1\x8e\xd1\x82\xd0\xb0\xd0\xb3\xd0\xb0\0" + "\xd1\x81\xd0\xb0\xd0\xba\xd0\xb0\xd0\xb2\xd1\x96\xd0\xba\xd0\xb0\0" + "\xd0\xba\xd1\x80\xd0\xb0\xd1\x81\xd0\xb0\xd0\xb2\xd1\x96\xd0\xba\xd0\xb0\0" + "\xd1\x87\xd1\x8d\xd1\x80\xd0\xb2\xd0\xb5\xd0\xbd\xd1\x8f\0" + "\xd0\xbb\xd1\x96\xd0\xbf\xd0\xb5\xd0\xbd\xd1\x8f\0" + "\xd0\xb6\xd0\xbd\xd1\x96\xd1\x9e\xd0\xbd\xd1\x8f\0" + "\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb0\xd1\x81\xd0\xbd\xd1\x8f\0" + "\xd0\xba\xd0\xb0\xd1\x81\xd1\x82\xd1\x80\xd1\x8b\xd1\x87\xd0\xbd\xd1\x96\xd0\xba\xd0\xb0\0" + "\xd0\xbb\xd1\x96\xd1\x81\xd1\x82\xd0\xb0\xd0\xbf\xd0\xb0\xd0\xb4\xd0\xb0\0" + "\xd1\x81\xd0\xbd\xd0\xb5\xd0\xb6\xd0\xbd\xd1\x8f\0" + "\xd1\x81\xd1\x82\xd1\x83\0" + "\xd1\x81\xd0\xb0\xd0\xba\0" + "\xd0\xba\xd1\x80\xd0\xb0\0" + "\xd1\x87\xd1\x8d\xd1\x80\0" + "\xd0\xbb\xd1\x96\xd0\xbf\0" + "\xd0\xb6\xd0\xbd\xd1\x96\0" + "\xd0\xba\xd0\xb0\xd1\x81\0" + "\xd0\xbb\xd1\x96\xd1\x81\0" + "\xd1\x81\xd0\xbd\xd0\xb5\0" + "nedelja\0" + "ponedeljek\0" + "torek\0" + "sreda\0" + "\xc4\x8d\x65trtek\0" + "petek\0" + "ned.\0" + "sre.\0" + "\xc4\x8d\x65t.\0" + "pet.\0" + "t\0" + "junij\0" + "julij\0" + "avgust\0" + "avg.\0" + "p\xc3\xbchap\xc3\xa4\x65v\0" + "esmasp\xc3\xa4\x65v\0" + "teisip\xc3\xa4\x65v\0" + "kolmap\xc3\xa4\x65v\0" + "neljap\xc3\xa4\x65v\0" + "reede\0" + "laup\xc3\xa4\x65v\0" + "jaanuar\0" + "veebruar\0" + "m\xc3\xa4rts\0" + "aprill\0" + "juuni\0" + "juuli\0" + "oktoober\0" + "detsember\0" + "jaan\0" + "veebr\0" + "sept\0" + "dets\0" + "sv\xc4\x93tdiena\0" + "pirmdiena\0" + "otrdiena\0" + "tre\xc5\xa1\x64iena\0" + "ceturtdiena\0" + "piektdiena\0" + "sestdiena\0" + "Sv\xc4\x93td.\0" + "Pirmd.\0" + "Otrd.\0" + "Tre\xc5\xa1\x64.\0" + "Ceturtd.\0" + "Piektd.\0" + "Sestd.\0" + "janv\xc4\x81ris\0" + "febru\xc4\x81ris\0" + "apr\xc4\xablis\0" + "maijs\0" + "j\xc5\xabnijs\0" + "j\xc5\xablijs\0" + "augusts\0" + "septembris\0" + "oktobris\0" + "novembris\0" + "decembris\0" + "j\xc5\xabn.\0" + "j\xc5\xabl.\0" + "sekmadienis\0" + "pirmadienis\0" + "antradienis\0" + "tre\xc4\x8diadienis\0" + "ketvirtadienis\0" + "penktadienis\0" + "\xc5\xa1\x65\xc5\xa1tadienis\0" + "sk\0" + "pr\0" + "an\0" + "tr\0" + "kt\0" + "pn\0" + "A\0" + "\xc5\xa0\0" + "sausis\0" + "vasaris\0" + "kovas\0" + "balandis\0" + "gegu\xc5\xbe\xc4\x97\0" + "bir\xc5\xbe\x65lis\0" + "liepa\0" + "rugpj\xc5\xabtis\0" + "rugs\xc4\x97jis\0" + "spalis\0" + "lapkritis\0" + "gruodis\0" + "sausio\0" + "vasario\0" + "kovo\0" + "baland\xc5\xbeio\0" + "gegu\xc5\xbe\xc4\x97s\0" + "bir\xc5\xbe\x65lio\0" + "liepos\0" + "rugpj\xc5\xab\xc4\x8dio\0" + "rugs\xc4\x97jo\0" + "spalio\0" + "lapkri\xc4\x8dio\0" + "gruod\xc5\xbeio\0" + "saus.\0" + "vas.\0" + "kov.\0" + "bal.\0" + "geg.\0" + "bir\xc5\xbe.\0" + "liep.\0" + "rugp.\0" + "rugs.\0" + "spal.\0" + "lapkr.\0" + "gruod.\0" + "\xd0\xaf\xd0\xba\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb5\0" + "\xd0\x94\xd1\x83\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb5\0" + "\xd0\xa1\xd0\xb5\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb5\0" + "\xd0\xa7\xd0\xbe\xd1\x80\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb5\0" + "\xd0\x9f\xd0\xb0\xd0\xbd\xd2\xb7\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb5\0" + "\xd2\xb6\xd1\x83\xd0\xbc\xd1\x8a\xd0\xb0\0" + "\xd0\xa8\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb5\0" + "\xd0\xaf\xd1\x88\xd0\xb1\0" + "\xd0\x94\xd1\x88\xd0\xb1\0" + "\xd0\xa1\xd1\x88\xd0\xb1\0" + "\xd0\xa7\xd1\x88\xd0\xb1\0" + "\xd0\x9f\xd1\x88\xd0\xb1\0" + "\xd2\xb6\xd0\xbc\xd1\x8a\0" + "\xd0\xa8\xd0\xbd\xd0\xb1\0" + "\xd0\xaf\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\0" + "\xd0\xa4\xd0\xb5\xd0\xb2\xd1\x80\xd0\xb0\xd0\xbb\0" + "\xd0\x9c\xd0\xb0\xd1\x80\xd1\x82\0" + "\xd0\x90\xd0\xbf\xd1\x80\xd0\xb5\xd0\xbb\0" + "\xd0\x9c\xd0\xb0\xd0\xb9\0" + "\xd0\x98\xd1\x8e\xd0\xbd\0" + "\xd0\x98\xd1\x8e\xd0\xbb\0" + "\xd0\x90\xd0\xb2\xd0\xb3\xd1\x83\xd1\x81\xd1\x82\0" + "\xd0\xa1\xd0\xb5\xd0\xbd\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\0" + "\xd0\x9e\xd0\xba\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\0" + "\xd0\x9d\xd0\xbe\xd1\x8f\xd0\xb1\xd1\x80\0" + "\xd0\x94\xd0\xb5\xd0\xba\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd0\xaf\xd0\xbd\xd0\xb2\0" + "\xd0\xa4\xd0\xb5\xd0\xb2\0" + "\xd0\x9c\xd0\xb0\xd1\x80\0" + "\xd0\x90\xd0\xbf\xd1\x80\0" + "\xd0\x90\xd0\xb2\xd0\xb3\0" + "\xd0\xa1\xd0\xb5\xd0\xbd\0" + "\xd0\x9e\xd0\xba\xd1\x82\0" + "\xd0\x9d\xd0\xbe\xd1\x8f\0" + "\xd0\x94\xd0\xb5\xd0\xba\0" + "\xdb\x8c\xda\xa9\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87\0" + "\xd8\xaf\xd9\x88\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87\0" + "\xd8\xb3\xd9\x87\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87\0" + "\xda\x86\xd9\x87\xd8\xa7\xd8\xb1\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87\0" + "\xd9\xbe\xd9\x86\xd8\xac\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87\0" + "\xd8\xac\xd9\x85\xd8\xb9\xd9\x87\0" + "\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87\0" + "\xdb\x8c\0" + "\xd8\xaf\0" + "\xd8\xb3\0" + "\xda\x86\0" + "\xd9\xbe\0" + "\xd8\xac\0" + "\xd8\xb4\0" + "\xda\x98\xd8\xa7\xd9\x86\xd9\x88\xdb\x8c\xd9\x87\0" + "\xd9\x81\xd9\x88\xd8\xb1\xdb\x8c\xd9\x87\0" + "\xd9\x85\xd8\xa7\xd8\xb1\xd8\xb3\0" + "\xd8\xa2\xd9\x88\xd8\xb1\xdb\x8c\xd9\x84\0" + "\xd9\x85\xd9\x87\0" + "\xda\x98\xd9\x88\xd8\xa6\xd9\x86\0" + "\xda\x98\xd9\x88\xd8\xa6\xdb\x8c\xd9\x87\0" + "\xd8\xa7\xd9\x88\xd8\xaa\0" + "\xd8\xb3\xd9\xbe\xd8\xaa\xd8\xa7\xd9\x85\xd8\xa8\xd8\xb1\0" + "\xd8\xa7\xda\xa9\xd8\xaa\xd8\xa8\xd8\xb1\0" + "\xd9\x86\xd9\x88\xd8\xa7\xd9\x85\xd8\xa8\xd8\xb1\0" + "\xd8\xaf\xd8\xb3\xd8\xa7\xd9\x85\xd8\xa8\xd8\xb1\0" + "\xda\x98\xd8\xa7\xd9\x86\xd9\x88\xdb\x8c\xd9\x87\xd9\x94\0" + "\xd9\x81\xd9\x88\xd8\xb1\xdb\x8c\xd9\x87\xd9\x94\0" + "\xd9\x85\xd9\x87\xd9\x94\0" + "\xda\x98\xd9\x88\xd8\xa6\xdb\x8c\xd9\x87\xd9\x94\0" + "Ch\xe1\xbb\xa7 Nh\xe1\xba\xadt\0" + "Th\xe1\xbb\xa9 Hai\0" + "Th\xe1\xbb\xa9 Ba\0" + "Th\xe1\xbb\xa9 T\xc6\xb0\0" + "Th\xe1\xbb\xa9 N\xc4\x83m\0" + "Th\xe1\xbb\xa9 S\xc3\xa1u\0" + "Th\xe1\xbb\xa9 B\xe1\xba\xa3y\0" + "CN\0" + "Th 2\0" + "Th 3\0" + "Th 4\0" + "Th 5\0" + "Th 6\0" + "Th 7\0" + "T2\0" + "T3\0" + "T4\0" + "T5\0" + "T6\0" + "T7\0" + "Th\xc3\xa1ng 1\0" + "Th\xc3\xa1ng 2\0" + "Th\xc3\xa1ng 3\0" + "Th\xc3\xa1ng 4\0" + "Th\xc3\xa1ng 5\0" + "Th\xc3\xa1ng 6\0" + "Th\xc3\xa1ng 7\0" + "Th\xc3\xa1ng 8\0" + "Th\xc3\xa1ng 9\0" + "Th\xc3\xa1ng 10\0" + "Th\xc3\xa1ng 11\0" + "Th\xc3\xa1ng 12\0" + "th\xc3\xa1ng 1\0" + "th\xc3\xa1ng 2\0" + "th\xc3\xa1ng 3\0" + "th\xc3\xa1ng 4\0" + "th\xc3\xa1ng 5\0" + "th\xc3\xa1ng 6\0" + "th\xc3\xa1ng 7\0" + "th\xc3\xa1ng 8\0" + "th\xc3\xa1ng 9\0" + "th\xc3\xa1ng 10\0" + "th\xc3\xa1ng 11\0" + "th\xc3\xa1ng 12\0" + "Thg 1\0" + "Thg 2\0" + "Thg 3\0" + "Thg 4\0" + "Thg 5\0" + "Thg 6\0" + "Thg 7\0" + "Thg 8\0" + "Thg 9\0" + "Thg 10\0" + "Thg 11\0" + "Thg 12\0" + "\xd5\xaf\xd5\xab\xd6\x80\xd5\xa1\xd5\xaf\xd5\xab\0" + "\xd5\xa5\xd6\x80\xd5\xaf\xd5\xb8\xd6\x82\xd5\xb7\xd5\xa1\xd5\xa2\xd5\xa9\xd5\xab\0" + "\xd5\xa5\xd6\x80\xd5\xa5\xd6\x84\xd5\xb7\xd5\xa1\xd5\xa2\xd5\xa9\xd5\xab\0" + "\xd5\xb9\xd5\xb8\xd6\x80\xd5\xa5\xd6\x84\xd5\xb7\xd5\xa1\xd5\xa2\xd5\xa9\xd5\xab\0" + "\xd5\xb0\xd5\xab\xd5\xb6\xd5\xa3\xd5\xb7\xd5\xa1\xd5\xa2\xd5\xa9\xd5\xab\0" + "\xd5\xb8\xd6\x82\xd6\x80\xd5\xa2\xd5\xa1\xd5\xa9\0" + "\xd5\xb7\xd5\xa1\xd5\xa2\xd5\xa1\xd5\xa9\0" + "\xd5\xaf\xd5\xab\xd6\x80\0" + "\xd5\xa5\xd6\x80\xd5\xaf\0" + "\xd5\xa5\xd6\x80\xd6\x84\0" + "\xd5\xb9\xd6\x80\xd6\x84\0" + "\xd5\xb0\xd5\xb6\xd5\xa3\0" + "\xd5\xb8\xd6\x82\xd6\x80\0" + "\xd5\xb7\xd5\xa2\xd5\xa9\0" + "\xd4\xbf\0" + "\xd4\xb5\0" + "\xd5\x89\0" + "\xd5\x80\0" + "\xd5\x88\0" + "\xd5\x87\0" + "\xd5\xb0\xd5\xb8\xd6\x82\xd5\xb6\xd5\xbe\xd5\xa1\xd6\x80\0" + "\xd6\x83\xd5\xa5\xd5\xbf\xd6\x80\xd5\xbe\xd5\xa1\xd6\x80\0" + "\xd5\xb4\xd5\xa1\xd6\x80\xd5\xbf\0" + "\xd5\xa1\xd5\xba\xd6\x80\xd5\xab\xd5\xac\0" + "\xd5\xb4\xd5\xa1\xd5\xb5\xd5\xab\xd5\xbd\0" + "\xd5\xb0\xd5\xb8\xd6\x82\xd5\xb6\xd5\xab\xd5\xbd\0" + "\xd5\xb0\xd5\xb8\xd6\x82\xd5\xac\xd5\xab\xd5\xbd\0" + "\xd6\x85\xd5\xa3\xd5\xb8\xd5\xbd\xd5\xbf\xd5\xb8\xd5\xbd\0" + "\xd5\xbd\xd5\xa5\xd5\xba\xd5\xbf\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\0" + "\xd5\xb0\xd5\xb8\xd5\xaf\xd5\xbf\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\0" + "\xd5\xb6\xd5\xb8\xd5\xb5\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\0" + "\xd5\xa4\xd5\xa5\xd5\xaf\xd5\xbf\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\0" + "\xd5\xb0\xd5\xb8\xd6\x82\xd5\xb6\xd5\xbe\xd5\xa1\xd6\x80\xd5\xab\0" + "\xd6\x83\xd5\xa5\xd5\xbf\xd6\x80\xd5\xbe\xd5\xa1\xd6\x80\xd5\xab\0" + "\xd5\xb4\xd5\xa1\xd6\x80\xd5\xbf\xd5\xab\0" + "\xd5\xa1\xd5\xba\xd6\x80\xd5\xab\xd5\xac\xd5\xab\0" + "\xd5\xb4\xd5\xa1\xd5\xb5\xd5\xab\xd5\xbd\xd5\xab\0" + "\xd5\xb0\xd5\xb8\xd6\x82\xd5\xb6\xd5\xab\xd5\xbd\xd5\xab\0" + "\xd5\xb0\xd5\xb8\xd6\x82\xd5\xac\xd5\xab\xd5\xbd\xd5\xab\0" + "\xd6\x85\xd5\xa3\xd5\xb8\xd5\xbd\xd5\xbf\xd5\xb8\xd5\xbd\xd5\xab\0" + "\xd5\xbd\xd5\xa5\xd5\xba\xd5\xbf\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\xd5\xab\0" + "\xd5\xb0\xd5\xb8\xd5\xaf\xd5\xbf\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\xd5\xab\0" + "\xd5\xb6\xd5\xb8\xd5\xb5\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\xd5\xab\0" + "\xd5\xa4\xd5\xa5\xd5\xaf\xd5\xbf\xd5\xa5\xd5\xb4\xd5\xa2\xd5\xa5\xd6\x80\xd5\xab\0" + "\xd5\xb0\xd5\xb6\xd5\xbe\0" + "\xd6\x83\xd5\xbf\xd5\xbe\0" + "\xd5\xb4\xd6\x80\xd5\xbf\0" + "\xd5\xa1\xd5\xba\xd6\x80\0" + "\xd5\xb4\xd5\xb5\xd5\xbd\0" + "\xd5\xb0\xd5\xb6\xd5\xbd\0" + "\xd5\xb0\xd5\xac\xd5\xbd\0" + "\xd6\x85\xd5\xa3\xd5\xbd\0" + "\xd5\xbd\xd5\xa5\xd5\xba\0" + "\xd5\xb0\xd5\xb8\xd5\xaf\0" + "\xd5\xb6\xd5\xb8\xd5\xb5\0" + "\xd5\xa4\xd5\xa5\xd5\xaf\0" + "bazar\0" + "bazar ert\xc9\x99si\0" + "\xc3\xa7\xc9\x99r\xc5\x9f\xc9\x99nb\xc9\x99 ax\xc5\x9f\x61m\xc4\xb1\0" + "\xc3\xa7\xc9\x99r\xc5\x9f\xc9\x99nb\xc9\x99\0" + "c\xc3\xbcm\xc9\x99 ax\xc5\x9f\x61m\xc4\xb1\0" + "c\xc3\xbcm\xc9\x99\0" + "\xc5\x9f\xc9\x99nb\xc9\x99\0" + "B.\0" + "B.E.\0" + "\xc3\x87.A.\0" + "\xc3\x87.\0" + "C.A.\0" + "C.\0" + "\xc5\x9e.\0" + "Yanvar\0" + "Fevral\0" + "Aprel\0" + "\xc4\xb0yun\0" + "\xc4\xb0yul\0" + "Avqust\0" + "Sentyabr\0" + "Oktyabr\0" + "Noyabr\0" + "Dekabr\0" + "yanvar\0" + "fevral\0" + "mart\0" + "aprel\0" + "may\0" + "iyun\0" + "iyul\0" + "avqust\0" + "sentyabr\0" + "oktyabr\0" + "noyabr\0" + "dekabr\0" + "yan\0" + "iyn\0" + "iyl\0" + "avq\0" + "sen\0" + "noy\0" + "dek\0" + "igandea\0" + "astelehena\0" + "asteartea\0" + "asteazkena\0" + "osteguna\0" + "ostirala\0" + "larunbata\0" + "ig.\0" + "al.\0" + "ar.\0" + "az.\0" + "og.\0" + "or.\0" + "lr.\0" + "I\0" + "urtarrila\0" + "Otsaila\0" + "Martxoa\0" + "Apirila\0" + "Maiatza\0" + "Ekaina\0" + "Uztaila\0" + "Abuztua\0" + "Iraila\0" + "Urria\0" + "Azaroa\0" + "Abendua\0" + "otsaila\0" + "martxoa\0" + "apirila\0" + "maiatza\0" + "ekaina\0" + "uztaila\0" + "abuztua\0" + "iraila\0" + "urria\0" + "azaroa\0" + "abendua\0" + "urt.\0" + "ots.\0" + "api.\0" + "mai.\0" + "eka.\0" + "uzt.\0" + "abu.\0" + "ira.\0" + "urr.\0" + "aza.\0" + "abe.\0" + "njed\xc5\xba\x65la\0" + "p\xc3\xb3nd\xc5\xba\x65la\0" + "wutora\0" + "srjeda\0" + "\xc5\xa1tw\xc3\xb3rtk\0" + "pjatk\0" + "nje\0" + "p\xc3\xb3n\0" + "wut\0" + "srj\0" + "\xc5\xa1tw\0" + "pja\0" + "sob\0" + "w\0" + "m\xc4\x9brc\0" + "apryl\0" + "meja\0" + "awgust\0" + "nowember\0" + "januara\0" + "februara\0" + "m\xc4\x9brca\0" + "apryla\0" + "meje\0" + "junija\0" + "julija\0" + "awgusta\0" + "oktobra\0" + "nowembra\0" + "m\xc4\x9br\0" + "mej\0" + "awg\0" + "now\0" + "\xd0\xbd\xd0\xb5\xd0\xb4\xd0\xb5\xd0\xbb\xd0\xb0\0" + "\xd1\x87\xd0\xb5\xd1\x82\xd0\xb2\xd1\x80\xd1\x82\xd0\xbe\xd0\xba\0" + "\xd0\xbf\xd0\xb5\xd1\x82\xd0\xbe\xd0\xba\0" + "\xd1\x81\xd0\xb0\xd0\xb1\xd0\xbe\xd1\x82\xd0\xb0\0" + "\xd0\xbd\xd0\xb5\xd0\xb4.\0" + "\xd0\xbf\xd0\xbe\xd0\xbd.\0" + "\xd0\xb2\xd1\x82\xd0\xbe.\0" + "\xd1\x81\xd1\x80\xd0\xb5.\0" + "\xd1\x87\xd0\xb5\xd1\x82.\0" + "\xd0\xbf\xd0\xb5\xd1\x82.\0" + "\xd1\x81\xd0\xb0\xd0\xb1.\0" + "\xd1\x98\xd0\xb0\xd0\xbd\xd1\x83\xd0\xb0\xd1\x80\xd0\xb8\0" + "\xd0\xbc\xd0\xb0\xd1\x98\0" + "\xd1\x98\xd1\x83\xd0\xbd\xd0\xb8\0" + "\xd1\x98\xd1\x83\xd0\xbb\xd0\xb8\0" + "\xd1\x98\xd0\xb0\xd0\xbd.\0" + "\xd1\x84\xd0\xb5\xd0\xb2.\0" + "\xd0\xbc\xd0\xb0\xd1\x80.\0" + "\xd1\x98\xd1\x83\xd0\xbd.\0" + "\xd1\x98\xd1\x83\xd0\xbb.\0" + "\xd1\x81\xd0\xb5\xd0\xbf\xd1\x82.\0" + "\xd0\xbd\xd0\xbe\xd0\xb5\xd0\xbc.\0" + "Sontaha\0" + "Mmantaha\0" + "Labobedi\0" + "Laboraru\0" + "Labone\0" + "Labohlane\0" + "Moqebelo\0" + "Son\0" + "Mma\0" + "Bed\0" + "Rar\0" + "Ne\0" + "Hla\0" + "Moq\0" + "Phesekgong\0" + "Hlakola\0" + "Hlakubele\0" + "Mmese\0" + "Motsheanong\0" + "Phupjane\0" + "Phupu\0" + "Phata\0" + "Leotshe\0" + "Mphalane\0" + "Pundungwane\0" + "Tshitwe\0" + "Phe\0" + "Kol\0" + "Ube\0" + "Mme\0" + "Mot\0" + "Upu\0" + "Pha\0" + "Leo\0" + "Mph\0" + "Pun\0" + "Tsh\0" + "Sonto\0" + "Musumbhunuku\0" + "Ravumbirhi\0" + "Ravunharhu\0" + "Ravumune\0" + "Ravuntlhanu\0" + "Mugqivela\0" + "Mus\0" + "Bir\0" + "Har\0" + "Tlh\0" + "Mug\0" + "Sunguti\0" + "Nyenyenyani\0" + "Nyenyankulu\0" + "Dzivamisoko\0" + "Mudyaxihi\0" + "Khotavuxika\0" + "Mawuwani\0" + "Mhawuri\0" + "Ndzhati\0" + "Nhlangula\0" + "Hukuri\0" + "N'wendzamhala\0" + "Yan\0" + "Kul\0" + "Dzi\0" + "Mud\0" + "Kho\0" + "Maw\0" + "Mha\0" + "Ndz\0" + "Nhl\0" + "Huk\0" + "N'w\0" + "Tshipi\0" + "Mosopulogo\0" + "Laboraro\0" + "Labotlhano\0" + "Matlhatso\0" + "Mos\0" + "Tla\0" + "Mat\0" + "Ferikgong\0" + "Tlhakole\0" + "Mopitlo\0" + "Moranang\0" + "Motsheganang\0" + "Seetebosigo\0" + "Phukwi\0" + "Phatwe\0" + "Lwetse\0" + "Diphalane\0" + "Ngwanatsele\0" + "Sedimonthole\0" + "Fer\0" + "Mop\0" + "Mor\0" + "See\0" + "Phu\0" + "Lwe\0" + "Dip\0" + "Ngw\0" + "Sed\0" + "Cawe\0" + "Mvulo\0" + "Lwesibini\0" + "Lwesithathu\0" + "Lwesine\0" + "Lwesihlanu\0" + "Mgqibelo\0" + "Caw\0" + "Mvu\0" + "Bin\0" + "Tha\0" + "Sin\0" + "Mgq\0" + "Janyuwari\0" + "Februwari\0" + "Matshi\0" + "Epreli\0" + "Meyi\0" + "Julayi\0" + "Agasti\0" + "Septemba\0" + "Okthoba\0" + "Novemba\0" + "Disemba\0" + "Epr\0" + "Mey\0" + "Aga\0" + "Dis\0" + "ISonto\0" + "UMsombuluko\0" + "ULwesibili\0" + "ULwesithathu\0" + "ULwesine\0" + "ULwesihlanu\0" + "UMgqibelo\0" + "Mso\0" + "Bil\0" + "B\0" + "Januwari\0" + "Mashi\0" + "Ephreli\0" + "Septhemba\0" + "UMasingana\0" + "Mas\0" + "Eph\0" + "Sondag\0" + "Maandag\0" + "Dinsdag\0" + "Woensdag\0" + "Donderdag\0" + "Vrydag\0" + "Saterdag\0" + "So.\0" + "Ma.\0" + "Di.\0" + "Wo.\0" + "Do.\0" + "Vr.\0" + "Sa.\0" + "Januarie\0" + "Februarie\0" + "Maart\0" + "Junie\0" + "Julie\0" + "Augustus\0" + "Jan.\0" + "Feb.\0" + "Mrt.\0" + "Apr.\0" + "Jun.\0" + "Jul.\0" + "Aug.\0" + "Sep.\0" + "Okt.\0" + "Nov.\0" + "Des.\0" + "\xe1\x83\x99\xe1\x83\x95\xe1\x83\x98\xe1\x83\xa0\xe1\x83\x90\0" + "\xe1\x83\x9d\xe1\x83\xa0\xe1\x83\xa8\xe1\x83\x90\xe1\x83\x91\xe1\x83\x90\xe1\x83\x97\xe1\x83\x98\0" + "\xe1\x83\xa1\xe1\x83\x90\xe1\x83\x9b\xe1\x83\xa8\xe1\x83\x90\xe1\x83\x91\xe1\x83\x90\xe1\x83\x97\xe1\x83\x98\0" + "\xe1\x83\x9d\xe1\x83\x97\xe1\x83\xae\xe1\x83\xa8\xe1\x83\x90\xe1\x83\x91\xe1\x83\x90\xe1\x83\x97\xe1\x83\x98\0" + "\xe1\x83\xae\xe1\x83\xa3\xe1\x83\x97\xe1\x83\xa8\xe1\x83\x90\xe1\x83\x91\xe1\x83\x90\xe1\x83\x97\xe1\x83\x98\0" + "\xe1\x83\x9e\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x90\xe1\x83\xa1\xe1\x83\x99\xe1\x83\x94\xe1\x83\x95\xe1\x83\x98\0" + "\xe1\x83\xa8\xe1\x83\x90\xe1\x83\x91\xe1\x83\x90\xe1\x83\x97\xe1\x83\x98\0" + "\xe1\x83\x99\xe1\x83\x95\xe1\x83\x98\0" + "\xe1\x83\x9d\xe1\x83\xa0\xe1\x83\xa8\0" + "\xe1\x83\xa1\xe1\x83\x90\xe1\x83\x9b\0" + "\xe1\x83\x9d\xe1\x83\x97\xe1\x83\xae\0" + "\xe1\x83\xae\xe1\x83\xa3\xe1\x83\x97\0" + "\xe1\x83\x9e\xe1\x83\x90\xe1\x83\xa0\0" + "\xe1\x83\xa8\xe1\x83\x90\xe1\x83\x91\0" + "\xe1\x83\x99\0" + "\xe1\x83\x9d\0" + "\xe1\x83\xa1\0" + "\xe1\x83\xae\0" + "\xe1\x83\x9e\0" + "\xe1\x83\xa8\0" + "\xe1\x83\x98\xe1\x83\x90\xe1\x83\x9c\xe1\x83\x95\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x98\0" + "\xe1\x83\x97\xe1\x83\x94\xe1\x83\x91\xe1\x83\x94\xe1\x83\xa0\xe1\x83\x95\xe1\x83\x90\xe1\x83\x9a\xe1\x83\x98\0" + "\xe1\x83\x9b\xe1\x83\x90\xe1\x83\xa0\xe1\x83\xa2\xe1\x83\x98\0" + "\xe1\x83\x90\xe1\x83\x9e\xe1\x83\xa0\xe1\x83\x98\xe1\x83\x9a\xe1\x83\x98\0" + "\xe1\x83\x9b\xe1\x83\x90\xe1\x83\x98\xe1\x83\xa1\xe1\x83\x98\0" + "\xe1\x83\x98\xe1\x83\x95\xe1\x83\x9c\xe1\x83\x98\xe1\x83\xa1\xe1\x83\x98\0" + "\xe1\x83\x98\xe1\x83\x95\xe1\x83\x9a\xe1\x83\x98\xe1\x83\xa1\xe1\x83\x98\0" + "\xe1\x83\x90\xe1\x83\x92\xe1\x83\x95\xe1\x83\x98\xe1\x83\xa1\xe1\x83\xa2\xe1\x83\x9d\0" + "\xe1\x83\xa1\xe1\x83\x94\xe1\x83\xa5\xe1\x83\xa2\xe1\x83\x94\xe1\x83\x9b\xe1\x83\x91\xe1\x83\x94\xe1\x83\xa0\xe1\x83\x98\0" + "\xe1\x83\x9d\xe1\x83\xa5\xe1\x83\xa2\xe1\x83\x9d\xe1\x83\x9b\xe1\x83\x91\xe1\x83\x94\xe1\x83\xa0\xe1\x83\x98\0" + "\xe1\x83\x9c\xe1\x83\x9d\xe1\x83\x94\xe1\x83\x9b\xe1\x83\x91\xe1\x83\x94\xe1\x83\xa0\xe1\x83\x98\0" + "\xe1\x83\x93\xe1\x83\x94\xe1\x83\x99\xe1\x83\x94\xe1\x83\x9b\xe1\x83\x91\xe1\x83\x94\xe1\x83\xa0\xe1\x83\x98\0" + "\xe1\x83\x98\xe1\x83\x90\xe1\x83\x9c\0" + "\xe1\x83\x97\xe1\x83\x94\xe1\x83\x91\0" + "\xe1\x83\x9b\xe1\x83\x90\xe1\x83\xa0\0" + "\xe1\x83\x90\xe1\x83\x9e\xe1\x83\xa0\0" + "\xe1\x83\x9b\xe1\x83\x90\xe1\x83\x98\0" + "\xe1\x83\x98\xe1\x83\x95\xe1\x83\x9c\0" + "\xe1\x83\x98\xe1\x83\x95\xe1\x83\x9a\0" + "\xe1\x83\x90\xe1\x83\x92\xe1\x83\x95\0" + "\xe1\x83\xa1\xe1\x83\x94\xe1\x83\xa5\0" + "\xe1\x83\x9d\xe1\x83\xa5\xe1\x83\xa2\0" + "\xe1\x83\x9c\xe1\x83\x9d\xe1\x83\x94\0" + "\xe1\x83\x93\xe1\x83\x94\xe1\x83\x99\0" + "m\xc3\xa1nadagur\0" + "t\xc3\xbdsdagur\0" + "mikudagur\0" + "h\xc3\xb3sdagur\0" + "fr\xc3\xadggjadagur\0" + "leygardagur\0" + "sun\0" + "m\xc3\xa1n\0" + "t\xc3\xbds\0" + "mik\0" + "h\xc3\xb3s\0" + "fr\xc3\xad\0" + "ley\0" + "\xe0\xa4\xb0\xe0\xa4\xb5\xe0\xa4\xbf\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xb8\xe0\xa5\x8b\xe0\xa4\xae\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xae\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xb2\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xac\xe0\xa5\x81\xe0\xa4\xa7\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\x97\xe0\xa5\x81\xe0\xa4\xb0\xe0\xa5\x81\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xb6\xe0\xa5\x81\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xb6\xe0\xa4\xa8\xe0\xa4\xbf\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xb0\xe0\xa4\xb5\xe0\xa4\xbf\0" + "\xe0\xa4\xb8\xe0\xa5\x8b\xe0\xa4\xae\0" + "\xe0\xa4\xae\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xb2\0" + "\xe0\xa4\xac\xe0\xa5\x81\xe0\xa4\xa7\0" + "\xe0\xa4\x97\xe0\xa5\x81\xe0\xa4\xb0\xe0\xa5\x81\0" + "\xe0\xa4\xb6\xe0\xa5\x81\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\0" + "\xe0\xa4\xb6\xe0\xa4\xa8\xe0\xa4\xbf\0" + "\xe0\xa4\xb0\0" + "\xe0\xa4\xb8\xe0\xa5\x8b\0" + "\xe0\xa4\xae\xe0\xa4\x82\0" + "\xe0\xa4\xac\xe0\xa5\x81\0" + "\xe0\xa4\x97\xe0\xa5\x81\0" + "\xe0\xa4\xb6\xe0\xa5\x81\0" + "\xe0\xa4\xb6\0" + "\xe0\xa4\x9c\xe0\xa4\xa8\xe0\xa4\xb5\xe0\xa4\xb0\xe0\xa5\x80\0" + "\xe0\xa4\xab\xe0\xa4\xbc\xe0\xa4\xb0\xe0\xa4\xb5\xe0\xa4\xb0\xe0\xa5\x80\0" + "\xe0\xa4\xae\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\x9a\0" + "\xe0\xa4\x85\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x88\xe0\xa4\xb2\0" + "\xe0\xa4\xae\xe0\xa4\x88\0" + "\xe0\xa4\x9c\xe0\xa5\x82\xe0\xa4\xa8\0" + "\xe0\xa4\x9c\xe0\xa5\x81\xe0\xa4\xb2\xe0\xa4\xbe\xe0\xa4\x88\0" + "\xe0\xa4\x85\xe0\xa4\x97\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\0" + "\xe0\xa4\xb8\xe0\xa4\xbf\xe0\xa4\xa4\xe0\xa4\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\x85\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\xa8\xe0\xa4\xb5\xe0\xa4\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\xa6\xe0\xa4\xbf\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\x9c\xe0\xa4\xa8\xe0\xa5\xb0\0" + "\xe0\xa4\xab\xe0\xa4\xbc\xe0\xa4\xb0\xe0\xa5\xb0\0" + "\xe0\xa4\x9c\xe0\xa5\x81\xe0\xa4\xb2\xe0\xa5\xb0\0" + "\xe0\xa4\x85\xe0\xa4\x97\xe0\xa5\xb0\0" + "\xe0\xa4\xb8\xe0\xa4\xbf\xe0\xa4\xa4\xe0\xa5\xb0\0" + "\xe0\xa4\x85\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x82\xe0\xa5\xb0\0" + "\xe0\xa4\xa8\xe0\xa4\xb5\xe0\xa5\xb0\0" + "\xe0\xa4\xa6\xe0\xa4\xbf\xe0\xa4\xb8\xe0\xa5\xb0\0" + "Il-\xc4\xa6\x61\x64\x64\0" + "It-Tnejn\0" + "It-Tlieta\0" + "L-Erbg\xc4\xa7\x61\0" + "Il-\xc4\xa6\x61mis\0" + "Il-\xc4\xa0img\xc4\xa7\x61\0" + "Is-Sibt\0" + "\xc4\xa6\x61\x64\0" + "Tne\0" + "Tli\0" + "Erb\0" + "\xc4\xa6\x61m\0" + "\xc4\xa0im\0" + "Sib\0" + "\xc4\xa6\x64\0" + "Tn\0" + "Tl\0" + "Er\0" + "\xc4\xa6m\0" + "\xc4\xa0m\0" + "Sb\0" + "Jannar\0" + "Frar\0" + "Marzu\0" + "Mejju\0" + "\xc4\xa0unju\0" + "Lulju\0" + "Awwissu\0" + "Settembru\0" + "Ottubru\0" + "Novembru\0" + "Di\xc4\x8b\x65mbru\0" + "Fra\0" + "Mej\0" + "\xc4\xa0un\0" + "Lul\0" + "Aww\0" + "Set\0" + "Ott\0" + "Di\xc4\x8b\0" + "sotnabeaivi\0" + "vuoss\xc3\xa1rga\0" + "ma\xc5\x8b\xc5\x8b\x65\x62\xc3\xa1rga\0" + "gaskavahkku\0" + "duorasdat\0" + "bearjadat\0" + "l\xc3\xa1vvardat\0" + "sotn\0" + "vuos\0" + "ma\xc5\x8b\0" + "gask\0" + "duor\0" + "bear\0" + "l\xc3\xa1v\0" + "o\xc4\x91\xc4\x91\x61jagem\xc3\xa1nnu\0" + "guovvam\xc3\xa1nnu\0" + "njuk\xc4\x8d\x61m\xc3\xa1nnu\0" + "cuo\xc5\x8bom\xc3\xa1nnu\0" + "miessem\xc3\xa1nnu\0" + "geassem\xc3\xa1nnu\0" + "suoidnem\xc3\xa1nnu\0" + "borgem\xc3\xa1nnu\0" + "\xc4\x8d\x61k\xc4\x8d\x61m\xc3\xa1nnu\0" + "golggotm\xc3\xa1nnu\0" + "sk\xc3\xa1\x62mam\xc3\xa1nnu\0" + "juovlam\xc3\xa1nnu\0" + "o\xc4\x91\xc4\x91j\0" + "guov\0" + "njuk\0" + "cuo\0" + "mies\0" + "geas\0" + "suoi\0" + "borg\0" + "\xc4\x8d\x61k\xc4\x8d\0" + "golg\0" + "sk\xc3\xa1\x62\0" + "juov\0" + "D\xc3\xa9 Domhnaigh\0" + "D\xc3\xa9 Luain\0" + "D\xc3\xa9 M\xc3\xa1irt\0" + "D\xc3\xa9 C\xc3\xa9\x61\x64\x61oin\0" + "D\xc3\xa9\x61rdaoin\0" + "D\xc3\xa9 hAoine\0" + "D\xc3\xa9 Sathairn\0" + "Domh\0" + "Luan\0" + "M\xc3\xa1irt\0" + "C\xc3\xa9\x61\x64\0" + "D\xc3\xa9\x61r\0" + "Aoine\0" + "Sath\0" + "Ean\xc3\xa1ir\0" + "Feabhra\0" + "M\xc3\xa1rta\0" + "Aibre\xc3\xa1n\0" + "Bealtaine\0" + "Meitheamh\0" + "I\xc3\xbail\0" + "L\xc3\xbanasa\0" + "Me\xc3\xa1n F\xc3\xb3mhair\0" + "Deireadh F\xc3\xb3mhair\0" + "Samhain\0" + "Nollaig\0" + "Ean\0" + "Feabh\0" + "Aib\0" + "Beal\0" + "Meith\0" + "L\xc3\xban\0" + "MF\xc3\xb3mh\0" + "DF\xc3\xb3mh\0" + "Samh\0" + "Noll\0" + "Ahad\0" + "Isnin\0" + "Khamis\0" + "Jumaat\0" + "Ahd\0" + "Isn\0" + "Kha\0" + "Mac\0" + "Julai\0" + "Ogos\0" + "Disember\0" + "Ogo\0" + "\xd0\xb6\xd0\xb5\xd0\xba\xd1\x81\xd0\xb5\xd0\xbd\xd0\xb1\xd1\x96\0" + "\xd0\xb4\xd2\xaf\xd0\xb9\xd1\x81\xd0\xb5\xd0\xbd\xd0\xb1\xd1\x96\0" + "\xd1\x81\xd0\xb5\xd0\xb9\xd1\x81\xd0\xb5\xd0\xbd\xd0\xb1\xd1\x96\0" + "\xd1\x81\xd3\x99\xd1\x80\xd1\x81\xd0\xb5\xd0\xbd\xd0\xb1\xd1\x96\0" + "\xd0\xb1\xd0\xb5\xd0\xb9\xd1\x81\xd0\xb5\xd0\xbd\xd0\xb1\xd1\x96\0" + "\xd0\xb6\xd2\xb1\xd0\xbc\xd0\xb0\0" + "\xd1\x81\xd0\xb5\xd0\xbd\xd0\xb1\xd1\x96\0" + "\xd0\x96\xd1\x81\0" + "\xd0\x94\xd1\x81\0" + "\xd0\xa1\xd1\x81\0" + "\xd0\xa1\xd1\x80\0" + "\xd0\x91\xd1\x81\0" + "\xd0\x96\xd0\xbc\0" + "\xd0\xa1\xd0\xb1\0" + "\xd0\x96\0" + "\xd0\x94\0" + "\xd0\x91\0" + "\xd2\x9a\xd0\xb0\xd2\xa3\xd1\x82\xd0\xb0\xd1\x80\0" + "\xd0\x90\xd2\x9b\xd0\xbf\xd0\xb0\xd0\xbd\0" + "\xd0\x9d\xd0\xb0\xd1\x83\xd1\x80\xd1\x8b\xd0\xb7\0" + "\xd0\xa1\xd3\x99\xd1\x83\xd1\x96\xd1\x80\0" + "\xd0\x9c\xd0\xb0\xd0\xbc\xd1\x8b\xd1\x80\0" + "\xd0\x9c\xd0\xb0\xd1\x83\xd1\x81\xd1\x8b\xd0\xbc\0" + "\xd0\xa8\xd1\x96\xd0\xbb\xd0\xb4\xd0\xb5\0" + "\xd0\xa2\xd0\xb0\xd0\xbc\xd1\x8b\xd0\xb7\0" + "\xd2\x9a\xd1\x8b\xd1\x80\xd0\xba\xd2\xaf\xd0\xb9\xd0\xb5\xd0\xba\0" + "\xd2\x9a\xd0\xb0\xd0\xb7\xd0\xb0\xd0\xbd\0" + "\xd2\x9a\xd0\xb0\xd1\x80\xd0\xb0\xd1\x88\xd0\xb0\0" + "\xd0\x96\xd0\xb5\xd0\xbb\xd1\x82\xd0\xbe\xd2\x9b\xd1\x81\xd0\xb0\xd0\xbd\0" + "\xd2\x9b\xd0\xb0\xd2\xa3\xd1\x82\xd0\xb0\xd1\x80\0" + "\xd0\xb0\xd2\x9b\xd0\xbf\xd0\xb0\xd0\xbd\0" + "\xd0\xbd\xd0\xb0\xd1\x83\xd1\x80\xd1\x8b\xd0\xb7\0" + "\xd1\x81\xd3\x99\xd1\x83\xd1\x96\xd1\x80\0" + "\xd0\xbc\xd0\xb0\xd0\xbc\xd1\x8b\xd1\x80\0" + "\xd0\xbc\xd0\xb0\xd1\x83\xd1\x81\xd1\x8b\xd0\xbc\0" + "\xd1\x88\xd1\x96\xd0\xbb\xd0\xb4\xd0\xb5\0" + "\xd1\x82\xd0\xb0\xd0\xbc\xd1\x8b\xd0\xb7\0" + "\xd2\x9b\xd1\x8b\xd1\x80\xd0\xba\xd2\xaf\xd0\xb9\xd0\xb5\xd0\xba\0" + "\xd2\x9b\xd0\xb0\xd0\xb7\xd0\xb0\xd0\xbd\0" + "\xd2\x9b\xd0\xb0\xd1\x80\xd0\xb0\xd1\x88\xd0\xb0\0" + "\xd0\xb6\xd0\xb5\xd0\xbb\xd1\x82\xd0\xbe\xd2\x9b\xd1\x81\xd0\xb0\xd0\xbd\0" + "\xd2\x9a\xd0\xb0\xd2\xa3.\0" + "\xd0\x90\xd2\x9b\xd0\xbf.\0" + "\xd0\x9d\xd0\xb0\xd1\x83.\0" + "\xd0\xa1\xd3\x99\xd1\x83.\0" + "\xd0\x9c\xd0\xb0\xd0\xbc.\0" + "\xd0\x9c\xd0\xb0\xd1\x83.\0" + "\xd0\xa8\xd1\x96\xd0\xbb.\0" + "\xd0\xa2\xd0\xb0\xd0\xbc.\0" + "\xd2\x9a\xd1\x8b\xd1\x80.\0" + "\xd2\x9a\xd0\xb0\xd0\xb7.\0" + "\xd2\x9a\xd0\xb0\xd1\x80.\0" + "\xd0\x96\xd0\xb5\xd0\xbb.\0" + "\xd0\xb6\xd0\xb5\xd0\xba\xd1\x88\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb8\0" + "\xd0\xb4\xd2\xaf\xd0\xb9\xd1\x88\xd3\xa9\xd0\xbc\xd0\xb1\xd2\xaf\0" + "\xd1\x88\xd0\xb5\xd0\xb9\xd1\x88\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb8\0" + "\xd1\x88\xd0\xb0\xd1\x80\xd1\x88\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb8\0" + "\xd0\xb1\xd0\xb5\xd0\xb9\xd1\x88\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb8\0" + "\xd0\xb6\xd1\x83\xd0\xbc\xd0\xb0\0" + "\xd0\xb8\xd1\x88\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb8\0" + "\xd0\xb6\xd0\xb5\xd0\xba.\0" + "\xd0\xb4\xd2\xaf\xd0\xb9.\0" + "\xd1\x88\xd0\xb5\xd0\xb9\xd1\x88.\0" + "\xd1\x88\xd0\xb0\xd1\x80\xd1\x88.\0" + "\xd0\xb1\xd0\xb5\xd0\xb9\xd1\x88.\0" + "\xd0\xb8\xd1\x88\xd0\xbc.\0" + "\xd0\xa8\0" + "\xd0\x98\0" + "\xd0\xaf\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8c\0" + "\xd0\xa4\xd0\xb5\xd0\xb2\xd1\x80\xd0\xb0\xd0\xbb\xd1\x8c\0" + "\xd0\x90\xd0\xbf\xd1\x80\xd0\xb5\xd0\xbb\xd1\x8c\0" + "\xd0\x98\xd1\x8e\xd0\xbd\xd1\x8c\0" + "\xd0\x98\xd1\x8e\xd0\xbb\xd1\x8c\0" + "\xd0\xa1\xd0\xb5\xd0\xbd\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8c\0" + "\xd0\x9e\xd0\xba\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8c\0" + "\xd0\x9d\xd0\xbe\xd1\x8f\xd0\xb1\xd1\x80\xd1\x8c\0" + "\xd0\x94\xd0\xb5\xd0\xba\xd0\xb0\xd0\xb1\xd1\x80\xd1\x8c\0" + "Jumapili\0" + "Jumatatu\0" + "Jumanne\0" + "Jumatano\0" + "Alhamisi\0" + "Ijumaa\0" + "Jumamosi\0" + "Machi\0" + "Aprili\0" + "Agosti\0" + "Oktoba\0" + "Desemba\0" + "Ago\0" + "\xc3\xbd\x65k\xc5\x9f\x65nbe\0" + "du\xc5\x9f\x65nbe\0" + "si\xc5\x9f\x65nbe\0" + "\xc3\xa7\x61r\xc5\x9f\x65nbe\0" + "pen\xc5\x9f\x65nbe\0" + "anna\0" + "\xc5\x9f\x65nbe\0" + "\xc3\xbd\x62\0" + "db\0" + "sb\0" + "\xc3\xa7\x62\0" + "pb\0" + "\xc5\x9f\x62\0" + "\xc3\x9d\0" + "\xc5\x9e\0" + "\xc3\xbd\x61nwar\0" + "fewral\0" + "ma\xc3\xbd\0" + "i\xc3\xbdun\0" + "i\xc3\xbdul\0" + "sent\xc3\xbd\x61\x62r\0" + "okt\xc3\xbd\x61\x62r\0" + "no\xc3\xbd\x61\x62r\0" + "\xc3\xbd\x61n\0" + "few\0" + "no\xc3\xbd\0" + "yakshanba\0" + "dushanba\0" + "seshanba\0" + "chorshanba\0" + "payshanba\0" + "juma\0" + "shanba\0" + "Yak\0" + "Dush\0" + "Sesh\0" + "Chor\0" + "Pay\0" + "Shan\0" + "Y\0" + "Iyun\0" + "Iyul\0" + "Avgust\0" + "Sentabr\0" + "Oktabr\0" + "sentabr\0" + "oktabr\0" + "Fev\0" + "Iyn\0" + "Iyl\0" + "Avg\0" + "Noy\0" + "Dek\0" + "\xe0\xa6\xb0\xe0\xa6\xac\xe0\xa6\xbf\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa6\xb8\xe0\xa7\x8b\xe0\xa6\xae\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa6\xae\xe0\xa6\x99\xe0\xa7\x8d\xe0\xa6\x97\xe0\xa6\xb2\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa6\xac\xe0\xa7\x81\xe0\xa6\xa7\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa6\xac\xe0\xa7\x83\xe0\xa6\xb9\xe0\xa6\xb8\xe0\xa7\x8d\xe0\xa6\xaa\xe0\xa6\xa4\xe0\xa6\xbf\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa6\xb6\xe0\xa7\x81\xe0\xa6\x95\xe0\xa7\x8d\xe0\xa6\xb0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa6\xb6\xe0\xa6\xa8\xe0\xa6\xbf\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa6\xb0\xe0\xa6\xac\xe0\xa6\xbf\0" + "\xe0\xa6\xb8\xe0\xa7\x8b\xe0\xa6\xae\0" + "\xe0\xa6\xae\xe0\xa6\x99\xe0\xa7\x8d\xe0\xa6\x97\xe0\xa6\xb2\0" + "\xe0\xa6\xac\xe0\xa7\x81\xe0\xa6\xa7\0" + "\xe0\xa6\xac\xe0\xa7\x83\xe0\xa6\xb9\xe0\xa6\xb8\xe0\xa7\x8d\xe0\xa6\xaa\xe0\xa6\xa4\xe0\xa6\xbf\0" + "\xe0\xa6\xb6\xe0\xa7\x81\xe0\xa6\x95\xe0\xa7\x8d\xe0\xa6\xb0\0" + "\xe0\xa6\xb6\xe0\xa6\xa8\xe0\xa6\xbf\0" + "\xe0\xa6\xb0\0" + "\xe0\xa6\xb8\xe0\xa7\x8b\0" + "\xe0\xa6\xae\0" + "\xe0\xa6\xac\xe0\xa7\x81\0" + "\xe0\xa6\xac\xe0\xa7\x83\0" + "\xe0\xa6\xb6\xe0\xa7\x81\0" + "\xe0\xa6\xb6\0" + "\xe0\xa6\x9c\xe0\xa6\xbe\xe0\xa6\xa8\xe0\xa7\x81\xe0\xa6\xaf\xe0\xa6\xbc\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa7\x80\0" + "\xe0\xa6\xab\xe0\xa7\x87\xe0\xa6\xac\xe0\xa7\x8d\xe0\xa6\xb0\xe0\xa7\x81\xe0\xa6\xaf\xe0\xa6\xbc\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa7\x80\0" + "\xe0\xa6\xae\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa7\x8d\xe0\xa6\x9a\0" + "\xe0\xa6\x8f\xe0\xa6\xaa\xe0\xa7\x8d\xe0\xa6\xb0\xe0\xa6\xbf\xe0\xa6\xb2\0" + "\xe0\xa6\xae\xe0\xa7\x87\0" + "\xe0\xa6\x9c\xe0\xa7\x81\xe0\xa6\xa8\0" + "\xe0\xa6\x9c\xe0\xa7\x81\xe0\xa6\xb2\xe0\xa6\xbe\xe0\xa6\x87\0" + "\xe0\xa6\x86\xe0\xa6\x97\xe0\xa6\xb8\xe0\xa7\x8d\xe0\xa6\x9f\0" + "\xe0\xa6\xb8\xe0\xa7\x87\xe0\xa6\xaa\xe0\xa7\x8d\xe0\xa6\x9f\xe0\xa7\x87\xe0\xa6\xae\xe0\xa7\x8d\xe0\xa6\xac\xe0\xa6\xb0\0" + "\xe0\xa6\x85\xe0\xa6\x95\xe0\xa7\x8d\xe0\xa6\x9f\xe0\xa7\x8b\xe0\xa6\xac\xe0\xa6\xb0\0" + "\xe0\xa6\xa8\xe0\xa6\xad\xe0\xa7\x87\xe0\xa6\xae\xe0\xa7\x8d\xe0\xa6\xac\xe0\xa6\xb0\0" + "\xe0\xa6\xa1\xe0\xa6\xbf\xe0\xa6\xb8\xe0\xa7\x87\xe0\xa6\xae\xe0\xa7\x8d\xe0\xa6\xac\xe0\xa6\xb0\0" + "\xe0\xa8\x90\xe0\xa8\xa4\xe0\xa8\xb5\xe0\xa8\xbe\xe0\xa8\xb0\0" + "\xe0\xa8\xb8\xe0\xa9\x8b\xe0\xa8\xae\xe0\xa8\xb5\xe0\xa8\xbe\xe0\xa8\xb0\0" + "\xe0\xa8\xae\xe0\xa9\xb0\xe0\xa8\x97\xe0\xa8\xb2\xe0\xa8\xb5\xe0\xa8\xbe\xe0\xa8\xb0\0" + "\xe0\xa8\xac\xe0\xa9\x81\xe0\xa9\xb1\xe0\xa8\xa7\xe0\xa8\xb5\xe0\xa8\xbe\xe0\xa8\xb0\0" + "\xe0\xa8\xb5\xe0\xa9\x80\xe0\xa8\xb0\xe0\xa8\xb5\xe0\xa8\xbe\xe0\xa8\xb0\0" + "\xe0\xa8\xb8\xe0\xa8\xbc\xe0\xa9\x81\xe0\xa9\xb1\xe0\xa8\x95\xe0\xa8\xb0\xe0\xa8\xb5\xe0\xa8\xbe\xe0\xa8\xb0\0" + "\xe0\xa8\xb8\xe0\xa8\xbc\xe0\xa8\xa8\xe0\xa8\xbf\xe0\xa9\xb1\xe0\xa8\x9a\xe0\xa8\xb0\xe0\xa8\xb5\xe0\xa8\xbe\xe0\xa8\xb0\0" + "\xe0\xa8\x90\xe0\xa8\xa4\0" + "\xe0\xa8\xb8\xe0\xa9\x8b\xe0\xa8\xae\0" + "\xe0\xa8\xae\xe0\xa9\xb0\xe0\xa8\x97\xe0\xa8\xb2\0" + "\xe0\xa8\xac\xe0\xa9\x81\xe0\xa9\xb1\xe0\xa8\xa7\0" + "\xe0\xa8\xb5\xe0\xa9\x80\xe0\xa8\xb0\0" + "\xe0\xa8\xb8\xe0\xa8\xbc\xe0\xa9\x81\xe0\xa9\xb1\xe0\xa8\x95\xe0\xa8\xb0\0" + "\xe0\xa8\xb8\xe0\xa8\xbc\xe0\xa8\xa8\xe0\xa8\xbf\xe0\xa9\xb1\xe0\xa8\x9a\xe0\xa8\xb0\0" + "\xe0\xa8\x90\0" + "\xe0\xa8\xb8\xe0\xa9\x8b\0" + "\xe0\xa8\xae\xe0\xa9\xb0\0" + "\xe0\xa8\xac\xe0\xa9\x81\xe0\xa9\xb1\0" + "\xe0\xa8\xb5\xe0\xa9\x80\0" + "\xe0\xa8\xb8\xe0\xa8\xbc\xe0\xa9\x81\xe0\xa9\xb1\0" + "\xe0\xa8\xb8\xe0\xa8\xbc\0" + "\xe0\xa8\x9c\xe0\xa8\xa8\xe0\xa8\xb5\xe0\xa8\xb0\xe0\xa9\x80\0" + "\xe0\xa8\xab\xe0\xa8\xbc\xe0\xa8\xb0\xe0\xa8\xb5\xe0\xa8\xb0\xe0\xa9\x80\0" + "\xe0\xa8\xae\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\x9a\0" + "\xe0\xa8\x85\xe0\xa8\xaa\xe0\xa9\x8d\xe0\xa8\xb0\xe0\xa9\x88\xe0\xa8\xb2\0" + "\xe0\xa8\xae\xe0\xa8\x88\0" + "\xe0\xa8\x9c\xe0\xa9\x82\xe0\xa8\xa8\0" + "\xe0\xa8\x9c\xe0\xa9\x81\xe0\xa8\xb2\xe0\xa8\xbe\xe0\xa8\x88\0" + "\xe0\xa8\x85\xe0\xa8\x97\xe0\xa8\xb8\xe0\xa8\xa4\0" + "\xe0\xa8\xb8\xe0\xa8\xa4\xe0\xa9\xb0\xe0\xa8\xac\xe0\xa8\xb0\0" + "\xe0\xa8\x85\xe0\xa8\x95\xe0\xa8\xa4\xe0\xa9\x82\xe0\xa8\xac\xe0\xa8\xb0\0" + "\xe0\xa8\xa8\xe0\xa8\xb5\xe0\xa9\xb0\xe0\xa8\xac\xe0\xa8\xb0\0" + "\xe0\xa8\xa6\xe0\xa8\xb8\xe0\xa9\xb0\xe0\xa8\xac\xe0\xa8\xb0\0" + "\xe0\xa8\x9c\xe0\xa8\xa8\0" + "\xe0\xa8\xab\xe0\xa8\xbc\xe0\xa8\xb0\0" + "\xe0\xa8\x85\xe0\xa8\xaa\xe0\xa9\x8d\xe0\xa8\xb0\xe0\xa9\x88\0" + "\xe0\xa8\x9c\xe0\xa9\x81\xe0\xa8\xb2\xe0\xa8\xbe\0" + "\xe0\xa8\x85\xe0\xa8\x97\0" + "\xe0\xa8\xb8\xe0\xa8\xa4\xe0\xa9\xb0\0" + "\xe0\xa8\x85\xe0\xa8\x95\xe0\xa8\xa4\xe0\xa9\x82\0" + "\xe0\xa8\xa8\xe0\xa8\xb5\xe0\xa9\xb0\0" + "\xe0\xa8\xa6\xe0\xa8\xb8\xe0\xa9\xb0\0" + "\xe0\xaa\xb0\xe0\xaa\xb5\xe0\xaa\xbf\xe0\xaa\xb5\xe0\xaa\xbe\xe0\xaa\xb0\0" + "\xe0\xaa\xb8\xe0\xab\x8b\xe0\xaa\xae\xe0\xaa\xb5\xe0\xaa\xbe\xe0\xaa\xb0\0" + "\xe0\xaa\xae\xe0\xaa\x82\xe0\xaa\x97\xe0\xaa\xb3\xe0\xaa\xb5\xe0\xaa\xbe\xe0\xaa\xb0\0" + "\xe0\xaa\xac\xe0\xab\x81\xe0\xaa\xa7\xe0\xaa\xb5\xe0\xaa\xbe\xe0\xaa\xb0\0" + "\xe0\xaa\x97\xe0\xab\x81\xe0\xaa\xb0\xe0\xab\x81\xe0\xaa\xb5\xe0\xaa\xbe\xe0\xaa\xb0\0" + "\xe0\xaa\xb6\xe0\xab\x81\xe0\xaa\x95\xe0\xab\x8d\xe0\xaa\xb0\xe0\xaa\xb5\xe0\xaa\xbe\xe0\xaa\xb0\0" + "\xe0\xaa\xb6\xe0\xaa\xa8\xe0\xaa\xbf\xe0\xaa\xb5\xe0\xaa\xbe\xe0\xaa\xb0\0" + "\xe0\xaa\xb0\xe0\xaa\xb5\xe0\xaa\xbf\0" + "\xe0\xaa\xb8\xe0\xab\x8b\xe0\xaa\xae\0" + "\xe0\xaa\xae\xe0\xaa\x82\xe0\xaa\x97\xe0\xaa\xb3\0" + "\xe0\xaa\xac\xe0\xab\x81\xe0\xaa\xa7\0" + "\xe0\xaa\x97\xe0\xab\x81\xe0\xaa\xb0\xe0\xab\x81\0" + "\xe0\xaa\xb6\xe0\xab\x81\xe0\xaa\x95\xe0\xab\x8d\xe0\xaa\xb0\0" + "\xe0\xaa\xb6\xe0\xaa\xa8\xe0\xaa\xbf\0" + "\xe0\xaa\xb0\0" + "\xe0\xaa\xb8\xe0\xab\x8b\0" + "\xe0\xaa\xae\xe0\xaa\x82\0" + "\xe0\xaa\xac\xe0\xab\x81\0" + "\xe0\xaa\x97\xe0\xab\x81\0" + "\xe0\xaa\xb6\xe0\xab\x81\0" + "\xe0\xaa\xb6\0" + "\xe0\xaa\x9c\xe0\xaa\xbe\xe0\xaa\xa8\xe0\xab\x8d\xe0\xaa\xaf\xe0\xab\x81\xe0\xaa\x86\xe0\xaa\xb0\xe0\xab\x80\0" + "\xe0\xaa\xab\xe0\xab\x87\xe0\xaa\xac\xe0\xab\x8d\xe0\xaa\xb0\xe0\xab\x81\xe0\xaa\x86\xe0\xaa\xb0\xe0\xab\x80\0" + "\xe0\xaa\xae\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xab\x8d\xe0\xaa\x9a\0" + "\xe0\xaa\x8f\xe0\xaa\xaa\xe0\xab\x8d\xe0\xaa\xb0\xe0\xaa\xbf\xe0\xaa\xb2\0" + "\xe0\xaa\xae\xe0\xab\x87\0" + "\xe0\xaa\x9c\xe0\xab\x82\xe0\xaa\xa8\0" + "\xe0\xaa\x9c\xe0\xab\x81\xe0\xaa\xb2\xe0\xaa\xbe\xe0\xaa\x88\0" + "\xe0\xaa\x91\xe0\xaa\x97\xe0\xaa\xb8\xe0\xab\x8d\xe0\xaa\x9f\0" + "\xe0\xaa\xb8\xe0\xaa\xaa\xe0\xab\x8d\xe0\xaa\x9f\xe0\xab\x87\xe0\xaa\xae\xe0\xab\x8d\xe0\xaa\xac\xe0\xaa\xb0\0" + "\xe0\xaa\x91\xe0\xaa\x95\xe0\xab\x8d\xe0\xaa\x9f\xe0\xab\x8b\xe0\xaa\xac\xe0\xaa\xb0\0" + "\xe0\xaa\xa8\xe0\xaa\xb5\xe0\xab\x87\xe0\xaa\xae\xe0\xab\x8d\xe0\xaa\xac\xe0\xaa\xb0\0" + "\xe0\xaa\xa1\xe0\xaa\xbf\xe0\xaa\xb8\xe0\xab\x87\xe0\xaa\xae\xe0\xab\x8d\xe0\xaa\xac\xe0\xaa\xb0\0" + "\xe0\xaa\x9c\xe0\xaa\xbe\xe0\xaa\xa8\xe0\xab\x8d\xe0\xaa\xaf\xe0\xab\x81\0" + "\xe0\xaa\xab\xe0\xab\x87\xe0\xaa\xac\xe0\xab\x8d\xe0\xaa\xb0\xe0\xab\x81\0" + "\xe0\xaa\xb8\xe0\xaa\xaa\xe0\xab\x8d\xe0\xaa\x9f\xe0\xab\x87\0" + "\xe0\xaa\x91\xe0\xaa\x95\xe0\xab\x8d\xe0\xaa\x9f\xe0\xab\x8b\0" + "\xe0\xaa\xa8\xe0\xaa\xb5\xe0\xab\x87\0" + "\xe0\xaa\xa1\xe0\xaa\xbf\xe0\xaa\xb8\xe0\xab\x87\0" + "\xe0\xac\xb0\xe0\xac\xac\xe0\xac\xbf\xe0\xac\xac\xe0\xac\xbe\xe0\xac\xb0\0" + "\xe0\xac\xb8\xe0\xad\x8b\xe0\xac\xae\xe0\xac\xac\xe0\xac\xbe\xe0\xac\xb0\0" + "\xe0\xac\xae\xe0\xac\x99\xe0\xad\x8d\xe0\xac\x97\xe0\xac\xb3\xe0\xac\xac\xe0\xac\xbe\xe0\xac\xb0\0" + "\xe0\xac\xac\xe0\xad\x81\xe0\xac\xa7\xe0\xac\xac\xe0\xac\xbe\xe0\xac\xb0\0" + "\xe0\xac\x97\xe0\xad\x81\xe0\xac\xb0\xe0\xad\x81\xe0\xac\xac\xe0\xac\xbe\xe0\xac\xb0\0" + "\xe0\xac\xb6\xe0\xad\x81\xe0\xac\x95\xe0\xad\x8d\xe0\xac\xb0\xe0\xac\xac\xe0\xac\xbe\xe0\xac\xb0\0" + "\xe0\xac\xb6\xe0\xac\xa8\xe0\xac\xbf\xe0\xac\xac\xe0\xac\xbe\xe0\xac\xb0\0" + "\xe0\xac\xb0\xe0\xac\xac\xe0\xac\xbf\0" + "\xe0\xac\xb8\xe0\xad\x8b\xe0\xac\xae\0" + "\xe0\xac\xae\xe0\xac\x99\xe0\xad\x8d\xe0\xac\x97\xe0\xac\xb3\0" + "\xe0\xac\xac\xe0\xad\x81\xe0\xac\xa7\0" + "\xe0\xac\x97\xe0\xad\x81\xe0\xac\xb0\xe0\xad\x81\0" + "\xe0\xac\xb6\xe0\xad\x81\xe0\xac\x95\xe0\xad\x8d\xe0\xac\xb0\0" + "\xe0\xac\xb6\xe0\xac\xa8\xe0\xac\xbf\0" + "\xe0\xac\xb0\0" + "\xe0\xac\xb8\xe0\xad\x8b\0" + "\xe0\xac\xae\0" + "\xe0\xac\xac\xe0\xad\x81\0" + "\xe0\xac\x97\xe0\xad\x81\0" + "\xe0\xac\xb6\xe0\xad\x81\0" + "\xe0\xac\xb6\0" + "\xe0\xac\x9c\xe0\xac\xbe\xe0\xac\xa8\xe0\xad\x81\xe0\xac\x86\xe0\xac\xb0\xe0\xad\x80\0" + "\xe0\xac\xab\xe0\xad\x87\xe0\xac\xac\xe0\xad\x83\xe0\xac\x86\xe0\xac\xb0\xe0\xad\x80\0" + "\xe0\xac\xae\xe0\xac\xbe\xe0\xac\xb0\xe0\xad\x8d\xe0\xac\x9a\xe0\xad\x8d\xe0\xac\x9a\0" + "\xe0\xac\x85\xe0\xac\xaa\xe0\xad\x8d\xe0\xac\xb0\xe0\xad\x87\xe0\xac\xb2\0" + "\xe0\xac\xae\xe0\xac\x87\0" + "\xe0\xac\x9c\xe0\xad\x81\xe0\xac\xa8\0" + "\xe0\xac\x9c\xe0\xad\x81\xe0\xac\xb2\xe0\xac\xbe\xe0\xac\x87\0" + "\xe0\xac\x85\xe0\xac\x97\xe0\xac\xb7\xe0\xad\x8d\xe0\xac\x9f\0" + "\xe0\xac\xb8\xe0\xad\x87\xe0\xac\xaa\xe0\xad\x8d\xe0\xac\x9f\xe0\xad\x87\xe0\xac\xae\xe0\xad\x8d\xe0\xac\xac\xe0\xac\xb0\0" + "\xe0\xac\x85\xe0\xac\x95\xe0\xad\x8d\xe0\xac\x9f\xe0\xad\x8b\xe0\xac\xac\xe0\xac\xb0\0" + "\xe0\xac\xa8\xe0\xac\xad\xe0\xad\x87\xe0\xac\xae\xe0\xad\x8d\xe0\xac\xac\xe0\xac\xb0\0" + "\xe0\xac\xa1\xe0\xac\xbf\xe0\xac\xb8\xe0\xad\x87\xe0\xac\xae\xe0\xad\x8d\xe0\xac\xac\xe0\xac\xb0\0" + "\xe0\xae\x9e\xe0\xae\xbe\xe0\xae\xaf\xe0\xae\xbf\xe0\xae\xb1\xe0\xaf\x81\0" + "\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xb3\xe0\xaf\x8d\0" + "\xe0\xae\x9a\xe0\xaf\x86\xe0\xae\xb5\xe0\xaf\x8d\xe0\xae\xb5\xe0\xae\xbe\xe0\xae\xaf\xe0\xaf\x8d\0" + "\xe0\xae\xaa\xe0\xaf\x81\xe0\xae\xa4\xe0\xae\xa9\xe0\xaf\x8d\0" + "\xe0\xae\xb5\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\xe0\xae\xb4\xe0\xae\xa9\xe0\xaf\x8d\0" + "\xe0\xae\xb5\xe0\xaf\x86\xe0\xae\xb3\xe0\xaf\x8d\xe0\xae\xb3\xe0\xae\xbf\0" + "\xe0\xae\x9a\xe0\xae\xa9\xe0\xae\xbf\0" + "\xe0\xae\x9e\xe0\xae\xbe\xe0\xae\xaf\xe0\xae\xbf.\0" + "\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d.\0" + "\xe0\xae\x9a\xe0\xaf\x86\xe0\xae\xb5\xe0\xaf\x8d.\0" + "\xe0\xae\xaa\xe0\xaf\x81\xe0\xae\xa4.\0" + "\xe0\xae\xb5\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe.\0" + "\xe0\xae\xb5\xe0\xaf\x86\xe0\xae\xb3\xe0\xaf\x8d.\0" + "\xe0\xae\x9e\xe0\xae\xbe\0" + "\xe0\xae\xa4\xe0\xae\xbf\0" + "\xe0\xae\x9a\xe0\xaf\x86\0" + "\xe0\xae\xaa\xe0\xaf\x81\0" + "\xe0\xae\xb5\xe0\xae\xbf\0" + "\xe0\xae\xb5\xe0\xaf\x86\0" + "\xe0\xae\x9a\0" + "\xe0\xae\x9c\xe0\xae\xa9\xe0\xae\xb5\xe0\xae\xb0\xe0\xae\xbf\0" + "\xe0\xae\xaa\xe0\xae\xbf\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xb0\xe0\xae\xb5\xe0\xae\xb0\xe0\xae\xbf\0" + "\xe0\xae\xae\xe0\xae\xbe\xe0\xae\xb0\xe0\xaf\x8d\xe0\xae\x9a\xe0\xaf\x8d\0" + "\xe0\xae\x8f\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xb0\xe0\xae\xb2\xe0\xaf\x8d\0" + "\xe0\xae\xae\xe0\xaf\x87\0" + "\xe0\xae\x9c\xe0\xaf\x82\xe0\xae\xa9\xe0\xaf\x8d\0" + "\xe0\xae\x9c\xe0\xaf\x82\xe0\xae\xb2\xe0\xaf\x88\0" + "\xe0\xae\x86\xe0\xae\x95\xe0\xae\xb8\xe0\xaf\x8d\xe0\xae\x9f\xe0\xaf\x8d\0" + "\xe0\xae\x9a\xe0\xaf\x86\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\x9f\xe0\xae\xae\xe0\xaf\x8d\xe0\xae\xaa\xe0\xae\xb0\xe0\xaf\x8d\0" + "\xe0\xae\x85\xe0\xae\x95\xe0\xaf\x8d\xe0\xae\x9f\xe0\xaf\x8b\xe0\xae\xaa\xe0\xae\xb0\xe0\xaf\x8d\0" + "\xe0\xae\xa8\xe0\xae\xb5\xe0\xae\xae\xe0\xaf\x8d\xe0\xae\xaa\xe0\xae\xb0\xe0\xaf\x8d\0" + "\xe0\xae\x9f\xe0\xae\xbf\xe0\xae\x9a\xe0\xae\xae\xe0\xaf\x8d\xe0\xae\xaa\xe0\xae\xb0\xe0\xaf\x8d\0" + "\xe0\xae\x9c\xe0\xae\xa9.\0" + "\xe0\xae\xaa\xe0\xae\xbf\xe0\xae\xaa\xe0\xaf\x8d.\0" + "\xe0\xae\xae\xe0\xae\xbe\xe0\xae\xb0\xe0\xaf\x8d.\0" + "\xe0\xae\x8f\xe0\xae\xaa\xe0\xaf\x8d.\0" + "\xe0\xae\x86\xe0\xae\x95.\0" + "\xe0\xae\x9a\xe0\xaf\x86\xe0\xae\xaa\xe0\xaf\x8d.\0" + "\xe0\xae\x85\xe0\xae\x95\xe0\xaf\x8d.\0" + "\xe0\xae\xa8\xe0\xae\xb5.\0" + "\xe0\xae\x9f\xe0\xae\xbf\xe0\xae\x9a.\0" + "\xe0\xb0\x86\xe0\xb0\xa6\xe0\xb0\xbf\xe0\xb0\xb5\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\x82\0" + "\xe0\xb0\xb8\xe0\xb1\x8b\xe0\xb0\xae\xe0\xb0\xb5\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\x82\0" + "\xe0\xb0\xae\xe0\xb0\x82\xe0\xb0\x97\xe0\xb0\xb3\xe0\xb0\xb5\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\x82\0" + "\xe0\xb0\xac\xe0\xb1\x81\xe0\xb0\xa7\xe0\xb0\xb5\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\x82\0" + "\xe0\xb0\x97\xe0\xb1\x81\xe0\xb0\xb0\xe0\xb1\x81\xe0\xb0\xb5\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\x82\0" + "\xe0\xb0\xb6\xe0\xb1\x81\xe0\xb0\x95\xe0\xb1\x8d\xe0\xb0\xb0\xe0\xb0\xb5\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\x82\0" + "\xe0\xb0\xb6\xe0\xb0\xa8\xe0\xb0\xbf\xe0\xb0\xb5\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\x82\0" + "\xe0\xb0\x86\xe0\xb0\xa6\xe0\xb0\xbf\0" + "\xe0\xb0\xb8\xe0\xb1\x8b\xe0\xb0\xae\0" + "\xe0\xb0\xae\xe0\xb0\x82\xe0\xb0\x97\xe0\xb0\xb3\0" + "\xe0\xb0\xac\xe0\xb1\x81\xe0\xb0\xa7\0" + "\xe0\xb0\x97\xe0\xb1\x81\xe0\xb0\xb0\xe0\xb1\x81\0" + "\xe0\xb0\xb6\xe0\xb1\x81\xe0\xb0\x95\xe0\xb1\x8d\xe0\xb0\xb0\0" + "\xe0\xb0\xb6\xe0\xb0\xa8\xe0\xb0\xbf\0" + "\xe0\xb0\x86\0" + "\xe0\xb0\xb8\xe0\xb1\x8b\0" + "\xe0\xb0\xae\0" + "\xe0\xb0\xac\xe0\xb1\x81\0" + "\xe0\xb0\x97\xe0\xb1\x81\0" + "\xe0\xb0\xb6\xe0\xb1\x81\0" + "\xe0\xb0\xb6\0" + "\xe0\xb0\x9c\xe0\xb0\xa8\xe0\xb0\xb5\xe0\xb0\xb0\xe0\xb0\xbf\0" + "\xe0\xb0\xab\xe0\xb0\xbf\xe0\xb0\xac\xe0\xb1\x8d\xe0\xb0\xb0\xe0\xb0\xb5\xe0\xb0\xb0\xe0\xb0\xbf\0" + "\xe0\xb0\xae\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb1\x8d\xe0\xb0\x9a\xe0\xb0\xbf\0" + "\xe0\xb0\x8f\xe0\xb0\xaa\xe0\xb1\x8d\xe0\xb0\xb0\xe0\xb0\xbf\xe0\xb0\xb2\xe0\xb1\x8d\0" + "\xe0\xb0\xae\xe0\xb1\x87\0" + "\xe0\xb0\x9c\xe0\xb1\x82\xe0\xb0\xa8\xe0\xb1\x8d\0" + "\xe0\xb0\x9c\xe0\xb1\x81\xe0\xb0\xb2\xe0\xb1\x88\0" + "\xe0\xb0\x86\xe0\xb0\x97\xe0\xb0\xb8\xe0\xb1\x8d\xe0\xb0\x9f\xe0\xb1\x81\0" + "\xe0\xb0\xb8\xe0\xb1\x86\xe0\xb0\xaa\xe0\xb1\x8d\xe0\xb0\x9f\xe0\xb1\x86\xe0\xb0\x82\xe0\xb0\xac\xe0\xb0\xb0\xe0\xb1\x8d\0" + "\xe0\xb0\x85\xe0\xb0\x95\xe0\xb1\x8d\xe0\xb0\x9f\xe0\xb1\x8b\xe0\xb0\xac\xe0\xb0\xb0\xe0\xb1\x8d\0" + "\xe0\xb0\xa8\xe0\xb0\xb5\xe0\xb0\x82\xe0\xb0\xac\xe0\xb0\xb0\xe0\xb1\x8d\0" + "\xe0\xb0\xa1\xe0\xb0\xbf\xe0\xb0\xb8\xe0\xb1\x86\xe0\xb0\x82\xe0\xb0\xac\xe0\xb0\xb0\xe0\xb1\x8d\0" + "\xe0\xb0\x9c\xe0\xb0\xa8\0" + "\xe0\xb0\xab\xe0\xb0\xbf\xe0\xb0\xac\xe0\xb1\x8d\xe0\xb0\xb0\0" + "\xe0\xb0\x8f\xe0\xb0\xaa\xe0\xb1\x8d\xe0\xb0\xb0\xe0\xb0\xbf\0" + "\xe0\xb0\xb8\xe0\xb1\x86\xe0\xb0\xaa\xe0\xb1\x8d\xe0\xb0\x9f\xe0\xb1\x86\xe0\xb0\x82\0" + "\xe0\xb0\x85\xe0\xb0\x95\xe0\xb1\x8d\xe0\xb0\x9f\xe0\xb1\x8b\0" + "\xe0\xb0\xa8\xe0\xb0\xb5\xe0\xb0\x82\0" + "\xe0\xb0\xa1\xe0\xb0\xbf\xe0\xb0\xb8\xe0\xb1\x86\xe0\xb0\x82\0" + "\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xa8\xe0\xb3\x81\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb0\0" + "\xe0\xb2\xb8\xe0\xb3\x8b\xe0\xb2\xae\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb0\0" + "\xe0\xb2\xae\xe0\xb2\x82\xe0\xb2\x97\xe0\xb2\xb3\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb0\0" + "\xe0\xb2\xac\xe0\xb3\x81\xe0\xb2\xa7\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb0\0" + "\xe0\xb2\x97\xe0\xb3\x81\xe0\xb2\xb0\xe0\xb3\x81\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb0\0" + "\xe0\xb2\xb6\xe0\xb3\x81\xe0\xb2\x95\xe0\xb3\x8d\xe0\xb2\xb0\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb0\0" + "\xe0\xb2\xb6\xe0\xb2\xa8\xe0\xb2\xbf\xe0\xb2\xb5\xe0\xb2\xbe\xe0\xb2\xb0\0" + "\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xa8\xe0\xb3\x81\0" + "\xe0\xb2\xb8\xe0\xb3\x8b\xe0\xb2\xae\0" + "\xe0\xb2\xae\xe0\xb2\x82\xe0\xb2\x97\xe0\xb2\xb3\0" + "\xe0\xb2\xac\xe0\xb3\x81\xe0\xb2\xa7\0" + "\xe0\xb2\x97\xe0\xb3\x81\xe0\xb2\xb0\xe0\xb3\x81\0" + "\xe0\xb2\xb6\xe0\xb3\x81\xe0\xb2\x95\xe0\xb3\x8d\xe0\xb2\xb0\0" + "\xe0\xb2\xb6\xe0\xb2\xa8\xe0\xb2\xbf\0" + "\xe0\xb2\xad\xe0\xb2\xbe\0" + "\xe0\xb2\xb8\xe0\xb3\x8b\0" + "\xe0\xb2\xae\xe0\xb2\x82\0" + "\xe0\xb2\xac\xe0\xb3\x81\0" + "\xe0\xb2\x97\xe0\xb3\x81\0" + "\xe0\xb2\xb6\xe0\xb3\x81\0" + "\xe0\xb2\xb6\0" + "\xe0\xb2\x9c\xe0\xb2\xa8\xe0\xb2\xb5\xe0\xb2\xb0\xe0\xb2\xbf\0" + "\xe0\xb2\xab\xe0\xb3\x86\xe0\xb2\xac\xe0\xb3\x8d\xe0\xb2\xb0\xe0\xb2\xb5\xe0\xb2\xb0\xe0\xb2\xbf\0" + "\xe0\xb2\xae\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb3\x8d\xe0\xb2\x9a\xe0\xb3\x8d\0" + "\xe0\xb2\x8f\xe0\xb2\xaa\xe0\xb3\x8d\xe0\xb2\xb0\xe0\xb2\xbf\xe0\xb2\xb2\xe0\xb3\x8d\0" + "\xe0\xb2\xae\xe0\xb3\x87\0" + "\xe0\xb2\x9c\xe0\xb3\x82\xe0\xb2\xa8\xe0\xb3\x8d\0" + "\xe0\xb2\x9c\xe0\xb3\x81\xe0\xb2\xb2\xe0\xb3\x88\0" + "\xe0\xb2\x86\xe0\xb2\x97\xe0\xb2\xb8\xe0\xb3\x8d\xe0\xb2\x9f\xe0\xb3\x8d\0" + "\xe0\xb2\xb8\xe0\xb3\x86\xe0\xb2\xaa\xe0\xb3\x8d\xe0\xb2\x9f\xe0\xb3\x86\xe0\xb2\x82\xe0\xb2\xac\xe0\xb2\xb0\xe0\xb3\x8d\0" + "\xe0\xb2\x85\xe0\xb2\x95\xe0\xb3\x8d\xe0\xb2\x9f\xe0\xb3\x8b\xe0\xb2\xac\xe0\xb2\xb0\xe0\xb3\x8d\0" + "\xe0\xb2\xa8\xe0\xb2\xb5\xe0\xb3\x86\xe0\xb2\x82\xe0\xb2\xac\xe0\xb2\xb0\xe0\xb3\x8d\0" + "\xe0\xb2\xa1\xe0\xb2\xbf\xe0\xb2\xb8\xe0\xb3\x86\xe0\xb2\x82\xe0\xb2\xac\xe0\xb2\xb0\xe0\xb3\x8d\0" + "\xe0\xb2\x9c\xe0\xb2\xa8\0" + "\xe0\xb2\xab\xe0\xb3\x86\xe0\xb2\xac\xe0\xb3\x8d\xe0\xb2\xb0\0" + "\xe0\xb2\x8f\xe0\xb2\xaa\xe0\xb3\x8d\xe0\xb2\xb0\xe0\xb2\xbf\0" + "\xe0\xb2\x86\xe0\xb2\x97\0" + "\xe0\xb2\xb8\xe0\xb3\x86\xe0\xb2\xaa\xe0\xb3\x8d\xe0\xb2\x9f\xe0\xb3\x86\xe0\xb2\x82\0" + "\xe0\xb2\x85\xe0\xb2\x95\xe0\xb3\x8d\xe0\xb2\x9f\xe0\xb3\x8b\0" + "\xe0\xb2\xa8\xe0\xb2\xb5\xe0\xb3\x86\xe0\xb2\x82\0" + "\xe0\xb2\xa1\xe0\xb2\xbf\xe0\xb2\xb8\xe0\xb3\x86\xe0\xb2\x82\0" + "\xe0\xb4\x9e\xe0\xb4\xbe\xe0\xb4\xaf\xe0\xb4\xb1\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb5\x8d\xe2\x80\x8c\xe0\xb4\x9a\0" + "\xe0\xb4\xa4\xe0\xb4\xbf\xe0\xb4\x99\xe0\xb5\x8d\xe0\xb4\x95\xe0\xb4\xb3\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb5\x8d\xe2\x80\x8c\xe0\xb4\x9a\0" + "\xe0\xb4\x9a\xe0\xb5\x8a\xe0\xb4\xb5\xe0\xb5\x8d\xe0\xb4\xb5\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb5\x8d\xe0\xb4\x9a\0" + "\xe0\xb4\xac\xe0\xb5\x81\xe0\xb4\xa7\xe0\xb4\xa8\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb5\x8d\xe2\x80\x8c\xe0\xb4\x9a\0" + "\xe0\xb4\xb5\xe0\xb5\x8d\xe0\xb4\xaf\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb5\x8d\xe2\x80\x8c\xe0\xb4\x9a\0" + "\xe0\xb4\xb5\xe0\xb5\x86\xe0\xb4\xb3\xe0\xb5\x8d\xe0\xb4\xb3\xe0\xb4\xbf\xe0\xb4\xaf\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb5\x8d\xe2\x80\x8c\xe0\xb4\x9a\0" + "\xe0\xb4\xb6\xe0\xb4\xa8\xe0\xb4\xbf\xe0\xb4\xaf\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb5\x8d\xe2\x80\x8c\xe0\xb4\x9a\0" + "\xe0\xb4\x9e\xe0\xb4\xbe\xe0\xb4\xaf\xe0\xb5\xbc\0" + "\xe0\xb4\xa4\xe0\xb4\xbf\xe0\xb4\x99\xe0\xb5\x8d\xe0\xb4\x95\xe0\xb5\xbe\0" + "\xe0\xb4\x9a\xe0\xb5\x8a\xe0\xb4\xb5\xe0\xb5\x8d\xe0\xb4\xb5\0" + "\xe0\xb4\xac\xe0\xb5\x81\xe0\xb4\xa7\xe0\xb5\xbb\0" + "\xe0\xb4\xb5\xe0\xb5\x8d\xe0\xb4\xaf\xe0\xb4\xbe\xe0\xb4\xb4\xe0\xb4\x82\0" + "\xe0\xb4\xb5\xe0\xb5\x86\xe0\xb4\xb3\xe0\xb5\x8d\xe0\xb4\xb3\xe0\xb4\xbf\0" + "\xe0\xb4\xb6\xe0\xb4\xa8\xe0\xb4\xbf\0" + "\xe0\xb4\x9e\xe0\xb4\xbe\0" + "\xe0\xb4\xa4\xe0\xb4\xbf\0" + "\xe0\xb4\x9a\xe0\xb5\x8a\0" + "\xe0\xb4\xac\xe0\xb5\x81\0" + "\xe0\xb4\xb5\xe0\xb5\x8d\xe0\xb4\xaf\xe0\xb4\xbe\0" + "\xe0\xb4\xb5\xe0\xb5\x86\0" + "\xe0\xb4\xb6\0" + "\xe0\xb4\x9c\xe0\xb4\xa8\xe0\xb5\x81\xe0\xb4\xb5\xe0\xb4\xb0\xe0\xb4\xbf\0" + "\xe0\xb4\xab\xe0\xb5\x86\xe0\xb4\xac\xe0\xb5\x8d\xe0\xb4\xb0\xe0\xb5\x81\xe0\xb4\xb5\xe0\xb4\xb0\xe0\xb4\xbf\0" + "\xe0\xb4\xae\xe0\xb4\xbe\xe0\xb5\xbc\xe0\xb4\x9a\xe0\xb5\x8d\xe0\xb4\x9a\xe0\xb5\x8d\0" + "\xe0\xb4\x8f\xe0\xb4\xaa\xe0\xb5\x8d\xe0\xb4\xb0\xe0\xb4\xbf\xe0\xb5\xbd\0" + "\xe0\xb4\xae\xe0\xb5\x87\xe0\xb4\xaf\xe0\xb5\x8d\0" + "\xe0\xb4\x9c\xe0\xb5\x82\xe0\xb5\xba\0" + "\xe0\xb4\x9c\xe0\xb5\x82\xe0\xb4\xb2\xe0\xb5\x88\0" + "\xe0\xb4\x93\xe0\xb4\x97\xe0\xb4\xb8\xe0\xb5\x8d\xe0\xb4\xb1\xe0\xb5\x8d\xe0\xb4\xb1\xe0\xb5\x8d\0" + "\xe0\xb4\xb8\xe0\xb5\x86\xe0\xb4\xaa\xe0\xb5\x8d\xe0\xb4\xb1\xe0\xb5\x8d\xe0\xb4\xb1\xe0\xb4\x82\xe0\xb4\xac\xe0\xb5\xbc\0" + "\xe0\xb4\x92\xe0\xb4\x95\xe0\xb5\x8d\xe2\x80\x8c\xe0\xb4\x9f\xe0\xb5\x8b\xe0\xb4\xac\xe0\xb5\xbc\0" + "\xe0\xb4\xa8\xe0\xb4\xb5\xe0\xb4\x82\xe0\xb4\xac\xe0\xb5\xbc\0" + "\xe0\xb4\xa1\xe0\xb4\xbf\xe0\xb4\xb8\xe0\xb4\x82\xe0\xb4\xac\xe0\xb5\xbc\0" + "\xe0\xb4\x9c\xe0\xb4\xa8\xe0\xb5\x81\0" + "\xe0\xb4\xab\xe0\xb5\x86\xe0\xb4\xac\xe0\xb5\x8d\xe0\xb4\xb0\xe0\xb5\x81\0" + "\xe0\xb4\xae\xe0\xb4\xbe\xe0\xb5\xbc\0" + "\xe0\xb4\x8f\xe0\xb4\xaa\xe0\xb5\x8d\xe0\xb4\xb0\xe0\xb4\xbf\0" + "\xe0\xb4\x93\xe0\xb4\x97\0" + "\xe0\xb4\xb8\xe0\xb5\x86\xe0\xb4\xaa\xe0\xb5\x8d\xe0\xb4\xb1\xe0\xb5\x8d\xe0\xb4\xb1\xe0\xb4\x82\0" + "\xe0\xb4\x92\xe0\xb4\x95\xe0\xb5\x8d\xe0\xb4\x9f\xe0\xb5\x8b\0" + "\xe0\xb4\xa8\xe0\xb4\xb5\xe0\xb4\x82\0" + "\xe0\xb4\xa1\xe0\xb4\xbf\xe0\xb4\xb8\xe0\xb4\x82\0" + "\xe0\xa6\xa6\xe0\xa7\x87\xe0\xa6\x93\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa7\xb0\0" + "\xe0\xa6\xb8\xe0\xa7\x8b\xe0\xa6\xae\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa7\xb0\0" + "\xe0\xa6\xae\xe0\xa6\x99\xe0\xa7\x8d\xe0\xa6\x97\xe0\xa6\xb2\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa7\xb0\0" + "\xe0\xa6\xac\xe0\xa7\x81\xe0\xa6\xa7\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa7\xb0\0" + "\xe0\xa6\xac\xe0\xa7\x83\xe0\xa6\xb9\xe0\xa6\xb7\xe0\xa7\x8d\xe0\xa6\xaa\xe0\xa6\xa4\xe0\xa6\xbf\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa7\xb0\0" + "\xe0\xa6\xb6\xe0\xa7\x81\xe0\xa6\x95\xe0\xa7\x8d\xe0\xa7\xb0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa7\xb0\0" + "\xe0\xa6\xb6\xe0\xa6\xa8\xe0\xa6\xbf\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa7\xb0\0" + "\xe0\xa7\xb0\xe0\xa6\xac\xe0\xa6\xbf\0" + "\xe0\xa6\xac\xe0\xa7\x83\xe0\xa6\xb9\xe0\xa6\xb7\xe0\xa7\x8d\xe0\xa6\xaa\xe0\xa6\xa4\xe0\xa6\xbf\0" + "\xe0\xa6\xb6\xe0\xa7\x81\xe0\xa6\x95\xe0\xa7\x8d\xe0\xa7\xb0\0" + "\xe0\xa6\x9c\xe0\xa6\xbe\xe0\xa6\xa8\xe0\xa7\x81\xe0\xa7\xb1\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa7\x80\0" + "\xe0\xa6\xab\xe0\xa7\x87\xe0\xa6\xac\xe0\xa7\x8d\xe0\xa7\xb0\xe0\xa7\x81\xe0\xa7\xb1\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa7\x80\0" + "\xe0\xa6\xae\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa7\x8d\xe0\xa6\x9a\0" + "\xe0\xa6\x8f\xe0\xa6\xaa\xe0\xa7\x8d\xe0\xa7\xb0\xe0\xa6\xbf\xe0\xa6\xb2\0" + "\xe0\xa6\x86\xe0\xa6\x97\xe0\xa6\xb7\xe0\xa7\x8d\xe0\xa6\x9f\0" + "\xe0\xa6\x9b\xe0\xa7\x87\xe0\xa6\xaa\xe0\xa7\x8d\xe0\xa6\xa4\xe0\xa7\x87\xe0\xa6\xae\xe0\xa7\x8d\xe0\xa6\xac\xe0\xa7\xb0\0" + "\xe0\xa6\x85\xe0\xa6\x95\xe0\xa7\x8d\xe0\xa6\x9f\xe0\xa7\x8b\xe0\xa6\xac\xe0\xa7\xb0\0" + "\xe0\xa6\xa8\xe0\xa7\xb1\xe0\xa7\x87\xe0\xa6\xae\xe0\xa7\x8d\xe0\xa6\xac\xe0\xa7\xb0\0" + "\xe0\xa6\xa1\xe0\xa6\xbf\xe0\xa6\x9a\xe0\xa7\x87\xe0\xa6\xae\xe0\xa7\x8d\xe0\xa6\xac\xe0\xa7\xb0\0" + "\xe0\xa6\x9c\xe0\xa6\xbe\xe0\xa6\xa8\xe0\xa7\x81\0" + "\xe0\xa6\xab\xe0\xa7\x87\xe0\xa6\xac\xe0\xa7\x8d\xe0\xa7\xb0\xe0\xa7\x81\0" + "\xe0\xa6\x86\xe0\xa6\x97\0" + "\xe0\xa6\xb8\xe0\xa7\x87\xe0\xa6\xaa\xe0\xa7\x8d\xe0\xa6\x9f\0" + "\xe0\xa6\x85\xe0\xa6\x95\xe0\xa7\x8d\xe0\xa6\x9f\xe0\xa7\x8b\0" + "\xe0\xa6\xa8\xe0\xa6\xad\xe0\xa7\x87\0" + "\xe0\xa6\xa1\xe0\xa6\xbf\xe0\xa6\xb8\xe0\xa7\x87\0" + "\xe0\xa4\xae\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xb3\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xae\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xb3\0" + "\xe0\xa4\x9c\xe0\xa4\xbe\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x80\0" + "\xe0\xa4\xab\xe0\xa5\x87\xe0\xa4\xac\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x81\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x80\0" + "\xe0\xa4\x8f\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa4\xbf\xe0\xa4\xb2\0" + "\xe0\xa4\xae\xe0\xa5\x87\0" + "\xe0\xa4\x9c\xe0\xa5\x81\xe0\xa4\xb2\xe0\xa5\x88\0" + "\xe0\xa4\x91\xe0\xa4\x97\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\x9f\0" + "\xe0\xa4\xb8\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x87\xe0\xa4\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\x91\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x8b\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\xa8\xe0\xa5\x8b\xe0\xa4\xb5\xe0\xa5\x8d\xe0\xa4\xb9\xe0\xa5\x87\xe0\xa4\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\xa1\xe0\xa4\xbf\xe0\xa4\xb8\xe0\xa5\x87\xe0\xa4\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\x9c\xe0\xa4\xbe\xe0\xa4\xa8\xe0\xa5\x87\0" + "\xe0\xa4\xab\xe0\xa5\x87\xe0\xa4\xac\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x81\0" + "\xe0\xa4\x8f\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa4\xbf\0" + "\xe0\xa4\x91\xe0\xa4\x97\0" + "\xe0\xa4\xb8\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x87\xe0\xa4\x82\0" + "\xe0\xa4\x91\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x8b\0" + "\xe0\xa4\xa8\xe0\xa5\x8b\xe0\xa4\xb5\xe0\xa5\x8d\xe0\xa4\xb9\xe0\xa5\x87\xe0\xa4\x82\0" + "\xe0\xa4\xa1\xe0\xa4\xbf\xe0\xa4\xb8\xe0\xa5\x87\xe0\xa4\x82\0" + "\xd0\xbd\xd1\x8f\xd0\xbc\0" + "\xd0\xb4\xd0\xb0\xd0\xb2\xd0\xb0\xd0\xb0\0" + "\xd0\xbc\xd1\x8f\xd0\xb3\xd0\xbc\xd0\xb0\xd1\x80\0" + "\xd0\xbb\xd1\x85\xd0\xb0\xd0\xb3\xd0\xb2\xd0\xb0\0" + "\xd0\xbf\xd2\xaf\xd1\x80\xd1\x8d\xd0\xb2\0" + "\xd0\xb1\xd0\xb0\xd0\xb0\xd1\x81\xd0\xb0\xd0\xbd\0" + "\xd0\xb1\xd1\x8f\xd0\xbc\xd0\xb1\xd0\xb0\0" + "\xd0\x9d\xd1\x8f\0" + "\xd0\x94\xd0\xb0\0" + "\xd0\x9c\xd1\x8f\0" + "\xd0\x9b\xd1\x85\0" + "\xd0\x9f\xd2\xaf\0" + "\xd0\x91\xd0\xb0\0" + "\xd0\x91\xd1\x8f\0" + "\xd0\x9d\xd1\x8d\xd0\xb3\xd0\xb4\xd2\xaf\xd0\xb3\xd1\x8d\xd1\x8d\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\xa5\xd0\xbe\xd1\x91\xd1\x80\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x93\xd1\x83\xd1\x80\xd0\xb0\xd0\xb2\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x94\xd3\xa9\xd1\x80\xd3\xa9\xd0\xb2\xd0\xb4\xd2\xaf\xd0\xb3\xd1\x8d\xd1\x8d\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\xa2\xd0\xb0\xd0\xb2\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x97\xd1\x83\xd1\x80\xd0\xb3\xd0\xb0\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x94\xd0\xbe\xd0\xbb\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x9d\xd0\xb0\xd0\xb9\xd0\xbc\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x95\xd1\x81\xd0\xb4\xd2\xaf\xd0\xb3\xd1\x8d\xd1\x8d\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x90\xd1\x80\xd0\xb0\xd0\xb2\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x90\xd1\x80\xd0\xb2\xd0\xb0\xd0\xbd \xd0\xbd\xd1\x8d\xd0\xb3\xd0\xb4\xd2\xaf\xd0\xb3\xd1\x8d\xd1\x8d\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xd0\x90\xd1\x80\xd0\xb2\xd0\xb0\xd0\xbd \xd1\x85\xd0\xbe\xd1\x91\xd1\x80\xd0\xb4\xd1\x83\xd0\xb3\xd0\xb0\xd0\xb0\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "1-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "2-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "3-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "4-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "5-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "6-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "7-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "8-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "9-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "10-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "11-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "12-\xd1\x80 \xd1\x81\xd0\xb0\xd1\x80\0" + "\xe0\xbd\x82\xe0\xbd\x9f\xe0\xbd\xa0\xe0\xbc\x8b\xe0\xbd\x89\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x98\xe0\xbc\x8b\0" + "\xe0\xbd\x82\xe0\xbd\x9f\xe0\xbd\xa0\xe0\xbc\x8b\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\0" + "\xe0\xbd\x82\xe0\xbd\x9f\xe0\xbd\xa0\xe0\xbc\x8b\xe0\xbd\x98\xe0\xbd\xb2\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbd\x98\xe0\xbd\xa2\xe0\xbc\x8b\0" + "\xe0\xbd\x82\xe0\xbd\x9f\xe0\xbd\xa0\xe0\xbc\x8b\xe0\xbd\xa3\xe0\xbe\xb7\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x82\xe0\xbd\x9f\xe0\xbd\xa0\xe0\xbc\x8b\xe0\xbd\x95\xe0\xbd\xb4\xe0\xbd\xa2\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\xb4\xe0\xbc\x8b\0" + "\xe0\xbd\x82\xe0\xbd\x9f\xe0\xbd\xa0\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\xe0\xbd\xa6\xe0\xbd\x84\xe0\xbd\xa6\xe0\xbc\x8b\0" + "\xe0\xbd\x82\xe0\xbd\x9f\xe0\xbd\xa0\xe0\xbc\x8b\xe0\xbd\xa6\xe0\xbe\xa4\xe0\xbd\xba\xe0\xbd\x93\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x89\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x98\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\0" + "\xe0\xbd\x98\xe0\xbd\xb2\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbd\x98\xe0\xbd\xa2\xe0\xbc\x8b\0" + "\xe0\xbd\xa3\xe0\xbe\xb7\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x95\xe0\xbd\xb4\xe0\xbd\xa2\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\xb4\xe0\xbc\x8b\0" + "\xe0\xbd\x94\xe0\xbc\x8b\xe0\xbd\xa6\xe0\xbd\x84\xe0\xbd\xa6\xe0\xbc\x8b\0" + "\xe0\xbd\xa6\xe0\xbe\xa4\xe0\xbd\xba\xe0\xbd\x93\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x89\xe0\xbd\xb2\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\0" + "\xe0\xbd\x98\xe0\xbd\xb2\xe0\xbd\x82\0" + "\xe0\xbd\xa3\xe0\xbe\xb7\xe0\xbd\x82\0" + "\xe0\xbd\x95\xe0\xbd\xb4\xe0\xbd\xa2\0" + "\xe0\xbd\xa6\xe0\xbd\x84\xe0\xbd\xa6\0" + "\xe0\xbd\xa6\xe0\xbe\xa4\xe0\xbd\xba\xe0\xbd\x93\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbd\x84\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbd\xbc\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\x89\xe0\xbd\xb2\xe0\xbd\xa6\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\xa6\xe0\xbd\xb4\xe0\xbd\x98\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x9e\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\xa3\xe0\xbe\x94\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbe\xb2\xe0\xbd\xb4\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x91\xe0\xbd\xb4\xe0\xbd\x93\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\xa2\xe0\xbe\x92\xe0\xbe\xb1\xe0\xbd\x91\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbd\x82\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x85\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x85\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\x85\xe0\xbd\xb2\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x85\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\x89\xe0\xbd\xb2\xe0\xbd\xa6\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbc\x8b\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbd\x84\xe0\xbc\x8b\xe0\xbd\x94\xe0\xbd\xbc\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\x89\xe0\xbd\xb2\xe0\xbd\xa6\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\xa6\xe0\xbd\xb4\xe0\xbd\x98\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x9e\xe0\xbd\xb2\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\xa3\xe0\xbe\x94\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbe\xb2\xe0\xbd\xb4\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x91\xe0\xbd\xb4\xe0\xbd\x93\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\xa2\xe0\xbe\x92\xe0\xbe\xb1\xe0\xbd\x91\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x91\xe0\xbd\x82\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x85\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x85\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\x85\xe0\xbd\xb2\xe0\xbd\x82\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbc\x8b\xe0\xbd\x96\xe0\xbd\x85\xe0\xbd\xb4\xe0\xbc\x8b\xe0\xbd\x82\xe0\xbd\x89\xe0\xbd\xb2\xe0\xbd\xa6\xe0\xbc\x8b\xe0\xbd\x94\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa1\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa2\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa3\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa4\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa5\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa6\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa7\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa8\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa9\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa1\xe0\xbc\xa0\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa1\xe0\xbc\xa1\0" + "\xe0\xbd\x9f\xe0\xbe\xb3\xe0\xbc\x8b\xe0\xbc\xa1\xe0\xbc\xa2\0" + "Dydd Sul\0" + "Dydd Llun\0" + "Dydd Mawrth\0" + "Dydd Mercher\0" + "Dydd Iau\0" + "Dydd Gwener\0" + "Dydd Sadwrn\0" + "Sul\0" + "Llun\0" + "Mer\0" + "Iau\0" + "Gwe\0" + "Sad\0" + "Ll\0" + "Ionawr\0" + "Chwefror\0" + "Mawrth\0" + "Ebrill\0" + "Mehefin\0" + "Gorffennaf\0" + "Awst\0" + "Medi\0" + "Hydref\0" + "Tachwedd\0" + "Rhagfyr\0" + "Ion\0" + "Chw\0" + "Ebr\0" + "Meh\0" + "Gor\0" + "Hyd\0" + "Tach\0" + "Rhag\0" + "\xe1\x9e\xa2\xe1\x9e\xb6\xe1\x9e\x91\xe1\x9e\xb7\xe1\x9e\x8f\xe1\x9f\x92\xe1\x9e\x99\0" + "\xe1\x9e\x85\xe1\x9f\x90\xe1\x9e\x93\xe1\x9f\x92\xe1\x9e\x91\0" + "\xe1\x9e\xa2\xe1\x9e\x84\xe1\x9f\x92\xe1\x9e\x82\xe1\x9e\xb6\xe1\x9e\x9a\0" + "\xe1\x9e\x96\xe1\x9e\xbb\xe1\x9e\x92\0" + "\xe1\x9e\x96\xe1\x9f\x92\xe1\x9e\x9a\xe1\x9e\xa0\xe1\x9e\x9f\xe1\x9f\x92\xe1\x9e\x94\xe1\x9e\x8f\xe1\x9e\xb7\xe1\x9f\x8d\0" + "\xe1\x9e\x9f\xe1\x9e\xbb\xe1\x9e\x80\xe1\x9f\x92\xe1\x9e\x9a\0" + "\xe1\x9e\x9f\xe1\x9f\x85\xe1\x9e\x9a\xe1\x9f\x8d\0" + "\xe1\x9e\xa2\0" + "\xe1\x9e\x85\0" + "\xe1\x9e\x96\0" + "\xe1\x9e\x9f\0" + "\xe1\x9e\x98\xe1\x9e\x80\xe1\x9e\x9a\xe1\x9e\xb6\0" + "\xe1\x9e\x80\xe1\x9e\xbb\xe1\x9e\x98\xe1\x9f\x92\xe1\x9e\x97\xe1\x9f\x88\0" + "\xe1\x9e\x98\xe1\x9e\xb8\xe1\x9e\x93\xe1\x9e\xb6\0" + "\xe1\x9e\x98\xe1\x9f\x81\xe1\x9e\x9f\xe1\x9e\xb6\0" + "\xe1\x9e\xa7\xe1\x9e\x9f\xe1\x9e\x97\xe1\x9e\xb6\0" + "\xe1\x9e\x98\xe1\x9e\xb7\xe1\x9e\x90\xe1\x9e\xbb\xe1\x9e\x93\xe1\x9e\xb6\0" + "\xe1\x9e\x80\xe1\x9e\x80\xe1\x9f\x92\xe1\x9e\x80\xe1\x9e\x8a\xe1\x9e\xb6\0" + "\xe1\x9e\x9f\xe1\x9e\xb8\xe1\x9e\xa0\xe1\x9e\xb6\0" + "\xe1\x9e\x80\xe1\x9e\x89\xe1\x9f\x92\xe1\x9e\x89\xe1\x9e\xb6\0" + "\xe1\x9e\x8f\xe1\x9e\xbb\xe1\x9e\x9b\xe1\x9e\xb6\0" + "\xe1\x9e\x9c\xe1\x9e\xb7\xe1\x9e\x85\xe1\x9f\x92\xe1\x9e\x86\xe1\x9e\xb7\xe1\x9e\x80\xe1\x9e\xb6\0" + "\xe1\x9e\x92\xe1\x9f\x92\xe1\x9e\x93\xe1\x9e\xbc\0" + "\xe0\xba\xa7\xe0\xba\xb1\xe0\xba\x99\xe0\xba\xad\xe0\xba\xb2\xe0\xba\x97\xe0\xba\xb4\xe0\xba\x94\0" + "\xe0\xba\xa7\xe0\xba\xb1\xe0\xba\x99\xe0\xba\x88\xe0\xba\xb1\xe0\xba\x99\0" + "\xe0\xba\xa7\xe0\xba\xb1\xe0\xba\x99\xe0\xba\xad\xe0\xba\xb1\xe0\xba\x87\xe0\xba\x84\xe0\xba\xb2\xe0\xba\x99\0" + "\xe0\xba\xa7\xe0\xba\xb1\xe0\xba\x99\xe0\xba\x9e\xe0\xba\xb8\xe0\xba\x94\0" + "\xe0\xba\xa7\xe0\xba\xb1\xe0\xba\x99\xe0\xba\x9e\xe0\xba\xb0\xe0\xba\xab\xe0\xba\xb1\xe0\xba\x94\0" + "\xe0\xba\xa7\xe0\xba\xb1\xe0\xba\x99\xe0\xba\xaa\xe0\xba\xb8\xe0\xba\x81\0" + "\xe0\xba\xa7\xe0\xba\xb1\xe0\xba\x99\xe0\xbb\x80\xe0\xba\xaa\xe0\xba\xbb\xe0\xba\xb2\0" + "\xe0\xba\xad\xe0\xba\xb2\xe0\xba\x97\xe0\xba\xb4\xe0\xba\x94\0" + "\xe0\xba\x88\xe0\xba\xb1\xe0\xba\x99\0" + "\xe0\xba\xad\xe0\xba\xb1\xe0\xba\x87\xe0\xba\x84\xe0\xba\xb2\xe0\xba\x99\0" + "\xe0\xba\x9e\xe0\xba\xb8\xe0\xba\x94\0" + "\xe0\xba\x9e\xe0\xba\xb0\xe0\xba\xab\xe0\xba\xb1\xe0\xba\x94\0" + "\xe0\xba\xaa\xe0\xba\xb8\xe0\xba\x81\0" + "\xe0\xbb\x80\xe0\xba\xaa\xe0\xba\xbb\xe0\xba\xb2\0" + "\xe0\xba\xad\xe0\xba\xb2\0" + "\xe0\xba\x88\0" + "\xe0\xba\xad\0" + "\xe0\xba\x9e\0" + "\xe0\xba\x9e\xe0\xba\xab\0" + "\xe0\xba\xaa\xe0\xba\xb8\0" + "\xe0\xba\xaa\0" + "\xe0\xba\xa1\xe0\xba\xb1\xe0\xba\x87\xe0\xba\x81\xe0\xba\xad\xe0\xba\x99\0" + "\xe0\xba\x81\xe0\xba\xb8\xe0\xba\xa1\xe0\xba\x9e\xe0\xba\xb2\0" + "\xe0\xba\xa1\xe0\xba\xb5\xe0\xba\x99\xe0\xba\xb2\0" + "\xe0\xbb\x80\xe0\xba\xa1\xe0\xba\xaa\xe0\xba\xb2\0" + "\xe0\xba\x9e\xe0\xba\xb6\xe0\xba\x94\xe0\xba\xaa\xe0\xba\xb0\xe0\xba\x9e\xe0\xba\xb2\0" + "\xe0\xba\xa1\xe0\xba\xb4\xe0\xba\x96\xe0\xba\xb8\xe0\xba\x99\xe0\xba\xb2\0" + "\xe0\xba\x81\xe0\xbb\x8d\xe0\xba\xa5\xe0\xba\xb0\xe0\xba\x81\xe0\xba\xbb\xe0\xba\x94\0" + "\xe0\xba\xaa\xe0\xba\xb4\xe0\xba\x87\xe0\xba\xab\xe0\xba\xb2\0" + "\xe0\xba\x81\xe0\xba\xb1\xe0\xba\x99\xe0\xba\x8d\xe0\xba\xb2\0" + "\xe0\xba\x95\xe0\xba\xb8\xe0\xba\xa5\xe0\xba\xb2\0" + "\xe0\xba\x9e\xe0\xba\xb0\xe0\xba\x88\xe0\xba\xb4\xe0\xba\x81\0" + "\xe0\xba\x97\xe0\xba\xb1\xe0\xba\x99\xe0\xba\xa7\xe0\xba\xb2\0" + "\xe0\xba\xa1.\xe0\xba\x81.\0" + "\xe0\xba\x81.\xe0\xba\x9e.\0" + "\xe0\xba\xa1.\xe0\xba\x99.\0" + "\xe0\xba\xa1.\xe0\xba\xaa.\0" + "\xe0\xba\x9e.\xe0\xba\x9e.\0" + "\xe0\xba\xa1\xe0\xba\xb4.\xe0\xba\x96.\0" + "\xe0\xba\x81.\xe0\xba\xa5.\0" + "\xe0\xba\xaa.\xe0\xba\xab.\0" + "\xe0\xba\x81.\xe0\xba\x8d.\0" + "\xe0\xba\x95.\xe0\xba\xa5.\0" + "\xe0\xba\x9e.\xe0\xba\x88.\0" + "\xe0\xba\x97.\xe0\xba\xa7.\0" + "\xe1\x80\x90\xe1\x80\x94\xe1\x80\x84\xe1\x80\xba\xe1\x80\xb9\xe1\x80\x82\xe1\x80\x94\xe1\x80\xbd\xe1\x80\xb1\0" + "\xe1\x80\x90\xe1\x80\x94\xe1\x80\x84\xe1\x80\xba\xe1\x80\xb9\xe1\x80\x9c\xe1\x80\xac\0" + "\xe1\x80\xa1\xe1\x80\x84\xe1\x80\xba\xe1\x80\xb9\xe1\x80\x82\xe1\x80\xab\0" + "\xe1\x80\x97\xe1\x80\xaf\xe1\x80\x92\xe1\x80\xb9\xe1\x80\x93\xe1\x80\x9f\xe1\x80\xb0\xe1\x80\xb8\0" + "\xe1\x80\x80\xe1\x80\xbc\xe1\x80\xac\xe1\x80\x9e\xe1\x80\x95\xe1\x80\x90\xe1\x80\xb1\xe1\x80\xb8\0" + "\xe1\x80\x9e\xe1\x80\xb1\xe1\x80\xac\xe1\x80\x80\xe1\x80\xbc\xe1\x80\xac\0" + "\xe1\x80\x85\xe1\x80\x94\xe1\x80\xb1\0" + "\xe1\x80\x90\0" + "\xe1\x80\xa1\0" + "\xe1\x80\x97\0" + "\xe1\x80\x80\0" + "\xe1\x80\x9e\0" + "\xe1\x80\x85\0" + "\xe1\x80\x87\xe1\x80\x94\xe1\x80\xba\xe1\x80\x94\xe1\x80\x9d\xe1\x80\xab\xe1\x80\x9b\xe1\x80\xae\0" + "\xe1\x80\x96\xe1\x80\xb1\xe1\x80\x96\xe1\x80\xb1\xe1\x80\xac\xe1\x80\xba\xe1\x80\x9d\xe1\x80\xab\xe1\x80\x9b\xe1\x80\xae\0" + "\xe1\x80\x99\xe1\x80\x90\xe1\x80\xba\0" + "\xe1\x80\xa7\xe1\x80\x95\xe1\x80\xbc\xe1\x80\xae\0" + "\xe1\x80\x99\xe1\x80\xb1\0" + "\xe1\x80\x87\xe1\x80\xbd\xe1\x80\x94\xe1\x80\xba\0" + "\xe1\x80\x87\xe1\x80\xb0\xe1\x80\x9c\xe1\x80\xad\xe1\x80\xaf\xe1\x80\x84\xe1\x80\xba\0" + "\xe1\x80\xa9\xe1\x80\x82\xe1\x80\xaf\xe1\x80\x90\xe1\x80\xba\0" + "\xe1\x80\x85\xe1\x80\x80\xe1\x80\xba\xe1\x80\x90\xe1\x80\x84\xe1\x80\xba\xe1\x80\x98\xe1\x80\xac\0" + "\xe1\x80\xa1\xe1\x80\xb1\xe1\x80\xac\xe1\x80\x80\xe1\x80\xba\xe1\x80\x90\xe1\x80\xad\xe1\x80\xaf\xe1\x80\x98\xe1\x80\xac\0" + "\xe1\x80\x94\xe1\x80\xad\xe1\x80\xaf\xe1\x80\x9d\xe1\x80\x84\xe1\x80\xba\xe1\x80\x98\xe1\x80\xac\0" + "\xe1\x80\x92\xe1\x80\xae\xe1\x80\x87\xe1\x80\x84\xe1\x80\xba\xe1\x80\x98\xe1\x80\xac\0" + "\xe1\x80\x87\xe1\x80\x94\xe1\x80\xba\0" + "\xe1\x80\x96\xe1\x80\xb1\0" + "\xe1\x80\xa7\0" + "\xe1\x80\x87\xe1\x80\xb0\0" + "\xe1\x80\xa9\0" + "\xe1\x80\x85\xe1\x80\x80\xe1\x80\xba\0" + "\xe1\x80\xa1\xe1\x80\xb1\xe1\x80\xac\xe1\x80\x80\xe1\x80\xba\0" + "\xe1\x80\x94\xe1\x80\xad\xe1\x80\xaf\0" + "\xe1\x80\x92\xe1\x80\xae\0" + "luns\0" + "m\xc3\xa9rcores\0" + "xoves\0" + "venres\0" + "Dom.\0" + "Luns\0" + "Mar.\0" + "M\xc3\xa9r.\0" + "Xov.\0" + "Ven.\0" + "S\xc3\xa1\x62.\0" + "Xaneiro\0" + "Febreiro\0" + "Marzo\0" + "Abril\0" + "Maio\0" + "Xu\xc3\xb1o\0" + "Xullo\0" + "Agosto\0" + "Setembro\0" + "Outubro\0" + "Novembro\0" + "Decembro\0" + "xaneiro\0" + "febreiro\0" + "xu\xc3\xb1o\0" + "xullo\0" + "decembro\0" + "Xan.\0" + "Abr.\0" + "Xul.\0" + "Ago.\0" + "Set.\0" + "Out.\0" + "Dec.\0" + "\xe0\xa4\x86\xe0\xa4\xa6\xe0\xa4\xbf\xe0\xa4\xa4\xe0\xa5\x8d\xe0\xa4\xaf\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xae\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xb3\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\x93\xe0\xa4\x97\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\x9f\0" + "\xe0\xa4\xb8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x87\xe0\xa4\x82\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\x93\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x8b\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xb6\x89\xe0\xb6\xbb\xe0\xb7\x92\xe0\xb6\xaf\xe0\xb7\x8f\0" + "\xe0\xb7\x83\xe0\xb6\xb3\xe0\xb7\x94\xe0\xb6\xaf\xe0\xb7\x8f\0" + "\xe0\xb6\x85\xe0\xb6\x9f\xe0\xb7\x84\xe0\xb6\xbb\xe0\xb7\x94\xe0\xb7\x80\xe0\xb7\x8f\xe0\xb6\xaf\xe0\xb7\x8f\0" + "\xe0\xb6\xb6\xe0\xb6\xaf\xe0\xb7\x8f\xe0\xb6\xaf\xe0\xb7\x8f\0" + "\xe0\xb6\xb6\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\xe0\xb7\x84\xe0\xb7\x83\xe0\xb7\x8a\xe0\xb6\xb4\xe0\xb6\xad\xe0\xb7\x92\xe0\xb6\xb1\xe0\xb7\x8a\xe0\xb6\xaf\xe0\xb7\x8f\0" + "\xe0\xb7\x83\xe0\xb7\x92\xe0\xb6\x9a\xe0\xb7\x94\xe0\xb6\xbb\xe0\xb7\x8f\xe0\xb6\xaf\xe0\xb7\x8f\0" + "\xe0\xb7\x83\xe0\xb7\x99\xe0\xb6\xb1\xe0\xb7\x83\xe0\xb7\x94\xe0\xb6\xbb\xe0\xb7\x8f\xe0\xb6\xaf\xe0\xb7\x8f\0" + "\xe0\xb6\x85\xe0\xb6\x9f\xe0\xb7\x84\0" + "\xe0\xb6\xb6\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\xe0\xb7\x84\xe0\xb7\x83\xe0\xb7\x8a\0" + "\xe0\xb7\x83\xe0\xb7\x92\xe0\xb6\x9a\xe0\xb7\x94\0" + "\xe0\xb7\x83\xe0\xb7\x99\xe0\xb6\xb1\0" + "\xe0\xb6\x89\0" + "\xe0\xb7\x83\0" + "\xe0\xb6\x85\0" + "\xe0\xb6\xb6\0" + "\xe0\xb6\xb6\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\0" + "\xe0\xb7\x83\xe0\xb7\x92\0" + "\xe0\xb7\x83\xe0\xb7\x99\0" + "\xe0\xb6\xa2\xe0\xb6\xb1\xe0\xb7\x80\xe0\xb7\x8f\xe0\xb6\xbb\xe0\xb7\x92\0" + "\xe0\xb6\xb4\xe0\xb7\x99\xe0\xb6\xb6\xe0\xb6\xbb\xe0\xb7\x80\xe0\xb7\x8f\xe0\xb6\xbb\xe0\xb7\x92\0" + "\xe0\xb6\xb8\xe0\xb7\x8f\xe0\xb6\xbb\xe0\xb7\x8a\xe0\xb6\xad\xe0\xb7\x94\0" + "\xe0\xb6\x85\xe0\xb6\xb4\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\xe0\xb7\x9a\xe0\xb6\xbd\xe0\xb7\x8a\0" + "\xe0\xb6\xb8\xe0\xb7\x90\xe0\xb6\xba\xe0\xb7\x92\0" + "\xe0\xb6\xa2\xe0\xb7\x96\xe0\xb6\xb1\xe0\xb7\x92\0" + "\xe0\xb6\xa2\xe0\xb7\x96\xe0\xb6\xbd\xe0\xb7\x92\0" + "\xe0\xb6\x85\xe0\xb6\x9c\xe0\xb7\x9d\xe0\xb7\x83\xe0\xb7\x8a\xe0\xb6\xad\xe0\xb7\x94\0" + "\xe0\xb7\x83\xe0\xb7\x90\xe0\xb6\xb4\xe0\xb7\x8a\xe0\xb6\xad\xe0\xb7\x90\xe0\xb6\xb8\xe0\xb7\x8a\xe0\xb6\xb6\xe0\xb6\xbb\xe0\xb7\x8a\0" + "\xe0\xb6\x94\xe0\xb6\x9a\xe0\xb7\x8a\xe0\xb6\xad\xe0\xb7\x9d\xe0\xb6\xb6\xe0\xb6\xbb\xe0\xb7\x8a\0" + "\xe0\xb6\xb1\xe0\xb7\x9c\xe0\xb7\x80\xe0\xb7\x90\xe0\xb6\xb8\xe0\xb7\x8a\xe0\xb6\xb6\xe0\xb6\xbb\xe0\xb7\x8a\0" + "\xe0\xb6\xaf\xe0\xb7\x99\xe0\xb7\x83\xe0\xb7\x90\xe0\xb6\xb8\xe0\xb7\x8a\xe0\xb6\xb6\xe0\xb6\xbb\xe0\xb7\x8a\0" + "\xe0\xb6\xa2\xe0\xb6\xb1\0" + "\xe0\xb6\xb4\xe0\xb7\x99\xe0\xb6\xb6\0" + "\xe0\xb6\xb8\xe0\xb7\x8f\xe0\xb6\xbb\xe0\xb7\x8a\0" + "\xe0\xb6\x85\xe0\xb6\x9c\xe0\xb7\x9d\0" + "\xe0\xb7\x83\xe0\xb7\x90\xe0\xb6\xb4\xe0\xb7\x8a\0" + "\xe0\xb6\x94\xe0\xb6\x9a\xe0\xb7\x8a\0" + "\xe0\xb6\xb1\xe0\xb7\x9c\xe0\xb7\x80\xe0\xb7\x90\0" + "\xe0\xb6\xaf\xe0\xb7\x99\xe0\xb7\x83\xe0\xb7\x90\0" + "\xe1\x8e\xa4\xe1\x8e\xbe\xe1\x8f\x99\xe1\x8f\x93\xe1\x8f\x86\xe1\x8f\x8d\xe1\x8e\xac\0" + "\xe1\x8e\xa4\xe1\x8e\xbe\xe1\x8f\x99\xe1\x8f\x93\xe1\x8f\x89\xe1\x8f\x85\xe1\x8e\xaf\0" + "\xe1\x8f\x94\xe1\x8e\xb5\xe1\x8f\x81\xe1\x8e\xa2\xe1\x8e\xa6\0" + "\xe1\x8f\xa6\xe1\x8e\xa2\xe1\x8f\x81\xe1\x8e\xa2\xe1\x8e\xa6\0" + "\xe1\x8f\x85\xe1\x8e\xa9\xe1\x8f\x81\xe1\x8e\xa2\xe1\x8e\xa6\0" + "\xe1\x8f\xa7\xe1\x8e\xbe\xe1\x8e\xa9\xe1\x8e\xb6\xe1\x8f\x8d\xe1\x8f\x97\0" + "\xe1\x8e\xa4\xe1\x8e\xbe\xe1\x8f\x99\xe1\x8f\x93\xe1\x8f\x88\xe1\x8f\x95\xe1\x8e\xbe\0" + "\xe1\x8f\x86\xe1\x8f\x8d\xe1\x8e\xac\0" + "\xe1\x8f\x89\xe1\x8f\x85\xe1\x8e\xaf\0" + "\xe1\x8f\x94\xe1\x8e\xb5\xe1\x8f\x81\0" + "\xe1\x8f\xa6\xe1\x8e\xa2\xe1\x8f\x81\0" + "\xe1\x8f\x85\xe1\x8e\xa9\xe1\x8f\x81\0" + "\xe1\x8f\xa7\xe1\x8e\xbe\xe1\x8e\xa9\0" + "\xe1\x8f\x88\xe1\x8f\x95\xe1\x8e\xbe\0" + "\xe1\x8f\x86\0" + "\xe1\x8f\x89\0" + "\xe1\x8f\x94\0" + "\xe1\x8f\xa6\0" + "\xe1\x8f\x85\0" + "\xe1\x8f\xa7\0" + "\xe1\x8e\xa4\0" + "\xe1\x8e\xa4\xe1\x8f\x83\xe1\x8e\xb8\xe1\x8f\x94\xe1\x8f\x85\0" + "\xe1\x8e\xa7\xe1\x8e\xa6\xe1\x8e\xb5\0" + "\xe1\x8e\xa0\xe1\x8f\x85\xe1\x8f\xb1\0" + "\xe1\x8e\xa7\xe1\x8f\xac\xe1\x8f\x82\0" + "\xe1\x8e\xa0\xe1\x8f\x82\xe1\x8f\x8d\xe1\x8e\xac\xe1\x8f\x98\0" + "\xe1\x8f\x95\xe1\x8e\xad\xe1\x8e\xb7\xe1\x8f\xb1\0" + "\xe1\x8e\xab\xe1\x8f\xb0\xe1\x8f\x89\xe1\x8f\x82\0" + "\xe1\x8e\xa6\xe1\x8e\xb6\xe1\x8f\x82\0" + "\xe1\x8f\x9a\xe1\x8e\xb5\xe1\x8f\x8d\xe1\x8f\x97\0" + "\xe1\x8f\x9a\xe1\x8f\x82\xe1\x8f\x85\xe1\x8f\x97\0" + "\xe1\x8f\x85\xe1\x8f\x93\xe1\x8f\x95\xe1\x8f\x86\0" + "\xe1\x8e\xa5\xe1\x8f\x8d\xe1\x8e\xa9\xe1\x8f\xb1\0" + "\xe1\x8e\xa4\xe1\x8f\x83\0" + "\xe1\x8e\xa7\xe1\x8e\xa6\0" + "\xe1\x8e\xa0\xe1\x8f\x85\0" + "\xe1\x8e\xa7\xe1\x8f\xac\0" + "\xe1\x8e\xa0\xe1\x8f\x82\0" + "\xe1\x8f\x95\xe1\x8e\xad\0" + "\xe1\x8e\xab\xe1\x8f\xb0\0" + "\xe1\x8e\xa6\xe1\x8e\xb6\0" + "\xe1\x8f\x9a\xe1\x8e\xb5\0" + "\xe1\x8f\x9a\xe1\x8f\x82\0" + "\xe1\x8f\x85\xe1\x8f\x93\0" + "\xe1\x8e\xa5\xe1\x8f\x8d\0" + "\xe1\x8a\xa5\xe1\x88\x91\xe1\x8b\xb5\0" + "\xe1\x88\xb0\xe1\x8a\x9e\0" + "\xe1\x88\x9b\xe1\x8a\xad\xe1\x88\xb0\xe1\x8a\x9e\0" + "\xe1\x88\xa8\xe1\x89\xa1\xe1\x8b\x95\0" + "\xe1\x88\x90\xe1\x88\x99\xe1\x88\xb5\0" + "\xe1\x8b\x93\xe1\x88\xad\xe1\x89\xa5\0" + "\xe1\x89\x85\xe1\x8b\xb3\xe1\x88\x9c\0" + "\xe1\x88\x9b\xe1\x8a\xad\xe1\x88\xb0\0" + "\xe1\x8a\xa5\0" + "\xe1\x88\xb0\0" + "\xe1\x88\x9b\0" + "\xe1\x88\xa8\0" + "\xe1\x88\x90\0" + "\xe1\x8b\x93\0" + "\xe1\x89\x85\0" + "\xe1\x8c\x83\xe1\x8a\x95\xe1\x8b\xa9\xe1\x8b\x88\xe1\x88\xaa\0" + "\xe1\x8d\x8c\xe1\x89\xa5\xe1\x88\xa9\xe1\x8b\x88\xe1\x88\xaa\0" + "\xe1\x88\x9b\xe1\x88\xad\xe1\x89\xbd\0" + "\xe1\x8a\xa4\xe1\x8d\x95\xe1\x88\xaa\xe1\x88\x8d\0" + "\xe1\x88\x9c\xe1\x8b\xad\0" + "\xe1\x8c\x81\xe1\x8a\x95\0" + "\xe1\x8c\x81\xe1\x88\x8b\xe1\x8b\xad\0" + "\xe1\x8a\xa6\xe1\x8c\x88\xe1\x88\xb5\xe1\x89\xb5\0" + "\xe1\x88\xb4\xe1\x8d\x95\xe1\x89\xb4\xe1\x88\x9d\xe1\x89\xa0\xe1\x88\xad\0" + "\xe1\x8a\xa6\xe1\x8a\xad\xe1\x89\xb6\xe1\x89\xa0\xe1\x88\xad\0" + "\xe1\x8a\x96\xe1\x89\xac\xe1\x88\x9d\xe1\x89\xa0\xe1\x88\xad\0" + "\xe1\x8b\xb2\xe1\x88\xb4\xe1\x88\x9d\xe1\x89\xa0\xe1\x88\xad\0" + "\xe1\x8c\x83\xe1\x8a\x95\xe1\x8b\xa9\0" + "\xe1\x8d\x8c\xe1\x89\xa5\xe1\x88\xa9\0" + "\xe1\x8a\xa4\xe1\x8d\x95\xe1\x88\xaa\0" + "\xe1\x8a\xa6\xe1\x8c\x88\xe1\x88\xb5\0" + "\xe1\x88\xb4\xe1\x8d\x95\xe1\x89\xb4\0" + "\xe1\x8a\xa6\xe1\x8a\xad\xe1\x89\xb6\0" + "\xe1\x8a\x96\xe1\x89\xac\xe1\x88\x9d\0" + "\xe1\x8b\xb2\xe1\x88\xb4\xe1\x88\x9d\0" + "Asamas\0" + "Aynas\0" + "Asinas\0" + "Akras\0" + "Akwas\0" + "Asimwas\0" + "Asi\xe1\xb8\x8dyas\0" + "Asa\0" + "Ayn\0" + "Asn\0" + "Akr\0" + "Akw\0" + "Asm\0" + "As\xe1\xb8\x8d\0" + "Yennayer\0" + "Yebrayer\0" + "Ibrir\0" + "Mayyu\0" + "Yunyu\0" + "Yulyuz\0" + "\xc6\x94uct\0" + "Cutanbir\0" + "K\xe1\xb9\xaduber\0" + "Nwanbir\0" + "Dujanbir\0" + "Yen\0" + "Yeb\0" + "Ibr\0" + "Yun\0" + "Yul\0" + "\xc6\x94uc\0" + "Cut\0" + "K\xe1\xb9\xadu\0" + "Nwa\0" + "Duj\0" + "\xe0\xa4\x86\xe0\xa4\x87\xe0\xa4\xa4\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xb8\xe0\xa5\x8b\xe0\xa4\xae\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xae\xe0\xa4\x99\xe0\xa5\x8d\xe0\xa4\x97\xe0\xa4\xb2\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xac\xe0\xa5\x81\xe0\xa4\xa7\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xac\xe0\xa4\xbf\xe0\xa4\xb9\xe0\xa4\xbf\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xb6\xe0\xa5\x81\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\xb6\xe0\xa4\xa8\xe0\xa4\xbf\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb0\0" + "\xe0\xa4\x86\xe0\xa4\x87\xe0\xa4\xa4\0" + "\xe0\xa4\xae\xe0\xa4\x99\xe0\xa5\x8d\xe0\xa4\x97\xe0\xa4\xb2\0" + "\xe0\xa4\xac\xe0\xa4\xbf\xe0\xa4\xb9\xe0\xa4\xbf\0" + "\xe0\xa4\x86\0" + "\xe0\xa4\xae\0" + "\xe0\xa4\xac\xe0\xa4\xbf\0" + "\xe0\xa4\xab\xe0\xa5\x87\xe0\xa4\xac\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x81\xe0\xa4\x85\xe0\xa4\xb0\xe0\xa5\x80\0" + "\xe0\xa4\x85\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa4\xbf\xe0\xa4\xb2\0" + "\xe0\xa4\x9c\xe0\xa5\x81\xe0\xa4\xa8\0" + "\xe0\xa4\x85\xe0\xa4\x97\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\x9f\0" + "\xe0\xa4\xb8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x87\xe0\xa4\xae\xe0\xa5\x8d\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\x85\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\x9f\xe0\xa5\x8b\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\xa8\xe0\xa5\x8b\xe0\xa4\xad\xe0\xa5\x87\xe0\xa4\xae\xe0\xa5\x8d\xe0\xa4\xac\xe0\xa4\xb0\0" + "\xe0\xa4\xa1\xe0\xa4\xbf\xe0\xa4\xb8\xe0\xa5\x87\xe0\xa4\xae\xe0\xa5\x8d\xe0\xa4\xac\xe0\xa4\xb0\0" + "snein\0" + "moandei\0" + "tiisdei\0" + "woansdei\0" + "tongersdei\0" + "freed\0" + "sneon\0" + "si\0" + "mo\0" + "fr\0" + "Jannewaris\0" + "Febrewaris\0" + "Maaie\0" + "Juny\0" + "Septimber\0" + "Novimber\0" + "Desimber\0" + "Mrt\0" + "\xd9\x88\xd8\xb1\xdb\x8c\0" + "\xd8\xba\xd9\x88\xdb\x8c\xdb\x8c\0" + "\xd8\xba\xd8\xa8\xd8\xb1\xda\xaf\xd9\x88\xd9\x84\xdb\x8c\0" + "\xda\x86\xd9\x86\xda\xaf\xd8\xa7\xda\x9a\0" + "\xd8\xb2\xd9\x85\xd8\xb1\xdb\x8c\0" + "\xd9\x88\xda\x96\xdb\x8c\0" + "\xd8\xaa\xd9\x84\xd9\x87\0" + "\xd9\x84\xda\x93\xd9\x85\0" + "\xd9\x84\xdb\x8c\xd9\x86\xd8\xaf\xdb\x8d\0" + "\xd9\x85\xd8\xb1\xd8\xba\xd9\x88\xd9\x85\xdb\x8c\0" + "\xd8\xb3\xd9\x84\xd9\x88\xd8\xa7\xd8\xba\xd9\x87\0" + "\xda\xa9\xd8\xa8\0" + "Linggo\0" + "Lunes\0" + "Martes\0" + "Miyerkules\0" + "Huwebes\0" + "Biyernes\0" + "Sabado\0" + "Lin\0" + "Lun\0" + "Miy\0" + "Huw\0" + "Biy\0" + "Enero\0" + "Pebrero\0" + "Marso\0" + "Mayo\0" + "Hunyo\0" + "Hulyo\0" + "Setyembre\0" + "Oktubre\0" + "Nobyembre\0" + "Disyembre\0" + "Ene\0" + "Peb\0" + "Abr\0" + "Hun\0" + "Hul\0" + "Nob\0" + "dewo\0" + "aa\xc9\x93nde\0" + "mawbaare\0" + "njeslaare\0" + "naasaande\0" + "mawnde\0" + "hoore-biir\0" + "dew\0" + "aa\xc9\x93\0" + "maw\0" + "naa\0" + "mwd\0" + "hbi\0" + "d\0" + "a\0" + "m\0" + "h\0" + "siilo\0" + "colte\0" + "mbooy\0" + "see\xc9\x97to\0" + "duujal\0" + "korse\0" + "morso\0" + "juko\0" + "siilto\0" + "yarkomaa\0" + "jolal\0" + "bowte\0" + "sii\0" + "col\0" + "mbo\0" + "see\0" + "duu\0" + "kor\0" + "mor\0" + "juk\0" + "slt\0" + "yar\0" + "jol\0" + "bow\0" + "Lahadi\0" + "Litinin\0" + "Talata\0" + "Laraba\0" + "Alhamis\0" + "Jumma\xca\xbc\x61\0" + "Asabar\0" + "Lah\0" + "Lit\0" + "Tal\0" + "Lar\0" + "Alh\0" + "Janairu\0" + "Faburairu\0" + "Maris\0" + "Afirilu\0" + "Mayu\0" + "Yuni\0" + "Yuli\0" + "Agusta\0" + "Satumba\0" + "Nuwamba\0" + "Disamba\0" + "Fab\0" + "Afi\0" + "Agu\0" + "Nuw\0" + "\xe1\xbb\x8cj\xe1\xbb\x8d\xcc\x81 \xc3\x80\xc3\xack\xc3\xba\0" + "\xe1\xbb\x8cj\xe1\xbb\x8d\xcc\x81 Aj\xc3\xa9\0" + "\xe1\xbb\x8cj\xe1\xbb\x8d\xcc\x81 \xc3\x8cs\xe1\xba\xb9\xcc\x81gun\0" + "\xe1\xbb\x8cj\xe1\xbb\x8d\xcc\x81r\xc3\xba\0" + "\xe1\xbb\x8cj\xe1\xbb\x8d\xcc\x81\x62\xe1\xbb\x8d\0" + "\xe1\xbb\x8cj\xe1\xbb\x8d\xcc\x81 \xe1\xba\xb8t\xc3\xac\0" + "\xe1\xbb\x8cj\xe1\xbb\x8d\xcc\x81 \xc3\x80\x62\xc3\xa1m\xe1\xba\xb9\xcc\x81ta\0" + "\xc3\x80\xc3\xack\xc3\xba\0" + "Aj\xc3\xa9\0" + "\xc3\x8cs\xe1\xba\xb9\xcc\x81gun\0" + "\xe1\xba\xb8t\xc3\xac\0" + "\xc3\x80\x62\xc3\xa1m\xe1\xba\xb9\xcc\x81ta\0" + "O\xe1\xb9\xa3\xc3\xb9 \xe1\xb9\xa2\xe1\xba\xb9\xcc\x81r\xe1\xba\xb9\xcc\x81\0" + "O\xe1\xb9\xa3\xc3\xb9 \xc3\x88r\xc3\xa8l\xc3\xa8\0" + "O\xe1\xb9\xa3\xc3\xb9 \xe1\xba\xb8r\xe1\xba\xb9\xcc\x80n\xc3\xa0\0" + "O\xe1\xb9\xa3\xc3\xb9 \xc3\x8cgb\xc3\xa9\0" + "O\xe1\xb9\xa3\xc3\xb9 \xe1\xba\xb8\xcc\x80\x62ibi\0" + "O\xe1\xb9\xa3\xc3\xb9 \xc3\x92k\xc3\xba\x64u\0" + "O\xe1\xb9\xa3\xc3\xb9 Ag\xe1\xba\xb9m\xe1\xbb\x8d\0" + "O\xe1\xb9\xa3\xc3\xb9 \xc3\x92g\xc3\xban\0" + "O\xe1\xb9\xa3\xc3\xb9 Owewe\0" + "O\xe1\xb9\xa3\xc3\xb9 \xe1\xbb\x8c\xcc\x80w\xc3\xa0r\xc3\xa0\0" + "O\xe1\xb9\xa3\xc3\xb9 B\xc3\xa9l\xc3\xba\0" + "O\xe1\xb9\xa3\xc3\xb9 \xe1\xbb\x8c\xcc\x80p\xe1\xba\xb9\xcc\x80\0" + "\xe1\xb9\xa2\xe1\xba\xb9\xcc\x81r\xe1\xba\xb9\xcc\x81\0" + "\xc3\x88r\xc3\xa8l\xc3\xa8\0" + "\xe1\xba\xb8r\xe1\xba\xb9\xcc\x80n\xc3\xa0\0" + "\xc3\x8cgb\xc3\xa9\0" + "\xe1\xba\xb8\xcc\x80\x62ibi\0" + "\xc3\x92k\xc3\xba\x64u\0" + "Ag\xe1\xba\xb9m\xe1\xbb\x8d\0" + "\xc3\x92g\xc3\xban\0" + "Owewe\0" + "\xe1\xbb\x8c\xcc\x80w\xc3\xa0r\xc3\xa0\0" + "B\xc3\xa9l\xc3\xba\0" + "\xe1\xbb\x8c\xcc\x80p\xe1\xba\xb9\xcc\x80\0" + "Sontaga\0" + "Mosupalogo\0" + "Labohlano\0" + "Mokibelo\0" + "Mok\0" + "Janaware\0" + "Feberware\0" + "Mat\xc5\xa1he\0" + "Aporele\0" + "Julae\0" + "Agostose\0" + "Setemere\0" + "Oktobore\0" + "Nofemere\0" + "Disemere\0" + "Apo\0" + "Nof\0" + "Sonndeg\0" + "M\xc3\xa9indeg\0" + "D\xc3\xabnschdeg\0" + "M\xc3\xabttwoch\0" + "Donneschdeg\0" + "Freideg\0" + "Samschdeg\0" + "M\xc3\xa9i\0" + "D\xc3\xabn\0" + "M\xc3\xabt\0" + "Don\0" + "Fre\0" + "Sam\0" + "M\xc3\xa4\x65rz\0" + "Abr\xc3\xabll\0" + "Mee\0" + "M\xc3\xa4\x65\0" + "sabaat\0" + "ataasinngorneq\0" + "marlunngorneq\0" + "pingasunngorneq\0" + "sisamanngorneq\0" + "tallimanngorneq\0" + "arfininngorneq\0" + "ata\0" + "pin\0" + "sis\0" + "tal\0" + "arf\0" + "martsi\0" + "aprili\0" + "maji\0" + "augustusi\0" + "septemberi\0" + "oktoberi\0" + "novemberi\0" + "decemberi\0" + "Mb\xe1\xbb\x8ds\xe1\xbb\x8b \xe1\xbb\xa4ka\0" + "M\xe1\xbb\x8dnde\0" + "Tiuzdee\0" + "Wenezdee\0" + "T\xe1\xbb\x8d\xe1\xbb\x8dzdee\0" + "Fra\xe1\xbb\x8b\x64\x65\x65\0" + "Sat\xe1\xbb\x8d\x64\x65\x65\0" + "\xe1\xbb\xa4ka\0" + "M\xe1\xbb\x8dn\0" + "Tiu\0" + "Wen\0" + "T\xe1\xbb\x8d\xe1\xbb\x8d\0" + "Fra\xe1\xbb\x8b\0" + "Jen\xe1\xbb\xa5war\xe1\xbb\x8b\0" + "Febr\xe1\xbb\xa5war\xe1\xbb\x8b\0" + "Maach\xe1\xbb\x8b\0" + "Eprel\0" + "Juun\0" + "Jula\xe1\xbb\x8b\0" + "\xe1\xbb\x8cg\xe1\xbb\x8d\xe1\xbb\x8dst\0" + "\xe1\xbb\x8cktoba\0" + "Jen\0" + "Maa\0" + "Juu\0" + "\xe1\xbb\x8cg\xe1\xbb\x8d\0" + "\xe1\xbb\x8ckt\0" + "Dilbata\0" + "Wiixata\0" + "Qibxata\0" + "Roobii\0" + "Kamiisa\0" + "Jimaata\0" + "Sanbata\0" + "Dil\0" + "Wix\0" + "Qib\0" + "Rob\0" + "Jim\0" + "San\0" + "Amajjii\0" + "Guraandhala\0" + "Bitooteessa\0" + "Elba\0" + "Caamsa\0" + "Waxabajjii\0" + "Adooleessa\0" + "Hagayya\0" + "Fuulbana\0" + "Onkololeessa\0" + "Sadaasa\0" + "Muddee\0" + "Ama\0" + "Gur\0" + "Bit\0" + "Elb\0" + "Cam\0" + "Wax\0" + "Ado\0" + "Hag\0" + "Ful\0" + "Onk\0" + "\xe1\x88\xb0\xe1\x8a\x95\xe1\x89\xa0\xe1\x89\xb5\0" + "\xe1\x88\xb0\xe1\x8a\x91\xe1\x8b\xad\0" + "\xe1\x88\xa0\xe1\x88\x89\xe1\x88\xb5\0" + "\xe1\x8a\x83\xe1\x88\x99\xe1\x88\xb5\0" + "\xe1\x8b\x93\xe1\x88\xad\xe1\x89\xa2\0" + "\xe1\x89\x80\xe1\x8b\xb3\xe1\x88\x9d\0" + "\xe1\x88\xb0\xe1\x8a\x95\0" + "\xe1\x88\xb0\xe1\x8a\x91\0" + "\xe1\x88\xb0\xe1\x88\x89\0" + "\xe1\x88\xa8\xe1\x89\xa1\0" + "\xe1\x88\x93\xe1\x88\x99\0" + "\xe1\x8b\x93\xe1\x88\xad\0" + "\xe1\x89\x80\xe1\x8b\xb3\0" + "\xe1\x88\xa0\0" + "\xe1\x88\x93\0" + "\xe1\x89\x80\0" + "\xe1\x8c\xa5\xe1\x88\xaa\0" + "\xe1\x88\x88\xe1\x8a\xab\xe1\x89\xb2\xe1\x89\xb5\0" + "\xe1\x88\x98\xe1\x8c\x8b\xe1\x89\xa2\xe1\x89\xb5\0" + "\xe1\x88\x9a\xe1\x8b\xab\xe1\x8b\x9d\xe1\x8b\xab\0" + "\xe1\x8c\x8d\xe1\x8a\x95\xe1\x89\xa6\xe1\x89\xb5\0" + "\xe1\x88\xb0\xe1\x8a\x90\0" + "\xe1\x88\x93\xe1\x88\x9d\xe1\x88\x88\0" + "\xe1\x8a\x90\xe1\x88\x93\xe1\x88\xb0\0" + "\xe1\x88\x98\xe1\x88\xb5\xe1\x8a\xa8\xe1\x88\xa8\xe1\x88\x9d\0" + "\xe1\x8c\xa5\xe1\x89\x85\xe1\x88\x9d\xe1\x89\xb2\0" + "\xe1\x88\x95\xe1\x8b\xb3\xe1\x88\xad\0" + "\xe1\x89\xb3\xe1\x88\x95\xe1\x88\xb3\xe1\x88\xb5\0" + "\xe1\x88\x88\xe1\x8a\xab\0" + "\xe1\x88\x98\xe1\x8c\x8b\0" + "\xe1\x88\x9a\xe1\x8b\xab\0" + "\xe1\x8c\x8d\xe1\x8a\x95\0" + "\xe1\x88\x93\xe1\x88\x9d\0" + "\xe1\x8a\x90\xe1\x88\x93\0" + "\xe1\x88\x98\xe1\x88\xb5\0" + "\xe1\x8c\xa5\xe1\x89\x85\0" + "\xe1\x88\x95\xe1\x8b\xb3\0" + "\xe1\x89\xb3\xe1\x88\x95\0" + "L\xc4\x81pule\0" + "Po\xca\xbb\x61kahi\0" + "Po\xca\xbb\x61lua\0" + "Po\xca\xbb\x61kolu\0" + "Po\xca\xbb\x61h\xc4\x81\0" + "Po\xca\xbb\x61lima\0" + "Po\xca\xbb\x61ono\0" + "LP\0" + "P1\0" + "P2\0" + "P3\0" + "P4\0" + "P5\0" + "P6\0" + "Ianuali\0" + "Pepeluali\0" + "Malaki\0" + "\xca\xbb\x41pelila\0" + "Iune\0" + "Iulai\0" + "\xca\xbb\x41ukake\0" + "Kepakemapa\0" + "\xca\xbbOkakopa\0" + "Nowemapa\0" + "Kekemapa\0" + "Ian.\0" + "Pep.\0" + "Mal.\0" + "\xca\xbb\x41p.\0" + "Iun.\0" + "Iul.\0" + "\xca\xbb\x41u.\0" + "Kep.\0" + "\xca\xbbOk.\0" + "Now.\0" + "Kek.\0" + "Axad\0" + "Isniin\0" + "Talaado\0" + "Arbaco\0" + "Khamiis\0" + "Jimco\0" + "Sabti\0" + "Axd\0" + "Arb\0" + "Kh\0" + "Bisha Koobaad\0" + "Bisha Labaad\0" + "Bisha Saddexaad\0" + "Bisha Afraad\0" + "Bisha Shanaad\0" + "Bisha Lixaad\0" + "Bisha Todobaad\0" + "Bisha Sideedaad\0" + "Bisha Sagaalaad\0" + "Bisha Tobnaad\0" + "Bisha Kow iyo Tobnaad\0" + "Bisha Laba iyo Tobnaad\0" + "Kob\0" + "Lab\0" + "Afr\0" + "Sha\0" + "Lix\0" + "Tod\0" + "Sid\0" + "Sag\0" + "Tob\0" + "KIT\0" + "LIT\0" + "\xea\x91\xad\xea\x86\x8f\xea\x91\x8d\0" + "\xea\x86\x8f\xea\x8a\x82\xea\x8b\x8d\0" + "\xea\x86\x8f\xea\x8a\x82\xea\x91\x8d\0" + "\xea\x86\x8f\xea\x8a\x82\xea\x8c\x95\0" + "\xea\x86\x8f\xea\x8a\x82\xea\x87\x96\0" + "\xea\x86\x8f\xea\x8a\x82\xea\x89\xac\0" + "\xea\x86\x8f\xea\x8a\x82\xea\x83\x98\0" + "\xea\x91\xad\xea\x86\x8f\0" + "\xea\x86\x8f\xea\x8b\x8d\0" + "\xea\x86\x8f\xea\x91\x8d\0" + "\xea\x86\x8f\xea\x8c\x95\0" + "\xea\x86\x8f\xea\x87\x96\0" + "\xea\x86\x8f\xea\x89\xac\0" + "\xea\x86\x8f\xea\x83\x98\0" + "\xea\x86\x8f\0" + "\xea\x8b\x8d\0" + "\xea\x91\x8d\0" + "\xea\x8c\x95\0" + "\xea\x87\x96\0" + "\xea\x89\xac\0" + "\xea\x83\x98\0" + "\xea\x8b\x8d\xea\x86\xaa\0" + "\xea\x91\x8d\xea\x86\xaa\0" + "\xea\x8c\x95\xea\x86\xaa\0" + "\xea\x87\x96\xea\x86\xaa\0" + "\xea\x89\xac\xea\x86\xaa\0" + "\xea\x83\x98\xea\x86\xaa\0" + "\xea\x8f\x83\xea\x86\xaa\0" + "\xea\x89\x86\xea\x86\xaa\0" + "\xea\x88\xac\xea\x86\xaa\0" + "\xea\x8a\xb0\xea\x86\xaa\0" + "\xea\x8a\xb0\xea\x8a\xaa\xea\x86\xaa\0" + "\xea\x8a\xb0\xea\x91\x8b\xea\x86\xaa\0" + "Meurzh\0" + "Merc\xca\xbcher\0" + "Yaou\0" + "Gwener\0" + "Sadorn\0" + "Meu.\0" + "Mer.\0" + "Gwe.\0" + "Sad.\0" + "Su\0" + "Mz\0" + "Mc\0" + "Genver\0" + "C\xca\xbchwevrer\0" + "Ebrel\0" + "Mae\0" + "Mezheven\0" + "Gouere\0" + "Eost\0" + "Gwengolo\0" + "Here\0" + "Du\0" + "Kerzu\0" + "Gen.\0" + "C\xca\xbchwe.\0" + "Meur.\0" + "Ebr.\0" + "Mezh.\0" + "Goue.\0" + "Gwen.\0" + "Ker.\0" + "\xd9\x8a\xdb\x95\xd9\x83\xd8\xb4\xdb\x95\xd9\x86\xd8\xa8\xdb\x95\0" + "\xd8\xaf\xdb\x88\xd8\xb4\xdb\x95\xd9\x86\xd8\xa8\xdb\x95\0" + "\xd8\xb3\xdb\x95\xd9\x8a\xd8\xb4\xdb\x95\xd9\x86\xd8\xa8\xdb\x95\0" + "\xda\x86\xd8\xa7\xd8\xb1\xd8\xb4\xdb\x95\xd9\x86\xd8\xa8\xdb\x95\0" + "\xd9\xbe\xdb\x95\xd9\x8a\xd8\xb4\xdb\x95\xd9\x86\xd8\xa8\xdb\x95\0" + "\xd8\xac\xdb\x88\xd9\x85\xdb\x95\0" + "\xd8\xb4\xdb\x95\xd9\x86\xd8\xa8\xdb\x95\0" + "\xd9\x8a\xdb\x95\0" + "\xd8\xaf\xdb\x88\0" + "\xd8\xb3\xdb\x95\0" + "\xda\x86\xd8\xa7\0" + "\xd9\xbe\xdb\x95\0" + "\xd8\xac\xdb\x88\0" + "\xd8\xb4\xdb\x95\0" + "\xd9\x8a\0" + "\xd9\x8a\xd8\xa7\xd9\x86\xdb\x8b\xd8\xa7\xd8\xb1\0" + "\xd9\x81\xdb\x90\xdb\x8b\xd8\xb1\xd8\xa7\xd9\x84\0" + "\xd9\x85\xd8\xa7\xd8\xb1\xd8\xaa\0" + "\xd8\xa6\xd8\xa7\xd9\xbe\xd8\xb1\xdb\x90\xd9\x84\0" + "\xd9\x85\xd8\xa7\xd9\x8a\0" + "\xd8\xa6\xd9\x89\xd9\x8a\xdb\x87\xd9\x86\0" + "\xd8\xa6\xd9\x89\xd9\x8a\xdb\x87\xd9\x84\0" + "\xd8\xa6\xd8\xa7\xdb\x8b\xd8\xba\xdb\x87\xd8\xb3\xd8\xaa\0" + "\xd8\xb3\xdb\x90\xd9\x86\xd8\xaa\xdb\x95\xd8\xa8\xd9\x89\xd8\xb1\0" + "\xd8\xa6\xdb\x86\xd9\x83\xd8\xaa\xdb\x95\xd8\xa8\xd9\x89\xd8\xb1\0" + "\xd9\x86\xd9\x88\xd9\x8a\xd8\xa7\xd8\xa8\xd9\x89\xd8\xb1\0" + "\xd8\xaf\xdb\x90\xd9\x83\xd8\xa7\xd8\xa8\xd9\x89\xd8\xb1\0" + "Sunntig\0" + "M\xc3\xa4\xc3\xa4ntig\0" + "Ziischtig\0" + "Mittwuch\0" + "Dunschtig\0" + "Friitig\0" + "Samschtig\0" + "Su.\0" + "M\xc3\xa4.\0" + "Zi.\0" + "Mi.\0" + "Du.\0" + "Fr.\0" + "Auguscht\0" + "Sept\xc3\xa4mber\0" + "Oktoober\0" + "Nov\xc3\xa4mber\0" + "Dez\xc3\xa4mber\0" + "\xd0\xb1\xd0\xb0\xd1\x81\xd0\xba\xd1\x8b\xd2\xbb\xd1\x8b\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8c\xd0\xb0\0" + "\xd0\xb1\xd1\x8d\xd0\xbd\xd0\xb8\xd0\xb4\xd0\xb8\xd1\x8d\xd0\xbd\xd0\xbd\xd1\x8c\xd0\xb8\xd0\xba\0" + "\xd0\xbe\xd0\xbf\xd1\x82\xd1\x83\xd0\xbe\xd1\x80\xd1\x83\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x83\xd0\xba\0" + "\xd1\x81\xd1\x8d\xd1\x80\xd1\x8d\xd0\xb4\xd1\x8d\0" + "\xd1\x87\xd1\x8d\xd0\xbf\xd0\xbf\xd0\xb8\xd1\x8d\xd1\x80\0" + "\xd0\x91\xd1\x8d\xd1\x8d\xd1\x82\xd0\xb8\xd2\xa5\xd1\x81\xd1\x8d\0" + "\xd1\x81\xd1\x83\xd0\xb1\xd1\x83\xd0\xbe\xd1\x82\xd0\xb0\0" + "\xd0\xb1\xd1\x81\0" + "\xd0\xb1\xd0\xbd\0" + "\xd0\xbe\xd0\xbf\0" + "\xd1\x81\xd1\x8d\0" + "\xd1\x87\xd0\xbf\0" + "\xd0\xb1\xd1\x8d\0" + "\xd0\x9e\0" + "\xd1\x82\xd0\xbe\xd1\x85\xd1\x81\xd1\x83\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x83\0" + "\xd0\xbe\xd0\xbb\xd1\x83\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x83\0" + "\xd0\xba\xd1\x83\xd0\xbb\xd1\x83\xd0\xbd \xd1\x82\xd1\x83\xd1\x82\xd0\xb0\xd1\x80\0" + "\xd0\xbc\xd1\x83\xd1\x83\xd1\x81 \xd1\x83\xd1\x81\xd1\x82\xd0\xb0\xd1\x80\0" + "\xd1\x8b\xd0\xb0\xd0\xbc \xd1\x8b\xd0\xb9\xd0\xb0\0" + "\xd0\xb1\xd1\x8d\xd1\x81 \xd1\x8b\xd0\xb9\xd0\xb0\0" + "\xd0\xbe\xd1\x82 \xd1\x8b\xd0\xb9\xd0\xb0\0" + "\xd0\xb0\xd1\x82\xd1\x8b\xd1\x80\xd0\xb4\xd1\x8c\xd1\x8b\xd1\x85 \xd1\x8b\xd0\xb9\xd0\xb0\0" + "\xd0\xb1\xd0\xb0\xd0\xbb\xd0\xb0\xd2\x95\xd0\xb0\xd0\xbd \xd1\x8b\xd0\xb9\xd0\xb0\0" + "\xd0\xb0\xd0\xbb\xd1\x82\xd1\x8b\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x8b\0" + "\xd1\x81\xd1\x8d\xd1\x82\xd0\xb8\xd0\xbd\xd0\xbd\xd1\x8c\xd0\xb8\0" + "\xd0\xb0\xd1\x85\xd1\x81\xd1\x8b\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x8b\0" + "\xd0\xa2\xd0\xbe\xd1\x85\xd1\x81\xd1\x83\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x83\0" + "\xd0\x9e\xd0\xbb\xd1\x83\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x83\0" + "\xd0\x9a\xd1\x83\xd0\xbb\xd1\x83\xd0\xbd \xd1\x82\xd1\x83\xd1\x82\xd0\xb0\xd1\x80\0" + "\xd0\x9c\xd1\x83\xd1\x83\xd1\x81 \xd1\x83\xd1\x81\xd1\x82\xd0\xb0\xd1\x80\0" + "\xd0\xab\xd0\xb0\xd0\xbc \xd1\x8b\xd0\xb9\xd1\x8b\xd0\xbd\0" + "\xd0\x91\xd1\x8d\xd1\x81 \xd1\x8b\xd0\xb9\xd1\x8b\xd0\xbd\0" + "\xd0\x9e\xd1\x82 \xd1\x8b\xd0\xb9\xd1\x8b\xd0\xbd\0" + "\xd0\x90\xd1\x82\xd1\x8b\xd1\x80\xd0\xb4\xd1\x8c\xd1\x8b\xd1\x85 \xd1\x8b\xd0\xb9\xd1\x8b\xd0\xbd\0" + "\xd0\x91\xd0\xb0\xd0\xbb\xd0\xb0\xd2\x95\xd0\xb0\xd0\xbd \xd1\x8b\xd0\xb9\xd1\x8b\xd0\xbd\0" + "\xd0\x90\xd0\xbb\xd1\x82\xd1\x8b\xd0\xbd\xd0\xbd\xd1\x8c\xd1\x8b\0" + "\xd0\xa1\xd1\x8d\xd1\x82\xd0\xb8\xd0\xbd\xd0\xbd\xd1\x8c\xd0\xb8\0" + "\xd0\xa2\xd0\xbe\xd1\x85\xd1\x81\0" + "\xd0\x9e\xd0\xbb\xd1\x83\xd0\xbd\0" + "\xd0\x9a\xd0\xbb\xd0\xbd\0" + "\xd0\x9c\xd1\x81\xd1\x83\0" + "\xd0\xab\xd0\xb0\xd0\xbc\0" + "\xd0\x91\xd1\x8d\xd1\x81\0" + "\xd0\x9e\xd1\x82\xd0\xb9\0" + "\xd0\x90\xd1\x82\xd1\x80\0" + "\xd0\x91\xd0\xbb\xd2\x95\0" + "\xd0\x90\xd0\xbb\xd1\x82\0" + "\xd0\xa1\xd1\x8d\xd1\x82\0" + "\xd0\x90\xd1\x85\xd1\x81\0" + "Ku cyumweru\0" + "Kuwa mbere\0" + "Kuwa kabiri\0" + "Kuwa gatatu\0" + "Kuwa kane\0" + "Kuwa gatanu\0" + "Kuwa gatandatu\0" + "cyu.\0" + "mbe.\0" + "kab.\0" + "gtu.\0" + "kan.\0" + "gnu.\0" + "gnd.\0" + "Mutarama\0" + "Gashyantare\0" + "Werurwe\0" + "Mata\0" + "Gicuransi\0" + "Kamena\0" + "Nyakanga\0" + "Kanama\0" + "Nzeli\0" + "Ukwakira\0" + "Ugushyingo\0" + "Ukuboza\0" + "mut.\0" + "gas.\0" + "wer.\0" + "mat.\0" + "gic.\0" + "kam.\0" + "nya.\0" + "nze.\0" + "ukw.\0" + "ugu.\0" + "uku.\0" + "DiD\xc3\xb2mhnaich\0" + "DiLuain\0" + "DiM\xc3\xa0irt\0" + "DiCiadain\0" + "DiarDaoin\0" + "DihAoine\0" + "DiSathairne\0" + "DiD\0" + "DiL\0" + "DiM\0" + "DiC\0" + "Dia\0" + "Dih\0" + "DiS\0" + "Am Faoilleach\0" + "An Gearran\0" + "Am M\xc3\xa0rt\0" + "An Giblean\0" + "An C\xc3\xa8itean\0" + "An t-\xc3\x92gmhios\0" + "An t-Iuchar\0" + "An L\xc3\xb9nastal\0" + "An t-Sultain\0" + "An D\xc3\xa0mhair\0" + "An t-Samhain\0" + "An D\xc3\xb9\x62hlachd\0" + "dhen Fhaoilleach\0" + "dhen Ghearran\0" + "dhen Mh\xc3\xa0rt\0" + "dhen Ghiblean\0" + "dhen Ch\xc3\xa8itean\0" + "dhen \xc3\x92gmhios\0" + "dhen Iuchar\0" + "dhen L\xc3\xb9nastal\0" + "dhen t-Sultain\0" + "dhen D\xc3\xa0mhair\0" + "dhen t-Samhain\0" + "dhen D\xc3\xb9\x62hlachd\0" + "Faoi\0" + "Gearr\0" + "M\xc3\xa0rt\0" + "Gibl\0" + "C\xc3\xa8it\0" + "\xc3\x92gmh\0" + "Iuch\0" + "L\xc3\xb9na\0" + "Sult\0" + "D\xc3\xa0mh\0" + "D\xc3\xb9\x62h\0" + "\xe9\x80\xb1\xe6\x97\xa5\0" + "\xe9\x80\xb1\xe4\xb8\x80\0" + "\xe9\x80\xb1\xe4\xba\x8c\0" + "\xe9\x80\xb1\xe4\xb8\x89\0" + "\xe9\x80\xb1\xe5\x9b\x9b\0" + "\xe9\x80\xb1\xe4\xba\x94\0" + "\xe9\x80\xb1\xe5\x85\xad\0" + "\xd8\xa7\xd9\x84\xd8\xa3\xd8\xad\xd8\xaf\0" + "\xd8\xa7\xd9\x84\xd8\xa7\xd8\xab\xd9\x86\xd9\x8a\xd9\x86\0" + "\xd8\xa7\xd9\x84\xd8\xab\xd9\x84\xd8\xa7\xd8\xab\xd8\xa7\xd8\xa1\0" + "\xd8\xa7\xd9\x84\xd8\xa3\xd8\xb1\xd8\xa8\xd8\xb9\xd8\xa7\xd8\xa1\0" + "\xd8\xa7\xd9\x84\xd8\xae\xd9\x85\xd9\x8a\xd8\xb3\0" + "\xd8\xa7\xd9\x84\xd8\xac\xd9\x85\xd8\xb9\xd8\xa9\0" + "\xd8\xa7\xd9\x84\xd8\xb3\xd8\xa8\xd8\xaa\0" + "\xd8\xad\0" + "\xd9\x86\0" + "\xd8\xab\0" + "\xd8\xb1\0" + "\xd8\xae\0" + "\xd9\x83\xd8\xa7\xd9\x86\xd9\x88\xd9\x86 \xd8\xa7\xd9\x84\xd8\xab\xd8\xa7\xd9\x86\xd9\x8a\0" + "\xd8\xb4\xd8\xa8\xd8\xa7\xd8\xb7\0" + "\xd8\xa2\xd8\xb0\xd8\xa7\xd8\xb1\0" + "\xd9\x86\xd9\x8a\xd8\xb3\xd8\xa7\xd9\x86\0" + "\xd8\xa3\xd9\x8a\xd8\xa7\xd8\xb1\0" + "\xd8\xad\xd8\xb2\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0" + "\xd8\xaa\xd9\x85\xd9\x88\xd8\xb2\0" + "\xd8\xa2\xd8\xa8\0" + "\xd8\xa3\xd9\x8a\xd9\x84\xd9\x88\xd9\x84\0" + "\xd8\xaa\xd8\xb4\xd8\xb1\xd9\x8a\xd9\x86 \xd8\xa7\xd9\x84\xd8\xa3\xd9\x88\xd9\x84\0" + "\xd8\xaa\xd8\xb4\xd8\xb1\xd9\x8a\xd9\x86 \xd8\xa7\xd9\x84\xd8\xab\xd8\xa7\xd9\x86\xd9\x8a\0" + "\xd9\x83\xd8\xa7\xd9\x86\xd9\x88\xd9\x86 \xd8\xa7\xd9\x84\xd8\xa3\xd9\x88\xd9\x84\0" + "ene\0" + "oct\0" + "tysdag\0" + "laurdag\0" + "tys\0" + "lau\0" + "segunda\0" + "ter\xc3\xa7\x61\0" + "quarta\0" + "quinta\0" + "sexta\0" + "Dum\0" + "Mie\0" + "Joi\0" + "Vin\0" + "S\xc3\xa2m\0" + "Ma\0" + "\xd9\xbe\xdb\x8c\xd8\xb1\0" + "\xd0\xb1\xd0\xb0\xd0\xb7\xd0\xb0\xd1\x80\0" + "\xd0\xb1\xd0\xb0\xd0\xb7\xd0\xb0\xd1\x80 \xd0\xb5\xd1\x80\xd1\x82\xd3\x99\xd1\x81\xd0\xb8\0" + "\xd1\x87\xd3\x99\xd1\x80\xd1\x88\xd3\x99\xd0\xbd\xd0\xb1\xd3\x99 \xd0\xb0\xd1\x85\xd1\x88\xd0\xb0\xd0\xbc\xd1\x8b\0" + "\xd1\x87\xd3\x99\xd1\x80\xd1\x88\xd3\x99\xd0\xbd\xd0\xb1\xd3\x99\0" + "\xd2\xb9\xd2\xaf\xd0\xbc\xd3\x99 \xd0\xb0\xd1\x85\xd1\x88\xd0\xb0\xd0\xbc\xd1\x8b\0" + "\xd2\xb9\xd2\xaf\xd0\xbc\xd3\x99\0" + "\xd1\x88\xd3\x99\xd0\xbd\xd0\xb1\xd3\x99\0" + "\xd0\x91.\0" + "\xd0\x91.\xd0\x95.\0" + "\xd0\xa7.\xd0\x90.\0" + "\xd0\xa7.\0" + "\xd2\xb8.\xd0\x90.\0" + "\xd2\xb8.\0" + "\xd0\xa8.\0" + "\xd0\x88\xd0\xb0\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\0" + "\xd0\x98\xd1\x98\xd1\x83\xd0\xbd\0" + "\xd0\x98\xd1\x98\xd1\x83\xd0\xbb\0" + "\xd0\xa1\xd0\xb5\xd0\xbd\xd1\x82\xd1\x98\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd0\x9e\xd0\xba\xd1\x82\xd1\x98\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd0\x9d\xd0\xbe\xd1\x98\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd1\x98\xd0\xb0\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\0" + "\xd1\x84\xd0\xb5\xd0\xb2\xd1\x80\xd0\xb0\xd0\xbb\0" + "\xd0\xb0\xd0\xbf\xd1\x80\xd0\xb5\xd0\xbb\0" + "\xd0\xb8\xd1\x98\xd1\x83\xd0\xbd\0" + "\xd0\xb8\xd1\x98\xd1\x83\xd0\xbb\0" + "\xd1\x81\xd0\xb5\xd0\xbd\xd1\x82\xd1\x98\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd0\xbe\xd0\xba\xd1\x82\xd1\x98\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd0\xbd\xd0\xbe\xd1\x98\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb0\xd0\xb1\xd1\x80\0" + "\xd1\x98\xd0\xb0\xd0\xbd\0" + "\xd0\xbc\xd0\xb0\xd1\x80\0" + "\xd0\xb8\xd1\x98\xd0\xbd\0" + "\xd0\xb8\xd1\x98\xd0\xbb\0" + "\xd1\x81\xd0\xb5\xd0\xbd\0" + "\xd0\xbd\xd0\xbe\xd1\x98\0" + "nje\xc5\xba\x65la\0" + "p\xc3\xb3nje\xc5\xba\x65le\0" + "wa\xc5\x82tora\0" + "srjoda\0" + "stw\xc3\xb3rtk\0" + "p\xc4\x9btk\0" + "wa\xc5\x82\0" + "stw\0" + "p\xc4\x9bt\0" + "\xd1\x8f\xd0\xba\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb0\0" + "\xd0\xb4\xd1\x83\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb0\0" + "\xd1\x81\xd0\xb5\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb0\0" + "\xd1\x87\xd0\xbe\xd1\x80\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb0\0" + "\xd0\xbf\xd0\xb0\xd0\xb9\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb0\0" + "\xd1\x88\xd0\xb0\xd0\xbd\xd0\xb1\xd0\xb0\0" + "\xd0\xaf\xd0\xba\xd1\x88\0" + "\xd0\x94\xd1\x83\xd1\x88\0" + "\xd0\xa1\xd0\xb5\xd1\x88\0" + "\xd0\xa7\xd0\xbe\xd1\x80\0" + "\xd0\x9f\xd0\xb0\xd0\xb9\0" + "\xd0\x96\xd1\x83\xd0\xbc\0" + "\xd0\xa8\xd0\xb0\xd0\xbd\0" + "\xd0\xaf\0" + "\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\0" + "\xd0\xb8\xd1\x8e\xd0\xbd\0" + "\xd0\xb8\xd1\x8e\xd0\xbb\0" + "\xd1\x81\xd0\xb5\xd0\xbd\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\0" + "\xd0\xbe\xd0\xba\xd1\x82\xd1\x8f\xd0\xb1\xd1\x80\0" + "\xd0\xbd\xd0\xbe\xd1\x8f\xd0\xb1\xd1\x80\0" + "\xd8\xa8\xd9\x8f\xd8\xaf\xda\xbe\0" + "\xd9\x85\xd8\xa6\0" + "\xd9\x8a\xd9\x86\xd8\xa7\xd9\x8a\xd8\xb1\0" + "\xd9\x81\xd8\xa8\xd8\xb1\xd8\xa7\xd9\x8a\xd8\xb1\0" + "\xd8\xa3\xd8\xa8\xd8\xb1\xd9\x8a\xd9\x84\0" + "\xd9\x85\xd8\xa7\xd9\x8a\xd9\x88\0" + "\xd9\x8a\xd9\x88\xd9\x86\xd9\x8a\xd9\x88\0" + "\xd9\x8a\xd9\x88\xd9\x84\xd9\x8a\xd9\x88\0" + "\xd8\xa3\xd8\xba\xd8\xb3\xd8\xb7\xd8\xb3\0" + "\xd8\xb3\xd8\xa8\xd8\xaa\xd9\x85\xd8\xa8\xd8\xb1\0" + "\xd8\xa3\xd9\x83\xd8\xaa\xd9\x88\xd8\xa8\xd8\xb1\0" + "\xd9\x86\xd9\x88\xd9\x81\xd9\x85\xd8\xa8\xd8\xb1\0" + "\xd8\xaf\xd9\x8a\xd8\xb3\xd9\x85\xd8\xa8\xd8\xb1\0" + "J\xc3\xa4nner\0" + "J\xc3\xa4n\0" + "Sun.\0" + "Mon.\0" + "Tue.\0" + "Wed.\0" + "Thu.\0" + "Fri.\0" + "Sat.\0" + "M.\0" + "Tu.\0" + "W.\0" + "Th.\0" + "F.\0" + "Oct.\0" + "juill.\0" + "vuoss\xc3\xa1rgga\0" + "ma\xc5\x8b\xc5\x8b\x65\x62\xc3\xa1rgga\0" + "gaskavahku\0" + "duorastaga\0" + "bearjadaga\0" + "l\xc3\xa1vvardaga\0" + "U\0" + "\xd8\xac\xd8\xa7\xd9\x86\xd9\x81\xd9\x8a\0" + "\xd9\x81\xd9\x8a\xd9\x81\xd8\xb1\xd9\x8a\0" + "\xd8\xa3\xd9\x81\xd8\xb1\xd9\x8a\xd9\x84\0" + "\xd8\xac\xd9\x88\xd8\xa7\xd9\x86\0" + "\xd8\xac\xd9\x88\xd9\x8a\xd9\x84\xd9\x8a\xd8\xa9\0" + "\xd8\xa3\xd9\x88\xd8\xaa\0" + "septembar\0" + "oktobar\0" + "novembar\0" + "decembar\0" + "avg\0" + "\xd9\x8a\xd9\x88\xd9\x84\xd9\x8a\xd9\x88\xd8\xb2\0" + "\xd8\xba\xd8\xb4\xd8\xaa\0" + "\xd8\xb4\xd8\xaa\xd9\x86\xd8\xa8\xd8\xb1\0" + "\xd9\x86\xd9\x88\xd9\x86\xd8\xa8\xd8\xb1\0" + "\xd8\xaf\xd8\xac\xd9\x86\xd8\xa8\xd8\xb1\0" + "ponedeljak\0" + "ut.\0" + "sr.\0" + "sub.\0" + "\xd0\xbd\xd0\xb5\xd0\xb4\xd1\x98\xd0\xb5\xd1\x99\xd0\xb0\0" + "\xd0\xbf\xd0\xbe\xd0\xbd\xd0\xb5\xd0\xb4\xd0\xb5\xd1\x99\xd0\xb0\xd0\xba\0" + "\xd1\x83\xd1\x82\xd0\xbe\xd1\x80\xd0\xb0\xd0\xba\0" + "\xd1\x81\xd1\x80\xd0\xb8\xd1\x98\xd0\xb5\xd0\xb4\xd0\xb0\0" + "\xd1\x87\xd0\xb5\xd1\x82\xd0\xb2\xd1\x80\xd1\x82\xd0\xb0\xd0\xba\0" + "\xd0\xbf\xd0\xb5\xd1\x82\xd0\xb0\xd0\xba\0" + "\xd1\x83\xd1\x82.\0" + "\xd1\x81\xd1\x80.\0" + "\xd1\x81\xd1\x83\xd0\xb1.\0" + "\xd1\x83\0" + "\xd1\x98\xd0\xb0\xd0\xbd\xd1\x83\xd0\xb0\xd1\x80\0" + "\xd1\x84\xd0\xb5\xd0\xb1\xd1\x80\xd1\x83\xd0\xb0\xd1\x80\0" + "\xd1\x98\xd1\x83\xd0\xbd\0" + "\xd1\x98\xd1\x83\xd0\xbb\0" + "\xd1\x81\xd0\xb5\xd0\xbf\xd1\x82\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb0\xd1\x80\0" + "\xd0\xbe\xd0\xba\xd1\x82\xd0\xbe\xd0\xb1\xd0\xb0\xd1\x80\0" + "\xd0\xbd\xd0\xbe\xd0\xb2\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb0\xd1\x80\0" + "\xd0\xb4\xd0\xb5\xd1\x86\xd0\xb5\xd0\xbc\xd0\xb1\xd0\xb0\xd1\x80\0" + "\xd1\x84\xd0\xb5\xd0\xb1.\0" + "\xd0\xbd\xd0\xbe\xd0\xb2.\0" + "\xd0\xb4\xd0\xb5\xd1\x86.\0" + "\xd0\xbd\xd0\xb5\xd0\xb4\xd0\xb5\xd1\x99\xd0\xb0\0" + "\xd0\xbd\xd0\xb5\xd0\xb4\0" + "\xd0\xbf\xd0\xbe\xd0\xbd\0" + "\xd1\x83\xd1\x82\xd0\xbe\0" + "\xd1\x81\xd1\x80\xd0\xb8\0" + "\xd1\x87\xd0\xb5\xd1\x82\0" + "\xd0\xbf\xd0\xb5\xd1\x82\0" + "\xd1\x81\xd1\x83\xd0\xb1\0" + "\xd1\x84\xd0\xb5\xd0\xb1\0" + "\xd0\xbd\xd0\xbe\xd0\xb2\0" + "\xd0\xb4\xd0\xb5\xd1\x86\0" + "l\0" + "j\0" + "v\0" + "sre\0" + "pasepeeivi\0" + "vuossaarg\xc3\xa2\0" + "majebaarg\xc3\xa2\0" + "koskoho\0" + "tuor\xc3\xa2stuv\0" + "v\xc3\xa1stuppeeivi\0" + "l\xc3\xa1vurduv\0" + "pas\0" + "vuo\0" + "kos\0" + "tuo\0" + "v\xc3\xa1s\0" + "u\xc4\x91\xc4\x91\xc3\xa2ivem\xc3\xa1\xc3\xa1nu\0" + "kuov\xc3\xa2m\xc3\xa1\xc3\xa1nu\0" + "njuh\xc4\x8d\xc3\xa2m\xc3\xa1\xc3\xa1nu\0" + "cu\xc3\xa1\xc5\x8buim\xc3\xa1\xc3\xa1nu\0" + "vyesim\xc3\xa1\xc3\xa1nu\0" + "kesim\xc3\xa1\xc3\xa1nu\0" + "syeinim\xc3\xa1\xc3\xa1nu\0" + "porgem\xc3\xa1\xc3\xa1nu\0" + "\xc4\x8doh\xc4\x8d\xc3\xa2m\xc3\xa1\xc3\xa1nu\0" + "roovv\xc3\xa2\x64m\xc3\xa1\xc3\xa1nu\0" + "skamm\xc3\xa2m\xc3\xa1\xc3\xa1nu\0" + "juovl\xc3\xa2m\xc3\xa1\xc3\xa1nu\0" + "u\xc4\x91iv\0" + "kuov\xc3\xa2\0" + "njuh\xc4\x8d\xc3\xa2\0" + "cu\xc3\xa1\xc5\x8bui\0" + "vyesi\0" + "kesi\0" + "syeini\0" + "porge\0" + "\xc4\x8doh\xc4\x8d\xc3\xa2\0" + "roovv\xc3\xa2\x64\0" + "skamm\xc3\xa2\0" + "juovl\xc3\xa2\0" + "Febrero\0" + "Junio\0" + "Julio\0" + "Setiembre\0" + "Octubre\0" + "Noviembre\0" + "Diciembre\0" + "setiembre\0" + "Ene.\0" + "May.\0" + "Dic.\0" + "\xd1\x81\xd1\x80\xd0\xb5\0" + "f\xc3\xa9v.\0" + "jui.\0" + "\xd8\xa7\xd9\x84\xd8\xaa\xd9\x82\xd9\x88\xd9\x8a\xd9\x85 \xd8\xa7\xd9\x84\xd9\x87\xd8\xac\xd8\xb1\xd9\x8a\0" + "\xd0\xb3\xd1\x80\xd0\xb8\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb0\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8 \xd0\xba\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb4\xd0\xb0\xd1\x80\0" + "calendari gregori\xc3\xa0\0" + "\xe5\x85\xac\xe5\x8e\x86\0" + "Gregori\xc3\xa1nsk\xc3\xbd kalend\xc3\xa1\xc5\x99\0" + "gregoriansk kalender\0" + "Gregorianischer Kalender\0" + "\xce\x93\xcf\x81\xce\xb7\xce\xb3\xce\xbf\xcf\x81\xce\xb9\xce\xb1\xce\xbd\xcf\x8c \xce\xb7\xce\xbc\xce\xb5\xcf\x81\xce\xbf\xce\xbb\xcf\x8c\xce\xb3\xce\xb9\xce\xbf\0" + "Gregorian Calendar\0" + "calendario gregoriano\0" + "gregoriaaninen kalenteri\0" + "calendrier gr\xc3\xa9gorien\0" + "\xd7\x9c\xd7\x95\xd7\x97 \xd7\x94\xd7\xa9\xd7\xa0\xd7\x94 \xd7\x94\xd7\x92\xd7\xa8\xd7\x92\xd7\x95\xd7\xa8\xd7\x99\xd7\x90\xd7\xa0\xd7\x99\0" + "Gergely-napt\xc3\xa1r\0" + "Gregor\xc3\xadskt dagatal\0" + "Calendario gregoriano\0" + "\xe8\xa5\xbf\xe6\x9a\xa6(\xe3\x82\xb0\xe3\x83\xac\xe3\x82\xb4\xe3\x83\xaa\xe3\x82\xaa\xe6\x9a\xa6)\0" + "\xec\x96\x91\xeb\xa0\xa5\0" + "Gregoriaanse kalender\0" + "kalendarz gregoria\xc5\x84ski\0" + "Calend\xc3\xa1rio Gregoriano\0" + "chalender gregorian\0" + "calendar gregorian\0" + "\xd0\xb3\xd1\x80\xd0\xb8\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb0\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9 \xd0\xba\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb4\xd0\xb0\xd1\x80\xd1\x8c\0" + "gregorijanski kalendar\0" + "gregori\xc3\xa1nsky kalend\xc3\xa1r\0" + "kalendar gregorian\0" + "\xe0\xb8\x9b\xe0\xb8\x8f\xe0\xb8\xb4\xe0\xb8\x97\xe0\xb8\xb4\xe0\xb8\x99\xe0\xb8\x9e\xe0\xb8\xb8\xe0\xb8\x97\xe0\xb8\x98\0" + "Miladi Takvim\0" + "\xd8\xac\xd8\xa7\xd8\xb1\xd8\xac\xdb\x8c\xd8\xa7\xd8\xa6\xdb\x8c \xda\xa9\xdb\x8c\xd9\x84\xd9\x86\xda\x88\xd8\xb1\0" + "Kalender Gregorian\0" + "\xd0\xb3\xd1\x80\xd0\xb8\xd0\xb3\xd0\xbe\xd1\x80\xd1\x96\xd0\xb0\xd0\xbd\xd1\x81\xd1\x8c\xd0\xba\xd0\xb8\xd0\xb9 \xd0\xba\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb4\xd0\xb0\xd1\x80\0" + "\xd0\xb3\xd1\x80\xd1\x8b\xd0\xb3\xd0\xb0\xd1\x80\xd1\x8b\xd1\x8f\xd0\xbd\xd1\x81\xd0\xba\xd1\x96 \xd0\xba\xd0\xb0\xd0\xbb\xd1\x8f\xd0\xbd\xd0\xb4\xd0\xb0\xd1\x80\0" + "gregorijanski koledar\0" + "Gregoriuse kalender\0" + "Gregora kalend\xc4\x81rs\0" + "Grigaliaus kalendorius\0" + "\xd8\xaa\xd9\x82\xd9\x88\xdb\x8c\xd9\x85 \xd9\x85\xdb\x8c\xd9\x84\xd8\xa7\xd8\xaf\xdb\x8c\0" + "L\xe1\xbb\x8b\x63h Gregory\0" + "\xd5\xa3\xd6\x80\xd5\xab\xd5\xa3\xd5\xb8\xd6\x80\xd5\xb5\xd5\xa1\xd5\xb6 \xd5\xbf\xd5\xb8\xd5\xb4\xd5\xa1\xd6\x80\0" + "Qreqorian T\xc9\x99qvimi\0" + "Egutegi gregoriarra\0" + "gregorianska protyka\0" + "\xd0\x93\xd1\x80\xd0\xb5\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd1\x98\xd0\xb0\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8 \xd0\xba\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb4\xd0\xb0\xd1\x80\0" + "ikhalenda lesi-Gregorian\0" + "Gregoriese kalender\0" + "\xe1\x83\x92\xe1\x83\xa0\xe1\x83\x98\xe1\x83\x92\xe1\x83\x9d\xe1\x83\xa0\xe1\x83\x98\xe1\x83\x90\xe1\x83\x9c\xe1\x83\xa3\xe1\x83\x9a\xe1\x83\x98 \xe1\x83\x99\xe1\x83\x90\xe1\x83\x9a\xe1\x83\x94\xe1\x83\x9c\xe1\x83\x93\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x98\0" + "gregorianskur kalendari\0" + "\xe0\xa4\x97\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x87\xe0\xa4\x97\xe0\xa5\x8b\xe0\xa4\xb0\xe0\xa4\xbf\xe0\xa4\xaf\xe0\xa4\xa8 \xe0\xa4\x95\xe0\xa5\x88\xe0\xa4\xb2\xe0\xa5\x87\xe0\xa4\x82\xe0\xa4\xa1\xe0\xa4\xb0\0" + "Kalendarju Gregorjan\0" + "gregoria kaleander\0" + "F\xc3\xa9ilire Ghr\xc3\xa9\x61g\xc3\xb3ra\0" + "Kalendar Gregory\0" + "\xd0\x93\xd1\x80\xd0\xb5\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb0\xd0\xbd\xd0\xb4\xd1\x8b\xd2\x9b \xd0\xba\xd2\xaf\xd0\xbd\xd1\x82\xd1\x96\xd0\xb7\xd0\xb1\xd0\xb5\0" + "\xd0\x93\xd1\x80\xd0\xb8\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb0\xd0\xbd \xd0\xb6\xd1\x8b\xd0\xbb\xd0\xbd\xd0\xb0\xd0\xb0\xd0\xbc\xd0\xb0\xd1\x81\xd1\x8b\0" + "Kalenda ya Kigregori\0" + "Gregor\xc3\xbd\x61n senenamasy\0" + "grigorian taqvimi\0" + "\xe0\xa6\x97\xe0\xa7\x8d\xe0\xa6\xb0\xe0\xa6\xbf\xe0\xa6\x97\xe0\xa7\x8b\xe0\xa6\xb0\xe0\xa6\xbf\xe0\xa6\xaf\xe0\xa6\xbc\xe0\xa6\xbe\xe0\xa6\xa8 \xe0\xa6\x95\xe0\xa7\x8d\xe0\xa6\xaf\xe0\xa6\xbe\xe0\xa6\xb2\xe0\xa7\x87\xe0\xa6\xa8\xe0\xa7\x8d\xe0\xa6\xa1\xe0\xa6\xbe\xe0\xa6\xb0\0" + "\xe0\xa8\x97\xe0\xa8\xb0\xe0\xa9\x87\xe0\xa8\x97\xe0\xa9\x8b\xe0\xa8\xb0\xe0\xa9\x80\xe0\xa8\x85\xe0\xa8\xa8 \xe0\xa8\x95\xe0\xa9\x88\xe0\xa8\xb2\xe0\xa9\xb0\xe0\xa8\xa1\xe0\xa8\xb0\0" + "\xe0\xaa\x97\xe0\xab\x8d\xe0\xaa\xb0\xe0\xab\x87\xe0\xaa\x97\xe0\xab\x8b\xe0\xaa\xb0\xe0\xaa\xbf\xe0\xaa\x85\xe0\xaa\xa8 \xe0\xaa\x95\xe0\xab\x87\xe0\xaa\xb2\xe0\xab\x87\xe0\xaa\xa8\xe0\xab\x8d\xe0\xaa\xa1\xe0\xaa\xb0\0" + "\xe0\xae\x95\xe0\xae\xbf\xe0\xae\xb0\xe0\xae\xbf\xe0\xae\x95\xe0\xaf\x8b\xe0\xae\xb0\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xa9\xe0\xaf\x8d \xe0\xae\xa8\xe0\xae\xbe\xe0\xae\xb3\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xbe\xe0\xae\x9f\xe0\xaf\x8d\xe0\xae\x9f\xe0\xae\xbf\0" + "\xe0\xb0\x97\xe0\xb1\x8d\xe0\xb0\xb0\xe0\xb1\x87\xe0\xb0\x97\xe0\xb1\x8b\xe0\xb0\xb0\xe0\xb0\xbf\xe0\xb0\xaf\xe0\xb0\xa8\xe0\xb1\x8d \xe0\xb0\x95\xe0\xb1\x8d\xe0\xb0\xaf\xe0\xb0\xbe\xe0\xb0\xb2\xe0\xb1\x86\xe0\xb0\x82\xe0\xb0\xa1\xe0\xb0\xb0\xe0\xb1\x8d\0" + "\xe0\xb2\x97\xe0\xb3\x8d\xe0\xb2\xb0\xe0\xb3\x86\xe0\xb2\x97\xe0\xb3\x8b\xe0\xb2\xb0\xe0\xb2\xbf\xe0\xb2\xaf\xe0\xb2\xa8\xe0\xb3\x8d \xe0\xb2\x95\xe0\xb3\x8d\xe0\xb2\xaf\xe0\xb2\xbe\xe0\xb2\xb2\xe0\xb3\x86\xe0\xb2\x82\xe0\xb2\xa1\xe0\xb2\xb0\xe0\xb3\x8d\0" + "\xe0\xb4\x87\xe0\xb4\x82\xe0\xb4\x97\xe0\xb5\x8d\xe0\xb4\xb2\xe0\xb5\x80\xe0\xb4\xb7\xe0\xb5\x8d \xe0\xb4\x95\xe0\xb4\xb2\xe0\xb4\xa3\xe0\xb5\x8d\xe0\xb4\x9f\xe0\xb5\xbc\0" + "\xe0\xa6\x97\xe0\xa7\x8d\xe0\xa7\xb0\xe0\xa6\xbf\xe0\xa6\x97\xe0\xa7\x8b\xe0\xa7\xb0\xe0\xa7\x80\xe0\xa6\xaf\xe0\xa6\xbc \xe0\xa6\xaa\xe0\xa6\x9e\xe0\xa7\x8d\xe0\xa6\x9c\xe0\xa6\xbf\xe0\xa6\x95\xe0\xa6\xbe\0" + "\xe0\xa4\x97\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x87\xe0\xa4\x97\xe0\xa5\x8b\xe0\xa4\xb0\xe0\xa4\xbf\xe0\xa4\xaf\xe0\xa4\xa8 \xe0\xa4\xa6\xe0\xa4\xbf\xe0\xa4\xa8\xe0\xa4\xa6\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\xb6\xe0\xa4\xbf\xe0\xa4\x95\xe0\xa4\xbe\0" + "\xd0\xb3\xd1\x80\xd0\xb5\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb9\xd0\xbd \xd1\x85\xd1\x83\xd0\xb0\xd0\xbd\xd0\xbb\xd0\xb8\0" + "Calendr Gregori\0" + "\xe1\x9e\x94\xe1\x9f\x92\xe1\x9e\x9a\xe1\x9e\x8f\xe1\x9e\xb7\xe1\x9e\x91\xe1\x9e\xb7\xe1\x9e\x93\xe2\x80\x8b\xe1\x9e\xa0\xe1\x9f\x92\xe1\x9e\x9f\xe1\x9e\x80\xe1\x9e\xa0\xe1\x9f\x92\xe1\x9e\x9f\xe1\x9f\x8a\xe1\x9e\xb8\0" + "\xe0\xba\x9b\xe0\xba\xb0\xe0\xba\x95\xe0\xba\xb4\xe0\xba\x97\xe0\xba\xb4\xe0\xba\x99\xe0\xbb\x80\xe0\xba\x81\xe0\xba\xa3\xe0\xbb\x82\xe0\xba\x81\xe0\xba\xa3\xe0\xba\xbd\xe0\xba\x99\0" + "\xe1\x80\x94\xe1\x80\xad\xe1\x80\xaf\xe1\x80\x84\xe1\x80\xba\xe1\x80\x84\xe1\x80\xb6\xe1\x80\x90\xe1\x80\x80\xe1\x80\xac\xe1\x80\x9e\xe1\x80\xaf\xe1\x80\xb6\xe1\x80\xb8 \xe1\x80\x95\xe1\x80\xbc\xe1\x80\x80\xe1\x80\xb9\xe1\x80\x81\xe1\x80\x92\xe1\x80\xad\xe1\x80\x94\xe1\x80\xba\0" + "\xe0\xb6\x9c\xe0\xb7\x8a\xe2\x80\x8d\xe0\xb6\xbb\xe0\xb7\x99\xe0\xb6\x9c\xe0\xb6\xbb\xe0\xb7\x92\xe0\xb6\xba\xe0\xb7\x8f\xe0\xb6\xb1\xe0\xb7\x94 \xe0\xb6\xaf\xe0\xb7\x92\xe0\xb6\xb1 \xe0\xb6\xaf\xe0\xb6\xbb\xe0\xb7\x8a\xe0\xb7\x81\xe0\xb6\xb1\xe0\xb6\xba\0" + "\xe1\x8e\xa9\xe1\x8e\xb4\xe1\x8e\xaa\xe1\x8e\xb5\xe1\x8e\xa0\xe1\x8f\x82 \xe1\x8f\x85\xe1\x8f\x99 \xe1\x8f\x97\xe1\x8f\x8e\xe1\x8f\x8d\xe1\x8f\x97\0" + "\xe1\x8b\xa8\xe1\x8c\x8d\xe1\x88\xaa\xe1\x8c\x8e\xe1\x88\xaa\xe1\x8b\xab\xe1\x8a\x95 \xe1\x8b\xa8\xe1\x89\x80\xe1\x8a\x95 \xe1\x8a\xa0\xe1\x89\x86\xe1\x8c\xa3\xe1\x8c\xa0\xe1\x88\xad\0" + "\xe0\xa4\x97\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x87\xe0\xa4\x97\xe0\xa5\x8b\xe0\xa4\xb0\xe0\xa4\xbf\xe0\xa4\xaf\xe0\xa4\xa8 \xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xa4\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x8b\0" + "Gregoriaanske kalinder\0" + "Gregorian na Kalendaryo\0" + "Gregorianesche Kalenner\0" + "gregorianskit ullorsiutaat\0" + "\xea\x84\x89\xea\x89\xbb\xea\x83\x85\xea\x91\x8d\0" + "deiziadur gregorian\0" + "\xd9\x85\xd9\x89\xd9\x84\xd8\xa7\xd8\xaf\xd9\x89\xd9\x8a\xdb\x95 \xd9\x8a\xd9\x89\xd9\x84\xd9\x86\xd8\xa7\xd9\x85\xdb\x95\xd8\xb3\xd9\x89\0" + "Gregoriaanisch Kal\xc3\xa4nder\0" + "Am M\xc3\xacosachan Griogarach\0" + "\xe5\x85\xac\xe6\x9b\x86\0" + "\xd8\xa7\xd9\x84\xd8\xaa\xd9\x82\xd9\x88\xd9\x8a\xd9\x85 \xd8\xa7\xd9\x84\xd9\x85\xd9\x8a\xd9\x84\xd8\xa7\xd8\xaf\xd9\x8a\0" + "Calend\xc3\xa1rio gregoriano\0" + "gregoria\xc5\x84ski kalender\0" + "\xd0\x93\xd1\x80\xd0\xb8\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb0\xd0\xbd \xd0\xba\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb4\xd0\xb0\xd1\x80\xd0\xb8\0" + "gregoriala\xc5\xa1 kalendar\0" + "\xd0\xb3\xd1\x80\xd0\xb5\xd0\xb3\xd0\xbe\xd1\x80\xd0\xb8\xd1\x98\xd0\xb0\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8 \xd0\xba\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb4\xd0\xb0\xd1\x80\0" +}; + + +#endif + diff --git a/Source/Engine/Localization/CultureInfo.cpp b/Source/Engine/Localization/CultureInfo.cpp index 77de59ee0..3e02ccf6e 100644 --- a/Source/Engine/Localization/CultureInfo.cpp +++ b/Source/Engine/Localization/CultureInfo.cpp @@ -2,13 +2,25 @@ #include "CultureInfo.h" #include "Engine/Core/Log.h" -#include "Engine/Scripting/ManagedCLR/MType.h" +#include "Engine/Core/Types/StringView.h" #include "Engine/Utilities/StringConverter.h" -#if USE_MONO -#include -#include -#include +#include "Engine/Scripting/Types.h" +#include "Engine/Scripting/ManagedCLR/MProperty.h" +#if USE_CSHARP +#include "Engine/Scripting/ScriptingType.h" +#include "Engine/Scripting/BinaryModule.h" +#include "Engine/Scripting/Scripting.h" +#include "Engine/Scripting/ManagedCLR/MAssembly.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" +#endif + +// Use in-built cultures info tables from mono +#include "CultureInfo.Tables.h" + +#if USE_MONO typedef struct { MonoObject obj; @@ -30,7 +42,6 @@ CultureInfo::CultureInfo(int32 lcid) _englishName = TEXT("Invariant Culture"); return; } -#if USE_MONO for (int32 i = 0; i < NUM_CULTURE_ENTRIES; i++) { auto& e = culture_entries[i]; @@ -47,7 +58,6 @@ CultureInfo::CultureInfo(int32 lcid) break; } } -#endif if (!_data) { _englishName = TEXT("Invariant Culture"); @@ -70,7 +80,6 @@ CultureInfo::CultureInfo(const StringAnsiView& name) _englishName = TEXT("Invariant Culture"); return; } -#if USE_MONO for (int32 i = 0; i < NUM_CULTURE_ENTRIES; i++) { auto& e = culture_entries[i]; @@ -87,7 +96,6 @@ CultureInfo::CultureInfo(const StringAnsiView& name) break; } } -#endif if (!_data) { _lcid = 127; @@ -122,16 +130,6 @@ const String& CultureInfo::GetEnglishName() const return _englishName; } -bool CultureInfo::IsRightToLeft() const -{ -#if USE_MONO - const auto data = static_cast(_data); - if (data) - return data->text_info.is_right_to_left ? true : false; -#endif - return false; -} - String CultureInfo::ToString() const { return _name; @@ -144,31 +142,18 @@ bool CultureInfo::operator==(const CultureInfo& other) const void* MUtils::ToManaged(const CultureInfo& value) { -#if USE_MONO - const auto klass = mono_class_from_name(mono_get_corlib(), "System.Globalization", "CultureInfo"); - if (klass) - { - void* iter = nullptr; - MonoMethod* method; - while ((method = mono_class_get_methods(klass, &iter))) - { - if (StringUtils::Compare(mono_method_get_name(method), ".ctor") == 0) - { - const auto sig = mono_method_signature(method); - void* sigParams = nullptr; - mono_signature_get_params(sig, &sigParams); - if (mono_signature_get_param_count(sig) == 1 && mono_type_get_class(((MonoType**)sigParams)[0]) != mono_get_string_class()) - { - MonoObject* obj = mono_object_new(mono_domain_get(), klass); - int32 lcid = value.GetLCID(); - void* params[1]; - params[0] = &lcid; - mono_runtime_invoke(method, obj, params, nullptr); - return obj; - } - } - } - } +#if USE_CSHARP + auto scriptingClass = Scripting::GetStaticClass(); + CHECK_RETURN(scriptingClass, nullptr); + auto cultureInfoToManaged = scriptingClass->GetMethod("CultureInfoToManaged", 1); + CHECK_RETURN(cultureInfoToManaged, nullptr); + + int32 lcid = value.GetLCID(); + void* params[1]; + params[0] = &lcid; + MObject* obj = cultureInfoToManaged->Invoke(nullptr, params, nullptr); + + return obj; #endif return nullptr; } @@ -179,6 +164,17 @@ CultureInfo MUtils::ToNative(void* value) #if USE_MONO if (value) lcid = static_cast(value)->lcid; +#elif USE_CSHARP + const MClass* klass = GetBinaryModuleCorlib()->Assembly->GetClass("System.Globalization.CultureInfo"); + if (value && klass) + { + MProperty* lcidProperty = klass->GetProperty("LCID"); + if (lcidProperty && lcidProperty->GetGetMethod()) + { + MObject* lcidObj = lcidProperty->GetGetMethod()->Invoke(value, nullptr, nullptr); + lcid = *(int32*)MCore::Object::Unbox(lcidObj); + } + } #endif return CultureInfo(lcid); } diff --git a/Source/Engine/Localization/CultureInfo.h b/Source/Engine/Localization/CultureInfo.h index aa82d36f6..debd537ab 100644 --- a/Source/Engine/Localization/CultureInfo.h +++ b/Source/Engine/Localization/CultureInfo.h @@ -11,6 +11,7 @@ API_CLASS(InBuild, Namespace="System.Globalization") class FLAXENGINE_API CultureInfo { DECLARE_SCRIPTING_TYPE_MINIMAL(CultureInfo); + private: void* _data; int32 _lcid; @@ -64,11 +65,6 @@ public: /// const String& GetEnglishName() const; - /// - /// Returns true if culture uses right-to-left (RTL) text layout. Otherwise it's more common left-to-right. - /// - bool IsRightToLeft() const; - String ToString() const; bool operator==(const CultureInfo& other) const; }; diff --git a/Source/Engine/Platform/Base/ThreadBase.cpp b/Source/Engine/Platform/Base/ThreadBase.cpp index 5739dbf3e..878cacfec 100644 --- a/Source/Engine/Platform/Base/ThreadBase.cpp +++ b/Source/Engine/Platform/Base/ThreadBase.cpp @@ -111,7 +111,7 @@ int32 ThreadBase::Run() _isRunning = false; ThreadExiting(thread, exitCode); ThreadRegistry::Remove(thread); - MCore::ExitThread(); // TODO: use mono_thread_detach instead of ext and unlink mono runtime from thread in ThreadExiting delegate + MCore::Thread::Exit(); // TODO: use mono_thread_detach instead of ext and unlink mono runtime from thread in ThreadExiting delegate // mono terminates the native thread.. return exitCode; diff --git a/Source/Engine/Platform/Base/WindowBase.cpp b/Source/Engine/Platform/Base/WindowBase.cpp index a9ffc8f25..e2460e373 100644 --- a/Source/Engine/Platform/Base/WindowBase.cpp +++ b/Source/Engine/Platform/Base/WindowBase.cpp @@ -10,15 +10,12 @@ #include "Engine/Platform/IGuiData.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Profiler/ProfilerCPU.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" #include "Engine/Scripting/ManagedCLR/MClass.h" -#if USE_MONO -#include -#endif -#if USE_MONO +#if USE_CSHARP // Helper macros for calling C# events #define BEGIN_INVOKE_EVENT(name, paramsCount) \ auto managedInstance = GetManagedInstance(); \ @@ -68,10 +65,11 @@ isText = false; data->GetAsFiles(&outputData); \ } \ params[1] = (void*)&isText; \ - MonoArray* outputDataMono = mono_array_new(mono_domain_get(), mono_get_string_class(), outputData.Count()); \ + MArray* outputDataManaged = MCore::Array::New(MCore::TypeCache::String, outputData.Count()); \ + MString** outputDataManagedPtr = MCore::Array::GetAddress(outputDataManaged); \ for (int32 i = 0; i < outputData.Count(); i++) \ - *(MonoString**)mono_array_addr_with_size(outputDataMono, sizeof(MonoString*), i) = MUtils::ToString(outputData[i]); \ - params[2] = outputDataMono; \ + outputDataManagedPtr[i] = MUtils::ToString(outputData[i]); \ + params[2] = outputDataManaged; \ MObject* exception = nullptr; \ auto resultObj = _method_##name->Invoke(GetManagedInstance(), params, &exception); \ if (resultObj) \ diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index c60f13064..1238d2548 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -7,15 +7,14 @@ #include "Engine/Profiler/ProfilerCPU.h" #include "ManagedCLR/MAssembly.h" #include "ManagedCLR/MClass.h" -#include "ManagedCLR/MType.h" #include "ManagedCLR/MMethod.h" #include "ManagedCLR/MField.h" #include "ManagedCLR/MUtils.h" +#include "ManagedCLR/MException.h" #include "FlaxEngine.Gen.h" -#include "MException.h" #include "Scripting.h" #include "Events.h" -#include "StdTypesContainer.h" +#include "Internal/StdTypesContainer.h" Dictionary, void(*)(ScriptingObject*, void*, bool)> ScriptingEvents::EventsTable; Delegate, ScriptingTypeHandle, StringView> ScriptingEvents::Event; @@ -25,7 +24,7 @@ ManagedBinaryModule* GetBinaryModuleCorlib() #if COMPILE_WITHOUT_CSHARP return nullptr; #else - static ManagedBinaryModule assembly("corlib", MAssemblyOptions(false)); // Don't precache all corlib classes + static ManagedBinaryModule assembly("corlib"); return &assembly; #endif } @@ -54,12 +53,12 @@ const ScriptingType& ScriptingTypeHandle::GetType() const return Module->Types[TypeIndex]; } -#if USE_MONO +#if USE_CSHARP -MonoClass* ScriptingTypeHandle::GetMonoClass() const +MClass* ScriptingTypeHandle::GetClass() const { ASSERT_LOW_LAYER(Module && Module->Types[TypeIndex].ManagedClass); - return Module->Types[TypeIndex].ManagedClass->GetNative(); + return Module->Types[TypeIndex].ManagedClass; } #endif @@ -695,8 +694,8 @@ void BinaryModule::Destroy(bool isReloading) GetModules().RemoveKeepOrder(this); } -ManagedBinaryModule::ManagedBinaryModule(const StringAnsiView& name, const MAssemblyOptions& options) - : ManagedBinaryModule(New(nullptr, name, options)) +ManagedBinaryModule::ManagedBinaryModule(const StringAnsiView& name) + : ManagedBinaryModule(New(nullptr, name)) { } @@ -799,18 +798,18 @@ namespace return nullptr; } - bool VariantTypeEquals(const VariantType& type, MonoType* monoType) + bool VariantTypeEquals(const VariantType& type, MType* mType) { - MonoClass* monoClass = mono_class_from_mono_type(monoType); - if (MUtils::GetClass(type) != monoClass) + MClass* mClass = MCore::Type::GetClass(mType); + if (MUtils::GetClass(type) != mClass) { // Hack for Vector2/3/4 which alias with Float2/3/4 or Double2/3/4 (depending on USE_LARGE_WORLDS) const auto& stdTypes = *StdTypesContainer::Instance(); - if (monoClass == stdTypes.Vector2Class->GetNative() && (type.Type == VariantType::Float2 || type.Type == VariantType::Double2)) + if (mClass == stdTypes.Vector2Class && (type.Type == VariantType::Float2 || type.Type == VariantType::Double2)) return true; - if (monoClass == stdTypes.Vector3Class->GetNative() && (type.Type == VariantType::Float3 || type.Type == VariantType::Double3)) + if (mClass == stdTypes.Vector3Class && (type.Type == VariantType::Float3 || type.Type == VariantType::Double3)) return true; - if (monoClass == stdTypes.Vector4Class->GetNative() && (type.Type == VariantType::Float4 || type.Type == VariantType::Double4)) + if (mClass == stdTypes.Vector4Class && (type.Type == VariantType::Float4 || type.Type == VariantType::Double4)) return true; return false; @@ -828,64 +827,54 @@ MMethod* ManagedBinaryModule::FindMethod(MClass* mclass, const ScriptingTypeMeth const auto& methods = mclass->GetMethods(); for (MMethod* method : methods) { -#if USE_MONO - MonoMethodSignature* sig = mono_method_signature(method->GetNative()); - /*if (method->IsStatic() != signature.IsStatic || - method->GetName() != signature.Name || - (int32)mono_signature_get_param_count(sig) != signature.Params.Count()) - continue;*/ +#if USE_CSHARP if (method->IsStatic() != signature.IsStatic) continue; if (method->GetName() != signature.Name) continue; - if ((int32)mono_signature_get_param_count(sig) != signature.Params.Count()) + if (method->GetParametersCount() != signature.Params.Count()) continue; - void* sigParams = nullptr; - MonoType* type = mono_signature_get_params(sig, &sigParams); bool isValid = true; - int paramIdx = 0; - while (type != nullptr) + for (int32 paramIdx = 0; paramIdx < signature.Params.Count(); paramIdx++) { auto& param = signature.Params[paramIdx]; - if (param.IsOut != (mono_signature_param_is_out(sig, paramIdx) != 0) || + MType* type = method->GetParameterType(paramIdx); + if (param.IsOut != method->GetParameterIsOut(paramIdx) || !VariantTypeEquals(param.Type, type)) { - auto asdf = VariantTypeEquals(param.Type, type); isValid = false; break; } - - type = mono_signature_get_params(sig, &sigParams); - paramIdx++; } - if (isValid && VariantTypeEquals(signature.ReturnType, mono_signature_get_return_type(sig))) + if (isValid && VariantTypeEquals(signature.ReturnType, method->GetReturnType())) return method; #endif } return nullptr; } -#if USE_MONO +#if USE_CSHARP -ManagedBinaryModule* ManagedBinaryModule::FindModule(MonoClass* klass) +ManagedBinaryModule* ManagedBinaryModule::FindModule(const MClass* klass) { - // TODO: consider caching lookup table MonoImage* -> ManagedBinaryModule* ManagedBinaryModule* module = nullptr; - MonoImage* mImage = mono_class_get_image(klass); - auto& modules = BinaryModule::GetModules(); - for (auto e : modules) + if (klass && klass->GetAssembly()) { - auto managedModule = dynamic_cast(e); - if (managedModule && managedModule->Assembly->GetMonoImage() == mImage) + auto& modules = BinaryModule::GetModules(); + for (auto e : modules) { - module = managedModule; - break; + auto managedModule = dynamic_cast(e); + if (managedModule && managedModule->Assembly == klass->GetAssembly()) + { + module = managedModule; + break; + } } } return module; } -ScriptingTypeHandle ManagedBinaryModule::FindType(MonoClass* klass) +ScriptingTypeHandle ManagedBinaryModule::FindType(const MClass* klass) { auto typeModule = FindModule(klass); if (typeModule) @@ -924,7 +913,7 @@ void ManagedBinaryModule::OnLoaded(MAssembly* assembly) ASSERT(type.ManagedClass == nullptr); // Cache class - const MString typeName(type.Fullname.Get(), type.Fullname.Length()); + const StringAnsi typeName(type.Fullname.Get(), type.Fullname.Length()); classes.TryGet(typeName, type.ManagedClass); if (type.ManagedClass == nullptr) { @@ -933,7 +922,7 @@ void ManagedBinaryModule::OnLoaded(MAssembly* assembly) } // Cache klass -> type index lookup - MonoClass* klass = type.ManagedClass->GetNative(); + MClass* klass = type.ManagedClass; #if !BUILD_RELEASE if (ClassToTypeIndex.ContainsKey(klass)) { @@ -1004,26 +993,14 @@ void ManagedBinaryModule::InitType(MClass* mclass) { #if !COMPILE_WITHOUT_CSHARP // Skip if already initialized - const MString& typeName = mclass->GetFullName(); + const StringAnsi& typeName = mclass->GetFullName(); if (TypeNameToTypeIndex.ContainsKey(typeName)) return; // Find first native base C++ class of this C# class - MClass* baseClass = nullptr; - MonoClass* baseKlass = mono_class_get_parent(mclass->GetNative()); - MonoImage* baseKlassImage = mono_class_get_image(baseKlass); + MClass* baseClass = mclass->GetBaseClass(); ScriptingTypeHandle baseType; - auto& modules = GetModules(); - for (int32 i = 0; i < modules.Count(); i++) - { - auto e = dynamic_cast(modules[i]); - if (e && e->Assembly->GetMonoImage() == baseKlassImage) - { - baseType.Module = e; - baseClass = e->Assembly->GetClass(baseKlass); - break; - } - } + baseType.Module = FindModule(baseClass); if (!baseClass) { LOG(Error, "Missing base class for managed class {0} from assembly {1}.", String(typeName), Assembly->ToString()); @@ -1058,13 +1035,12 @@ void ManagedBinaryModule::InitType(MClass* mclass) _managedMemoryBlocks.Add(typeNameData); // Initialize scripting interfaces implemented in C# - MonoClass* interfaceKlass; - void* interfaceIt = nullptr; int32 interfacesCount = 0; - MonoClass* klass = mclass->GetNative(); - while ((interfaceKlass = mono_class_get_interfaces(klass, &interfaceIt))) + MClass* klass = mclass; + const Array& interfaceClasses = klass->GetInterfaces(); + for (const MClass* interfaceClass : interfaceClasses) { - const ScriptingTypeHandle interfaceType = FindType(interfaceKlass); + const ScriptingTypeHandle interfaceType = FindType(interfaceClass); if (interfaceType) interfacesCount++; } @@ -1073,10 +1049,9 @@ void ManagedBinaryModule::InitType(MClass* mclass) { interfaces = (ScriptingType::InterfaceImplementation*)Allocator::Allocate((interfacesCount + 1) * sizeof(ScriptingType::InterfaceImplementation)); interfacesCount = 0; - interfaceIt = nullptr; - while ((interfaceKlass = mono_class_get_interfaces(klass, &interfaceIt))) + for (const MClass* interfaceClass : interfaceClasses) { - const ScriptingTypeHandle interfaceTypeHandle = FindType(interfaceKlass); + const ScriptingTypeHandle interfaceTypeHandle = FindType(interfaceClass); if (!interfaceTypeHandle) continue; auto& interface = interfaces[interfacesCount++]; @@ -1100,7 +1075,7 @@ void ManagedBinaryModule::InitType(MClass* mclass) auto& type = Types[typeIndex]; type.ManagedClass = mclass; - // Register Mono class + // Register C# class ASSERT(!ClassToTypeIndex.ContainsKey(klass)); ClassToTypeIndex[klass] = typeIndex; @@ -1125,11 +1100,9 @@ void ManagedBinaryModule::InitType(MClass* mclass) // Special case if method was found but the base class uses generic arguments if (method && baseClass->IsGeneric()) { - // TODO: encapsulate it into MClass to support inflated methods - auto parentClass = mono_class_get_parent(mclass->GetNative()); - auto parentMethod = mono_class_get_method_from_name(parentClass, referenceMethod->GetName().Get(), 0); - auto inflatedMethod = mono_class_inflate_generic_method(parentMethod, nullptr); - method = New(inflatedMethod, baseClass); + MClass* parentClass = mclass->GetBaseClass(); + MMethod* parentMethod = parentClass->GetMethod(referenceMethod->GetName().Get(), 0); + method = parentMethod->InflateGeneric(); } baseClass = baseClass->GetBaseClass(); @@ -1153,7 +1126,7 @@ void ManagedBinaryModule::OnUnloading(MAssembly* assembly) for (int32 i = _firstManagedTypeIndex; i < Types.Count(); i++) { const ScriptingType& type = Types[i]; - const MString typeName(type.Fullname.Get(), type.Fullname.Length()); + const StringAnsi typeName(type.Fullname.Get(), type.Fullname.Length()); TypeNameToTypeIndex.Remove(typeName); } } @@ -1211,10 +1184,9 @@ void* ManagedBinaryModule::FindMethod(const ScriptingTypeHandle& typeHandle, con bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Span paramValues, Variant& result) { -#if USE_MONO +#if USE_CSHARP const auto mMethod = (MMethod*)method; - MonoMethodSignature* signature = mono_method_signature(mMethod->GetNative()); - const int32 parametersCount = mono_signature_get_param_count(signature); + const int32 parametersCount = mMethod->GetParametersCount();; if (paramValues.Length() != parametersCount) { LOG(Error, "Failed to call method '{0}.{1}' (args count: {2}) with invalid parameters amount ({3})", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount, paramValues.Length()); @@ -1227,10 +1199,10 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp if (!mMethod->IsStatic()) { // Box instance into C# object - MonoObject* instanceObject = MUtils::BoxVariant(instance); + MObject* instanceObject = MUtils::BoxVariant(instance); // Validate instance - if (!instanceObject || !mono_class_is_subclass_of(mono_object_get_class(instanceObject), mMethod->GetParentClass()->GetNative(), withInterfaces)) + if (!instanceObject || !MCore::Object::GetClass(instanceObject)->IsSubClassOf(mMethod->GetParentClass(), withInterfaces)) { if (!instanceObject) LOG(Error, "Failed to call method '{0}.{1}' (args count: {2}) without object instance", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount); @@ -1240,37 +1212,32 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp } // For value-types instance is the actual boxed object data, not te object itself - mInstance = mono_class_is_valuetype(mono_object_get_class(instanceObject)) ? mono_object_unbox(instanceObject) : instanceObject; + mInstance = MCore::Object::GetClass(instanceObject)->IsValueType() ? MCore::Object::Unbox(instanceObject) : instanceObject; } // Marshal parameters void** params = (void**)alloca(parametersCount * sizeof(void*)); bool failed = false; bool hasOutParams = false; - void* sigParams = nullptr; - MonoType* type = mono_signature_get_params(signature, &sigParams); - for (int paramIdx = 0; type != nullptr;) + for (int32 paramIdx = 0; paramIdx < parametersCount; paramIdx++) { - auto& paramValue = paramValues[paramIdx]; - const bool isOut = mono_signature_param_is_out(signature, paramIdx) != 0; + Variant& paramValue = paramValues[paramIdx]; + const bool isOut = mMethod->GetParameterIsOut(paramIdx); hasOutParams |= isOut; // Marshal parameter for managed method - MType paramType(type); + MType* paramType = mMethod->GetParameterType(paramIdx); params[paramIdx] = MUtils::VariantToManagedArgPtr(paramValue, paramType, failed); if (failed) { - LOG(Error, "Failed to marshal parameter {5}:{4} of method '{0}.{1}' (args count: {2}), value type: {6}, value: {3}", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount, paramValue, paramType.ToString(), paramIdx, paramValue.Type); + LOG(Error, "Failed to marshal parameter {5}:{4} of method '{0}.{1}' (args count: {2}), value type: {6}, value: {3}", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount, paramValue, MCore::Type::ToString(paramType), paramIdx, paramValue.Type); return true; } - - type = mono_signature_get_params(signature, &sigParams); - paramIdx++; } // Invoke the method MObject* exception = nullptr; - MonoObject* resultObject = withInterfaces ? mMethod->InvokeVirtual((MonoObject*)mInstance, params, &exception) : mMethod->Invoke(mInstance, params, &exception); + MObject* resultObject = withInterfaces ? mMethod->InvokeVirtual((MObject*)mInstance, params, &exception) : mMethod->Invoke(mInstance, params, &exception); if (exception) { MException ex(exception); @@ -1303,18 +1270,17 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp { for (int32 paramIdx = 0; paramIdx < parametersCount; paramIdx++) { - const bool isOut = mono_signature_param_is_out(signature, paramIdx) != 0; - if (isOut) + if (mMethod->GetParameterIsOut(paramIdx)) { auto& paramValue = paramValues[paramIdx]; auto param = params[paramIdx]; switch (paramValue.Type.Type) { case VariantType::String: - paramValue.SetString(MUtils::ToString((MonoString*)param)); + paramValue.SetString(MUtils::ToString((MString*)param)); break; case VariantType::Object: - paramValue = MUtils::UnboxVariant((MonoObject*)param); + paramValue = MUtils::UnboxVariant((MObject*)param); break; case VariantType::Structure: { @@ -1322,7 +1288,8 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp if (paramTypeHandle) { auto& valueType = paramTypeHandle.GetType(); - valueType.Struct.Unbox(paramValue.AsBlob.Data, (MonoObject*)((byte*)param - sizeof(MonoObject))); + MISSING_CODE("TODO: reimplement unpacking managed structure out parameter from C# call"); + //valueType.Struct.Unbox(paramValue.AsBlob.Data, (MObject*)((byte*)param - sizeof(MonoObject))); // TODO: fix this for dotnet7 } break; } @@ -1339,21 +1306,18 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp void ManagedBinaryModule::GetMethodSignature(void* method, ScriptingTypeMethodSignature& signature) { -#if USE_MONO +#if USE_CSHARP const auto mMethod = (MMethod*)method; signature.Name = mMethod->GetName(); signature.IsStatic = mMethod->IsStatic(); - MonoMethodSignature* sig = mono_method_signature(mMethod->GetNative()); - signature.ReturnType = MoveTemp(MUtils::UnboxVariantType(mono_signature_get_return_type(sig))); - void* signatureParams = nullptr; - mono_signature_get_params(sig, &signatureParams); - const int32 paramsCount = (int32)mono_signature_get_param_count(sig); + signature.ReturnType = MoveTemp(MUtils::UnboxVariantType(mMethod->GetReturnType())); + const int32 paramsCount = mMethod->GetParametersCount(); signature.Params.Resize(paramsCount); for (int32 paramIdx = 0; paramIdx < paramsCount; paramIdx++) { auto& param = signature.Params[paramIdx]; - param.Type = MoveTemp(MUtils::UnboxVariantType(((MonoType**)signatureParams)[paramIdx])); - param.IsOut = mono_signature_param_is_out(sig, paramIdx) != 0; + param.Type = MoveTemp(MUtils::UnboxVariantType(mMethod->GetParameterType(paramIdx))); + param.IsOut = mMethod->GetParameterIsOut(paramIdx); } #endif } @@ -1366,28 +1330,28 @@ void* ManagedBinaryModule::FindField(const ScriptingTypeHandle& typeHandle, cons void ManagedBinaryModule::GetFieldSignature(void* field, ScriptingTypeFieldSignature& fieldSignature) { -#if USE_MONO +#if USE_CSHARP const auto mField = (MField*)field; fieldSignature.Name = mField->GetName(); - fieldSignature.ValueType = MoveTemp(MUtils::UnboxVariantType(mField->GetType().GetNative())); + fieldSignature.ValueType = MoveTemp(MUtils::UnboxVariantType(mField->GetType())); fieldSignature.IsStatic = mField->IsStatic(); #endif } bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Variant& result) { -#if USE_MONO +#if USE_CSHARP const auto mField = (MField*)field; // Get instance object - MonoObject* instanceObject = nullptr; + MObject* instanceObject = nullptr; if (!mField->IsStatic()) { // Box instance into C# object instanceObject = MUtils::BoxVariant(instance); // Validate instance - if (!instanceObject || !mono_class_is_subclass_of(mono_object_get_class(instanceObject), mField->GetParentClass()->GetNative(), false)) + if (!instanceObject || !MCore::Object::GetClass(instanceObject)->IsSubClassOf(mField->GetParentClass())) { if (!instanceObject) LOG(Error, "Failed to get field '{0}.{1}' without object instance", String(mField->GetParentClass()->GetFullName()), String(mField->GetName())); @@ -1398,7 +1362,7 @@ bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Va } // Get the value - MonoObject* resultObject = mField->GetValueBoxed(instanceObject); + MObject* resultObject = mField->GetValueBoxed(instanceObject); result = MUtils::UnboxVariant(resultObject); return false; #else @@ -1408,18 +1372,18 @@ bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Va bool ManagedBinaryModule::SetFieldValue(void* field, const Variant& instance, Variant& value) { -#if USE_MONO +#if USE_CSHARP const auto mField = (MField*)field; // Get instance object - MonoObject* instanceObject = nullptr; + MObject* instanceObject = nullptr; if (!mField->IsStatic()) { // Box instance into C# object instanceObject = MUtils::BoxVariant(instance); // Validate instance - if (!instanceObject || !mono_class_is_subclass_of(mono_object_get_class(instanceObject), mField->GetParentClass()->GetNative(), false)) + if (!instanceObject || !MCore::Object::GetClass(instanceObject)->IsSubClassOf(mField->GetParentClass())) { if (!instanceObject) LOG(Error, "Failed to set field '{0}.{1}' without object instance", String(mField->GetParentClass()->GetFullName()), String(mField->GetName())); @@ -1446,8 +1410,8 @@ void ManagedBinaryModule::Destroy(bool isReloading) Assembly->Unload(isReloading); } -NativeBinaryModule::NativeBinaryModule(const StringAnsiView& name, const MAssemblyOptions& options) - : NativeBinaryModule(New(nullptr, name, options)) +NativeBinaryModule::NativeBinaryModule(const StringAnsiView& name) + : NativeBinaryModule(New(nullptr, name)) { } diff --git a/Source/Engine/Scripting/BinaryModule.h b/Source/Engine/Scripting/BinaryModule.h index 02e3e0c2e..36e90acdf 100644 --- a/Source/Engine/Scripting/BinaryModule.h +++ b/Source/Engine/Scripting/BinaryModule.h @@ -9,7 +9,6 @@ #include "Engine/Core/Collections/Dictionary.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Core/ISerializable.h" -#include "ManagedCLR/MAssemblyOptions.h" /// /// The scripting type method metadata for code reflection. @@ -269,8 +268,7 @@ public: /// Initializes a new instance of the class. /// /// The module name. - /// The assembly options. - ManagedBinaryModule(const StringAnsiView& name, const MAssemblyOptions& options); + ManagedBinaryModule(const StringAnsiView& name); /// /// Initializes a new instance of the class. @@ -290,18 +288,18 @@ public: /// MAssembly* Assembly; -#if !COMPILE_WITHOUT_CSHARP +#if USE_CSHARP /// /// The scripting types cache that maps the managed class to the scripting type index. Build after assembly is loaded and scripting types get the managed classes information. /// - Dictionary ClassToTypeIndex; + Dictionary ClassToTypeIndex; #endif static ScriptingObject* ManagedObjectSpawn(const ScriptingObjectSpawnParams& params); static MMethod* FindMethod(MClass* mclass, const ScriptingTypeMethodSignature& signature); -#if USE_MONO - static ManagedBinaryModule* FindModule(MonoClass* klass); - static ScriptingTypeHandle FindType(MonoClass* klass); +#if USE_CSHARP + static ManagedBinaryModule* FindModule(const MClass* klass); + static ScriptingTypeHandle FindType(const MClass* klass); #endif private: @@ -339,8 +337,7 @@ public: /// Initializes a new instance of the class. /// /// The module name. - /// The assembly options. - NativeBinaryModule(const StringAnsiView& name, const MAssemblyOptions& options); + NativeBinaryModule(const StringAnsiView& name); /// /// Initializes a new instance of the class. diff --git a/Source/Engine/Scripting/DotNet/CoreCLR.cpp b/Source/Engine/Scripting/DotNet/CoreCLR.cpp deleted file mode 100644 index be069e75e..000000000 --- a/Source/Engine/Scripting/DotNet/CoreCLR.cpp +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "CoreCLR.h" - -#if USE_NETCORE -#include "Engine/Core/Log.h" -#include "Engine/Platform/Platform.h" -#include "Engine/Platform/FileSystem.h" -#include "Engine/Core/Types/DateTime.h" -#include "Engine/Core/Collections/Dictionary.h" -#include "Engine/Debug/DebugLog.h" -#include "Engine/Engine/Globals.h" -#if DOTNET_HOST_CORECRL -#include -#include -#include -#elif DOTNET_HOST_MONO -#include "Engine/Scripting/ManagedCLR/MCore.h" -#include "Engine/Scripting/ManagedCLR/MDomain.h" -#include "Engine/Debug/Exceptions/CLRInnerException.h" -#include -#include -#include -typedef char char_t; -#else -#error "Unknown .NET runtime host." -#endif -#if PLATFORM_WINDOWS -#include -#undef SetEnvironmentVariable -#undef LoadLibrary -#endif - -static Dictionary CachedFunctions; -static const char_t* NativeInteropTypeName = FLAX_CORECLR_TEXT("FlaxEngine.NativeInterop, FlaxEngine.CSharp"); - -#if DOTNET_HOST_CORECRL - -hostfxr_initialize_for_runtime_config_fn hostfxr_initialize_for_runtime_config; -hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line; -hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate; -hostfxr_close_fn hostfxr_close; -load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer; -get_function_pointer_fn get_function_pointer; -hostfxr_set_error_writer_fn hostfxr_set_error_writer; -hostfxr_get_dotnet_environment_info_result_fn hostfxr_get_dotnet_environment_info_result; -hostfxr_run_app_fn hostfxr_run_app; - -bool CoreCLR::InitHostfxr(const String& configPath, const String& libraryPath) -{ - const FLAX_CORECLR_STRING& library_path = FLAX_CORECLR_STRING(libraryPath); - - // Get path to hostfxr library - get_hostfxr_parameters get_hostfxr_params; - get_hostfxr_params.size = sizeof(hostfxr_initialize_parameters); - get_hostfxr_params.assembly_path = library_path.Get(); - FLAX_CORECLR_STRING dotnetRoot; - // TODO: implement proper lookup for dotnet instalation folder and handle standalone build of FlaxGame -#if PLATFORM_MAC - get_hostfxr_params.dotnet_root = "/usr/local/share/dotnet"; -#else - get_hostfxr_params.dotnet_root = nullptr; -#endif -#if !USE_EDITOR - const String& bundledDotnetPath = Globals::ProjectFolder / TEXT("Dotnet"); - if (FileSystem::DirectoryExists(bundledDotnetPath)) - { - dotnetRoot = FLAX_CORECLR_STRING(bundledDotnetPath); -#if PLATFORM_WINDOWS_FAMILY - dotnetRoot.Replace('/', '\\'); -#endif - get_hostfxr_params.dotnet_root = dotnetRoot.Get(); - } -#endif - char_t hostfxrPath[1024]; - size_t hostfxrPathSize = sizeof(hostfxrPath) / sizeof(char_t); - int rc = get_hostfxr_path(hostfxrPath, &hostfxrPathSize, &get_hostfxr_params); - if (rc != 0) - { - LOG(Error, "Failed to find hostfxr: {0:x} ({1})", (unsigned int)rc, String(get_hostfxr_params.dotnet_root)); - - // Warn user about missing .Net -#if PLATFORM_DESKTOP - Platform::OpenUrl(TEXT("https://dotnet.microsoft.com/en-us/download/dotnet/7.0")); -#endif -#if USE_EDITOR - LOG(Fatal, "Missing .NET 7 SDK installation requried to run Flax Editor."); -#else - LOG(Fatal, "Missing .NET 7 Runtime installation requried to run this application."); -#endif - return true; - } - String path(hostfxrPath); - LOG(Info, "Found hostfxr in {0}", path); - - // Get API from hostfxr library - void* hostfxr = Platform::LoadLibrary(path.Get()); - if (hostfxr == nullptr) - { - LOG(Fatal, "Failed to load hostfxr library ({0})", path); - return true; - } - hostfxr_initialize_for_runtime_config = (hostfxr_initialize_for_runtime_config_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_runtime_config"); - hostfxr_initialize_for_dotnet_command_line = (hostfxr_initialize_for_dotnet_command_line_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_dotnet_command_line"); - hostfxr_get_runtime_delegate = (hostfxr_get_runtime_delegate_fn)Platform::GetProcAddress(hostfxr, "hostfxr_get_runtime_delegate"); - hostfxr_close = (hostfxr_close_fn)Platform::GetProcAddress(hostfxr, "hostfxr_close"); - hostfxr_set_error_writer = (hostfxr_set_error_writer_fn)Platform::GetProcAddress(hostfxr, "hostfxr_set_error_writer"); - hostfxr_get_dotnet_environment_info_result = (hostfxr_get_dotnet_environment_info_result_fn)Platform::GetProcAddress(hostfxr, "hostfxr_get_dotnet_environment_info_result"); - hostfxr_run_app = (hostfxr_run_app_fn)Platform::GetProcAddress(hostfxr, "hostfxr_run_app"); - if (!hostfxr_get_runtime_delegate || !hostfxr_run_app) - { - LOG(Fatal, "Failed to setup hostfxr API ({0})", path); - return true; - } - - // Initialize hosting component - const char_t* argv[1] = { library_path.Get() }; - hostfxr_initialize_parameters init_params; - init_params.size = sizeof(hostfxr_initialize_parameters); - init_params.host_path = library_path.Get(); - path = String(StringUtils::GetDirectoryName(path)) / TEXT("/../../../"); - StringUtils::PathRemoveRelativeParts(path); - dotnetRoot = FLAX_CORECLR_STRING(path); - init_params.dotnet_root = dotnetRoot.Get(); - hostfxr_handle handle = nullptr; - rc = hostfxr_initialize_for_dotnet_command_line(ARRAY_COUNT(argv), argv, &init_params, &handle); - if (rc != 0 || handle == nullptr) - { - hostfxr_close(handle); - LOG(Fatal, "Failed to initialize hostfxr: {0:x} ({1})", (unsigned int)rc, String(init_params.dotnet_root)); - return true; - } - - void* pget_function_pointer = nullptr; - rc = hostfxr_get_runtime_delegate(handle, hdt_get_function_pointer, &pget_function_pointer); - if (rc != 0 || pget_function_pointer == nullptr) - { - hostfxr_close(handle); - LOG(Fatal, "Failed to get runtime delegate hdt_get_function_pointer: 0x{0:x}", (unsigned int)rc); - return true; - } - - hostfxr_close(handle); - get_function_pointer = (get_function_pointer_fn)pget_function_pointer; - return false; -} - -void CoreCLR::ShutdownHostfxr() -{ -} - -void* CoreCLR::GetStaticMethodPointer(const String& methodName) -{ - void* fun; - if (CachedFunctions.TryGet(methodName, fun)) - return fun; - - int rc = get_function_pointer(NativeInteropTypeName, FLAX_CORECLR_STRING(methodName).Get(), UNMANAGEDCALLERSONLY_METHOD, nullptr, nullptr, &fun); - if (rc != 0) - LOG(Fatal, "Failed to get unmanaged function pointer for method {0}: 0x{1:x}", methodName.Get(), (unsigned int)rc); - - CachedFunctions.Add(methodName, fun); - return fun; -} - -#elif DOTNET_HOST_MONO - -#ifdef USE_MONO_AOT_MODULE -void* MonoAotModuleHandle = nullptr; -#endif -MonoDomain* MonoDomainHandle = nullptr; - -void OnLogCallback(const char* logDomain, const char* logLevel, const char* message, mono_bool fatal, void* userData) -{ - String currentDomain(logDomain); - String msg(message); - msg.Replace('\n', ' '); - - static const char* monoErrorLevels[] = - { - nullptr, - "error", - "critical", - "warning", - "message", - "info", - "debug" - }; - - uint32 errorLevel = 0; - if (logLevel != nullptr) - { - for (uint32 i = 1; i < 7; i++) - { - if (strcmp(monoErrorLevels[i], logLevel) == 0) - { - errorLevel = i; - break; - } - } - } - - if (currentDomain.IsEmpty()) - { - auto domain = MCore::GetActiveDomain(); - if (domain != nullptr) - { - currentDomain = domain->GetName().Get(); - } - else - { - currentDomain = "null"; - } - } - -#if 0 - // Print C# stack trace (crash may be caused by the managed code) - if (mono_domain_get() && Assemblies::FlaxEngine.Assembly->IsLoaded()) - { - const auto managedStackTrace = DebugLog::GetStackTrace(); - if (managedStackTrace.HasChars()) - { - LOG(Warning, "Managed stack trace:"); - LOG_STR(Warning, managedStackTrace); - } - } -#endif - - if (errorLevel == 0) - { - Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); - } - else if (errorLevel <= 2) - { - Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); - } - else if (errorLevel <= 3) - { - LOG(Warning, "Message: {0} | Domain: {1}", msg, currentDomain); - } - else - { - LOG(Info, "Message: {0} | Domain: {1}", msg, currentDomain); - } -} - -void OnPrintCallback(const char* string, mono_bool isStdout) -{ - LOG_STR(Warning, String(string)); -} - -void OnPrintErrorCallback(const char* string, mono_bool isStdout) -{ - // HACK: ignore this message - if (string && Platform::MemoryCompare(string, "debugger-agent: Unable to listen on ", 36) == 0) - return; - - LOG_STR(Error, String(string)); -} - -bool CoreCLR::InitHostfxr(const String& configPath, const String& libraryPath) -{ -#if 1 - // Enable detailed Mono logging - Platform::SetEnvironmentVariable(TEXT("MONO_LOG_LEVEL"), TEXT("debug")); - Platform::SetEnvironmentVariable(TEXT("MONO_LOG_MASK"), TEXT("all")); - //Platform::SetEnvironmentVariable(TEXT("MONO_GC_DEBUG"), TEXT("6:gc-log.txt,check-remset-consistency,nursery-canaries")); -#endif - -#if defined(USE_MONO_AOT_MODE) - // Enable AOT mode (per-platform) - mono_jit_set_aot_mode(USE_MONO_AOT_MODE); -#endif - -#ifdef USE_MONO_AOT_MODULE - // Load AOT module - const DateTime aotModuleLoadStartTime = DateTime::Now(); - LOG(Info, "Loading Mono AOT module..."); - void* libAotModule = Platform::LoadLibrary(TEXT(USE_MONO_AOT_MODULE)); - if (libAotModule == nullptr) - { - LOG(Error, "Failed to laod Mono AOT module (" TEXT(USE_MONO_AOT_MODULE) ")"); - return true; - } - MonoAotModuleHandle = libAotModule; - void* getModulesPtr = Platform::GetProcAddress(libAotModule, "GetMonoModules"); - if (getModulesPtr == nullptr) - { - LOG(Error, "Failed to get Mono AOT modules getter."); - return true; - } - typedef int (*GetMonoModulesFunc)(void** buffer, int bufferSize); - const auto getModules = (GetMonoModulesFunc)getModulesPtr; - const int32 moduelsCount = getModules(nullptr, 0); - void** modules = (void**)Allocator::Allocate(moduelsCount * sizeof(void*)); - getModules(modules, moduelsCount); - for (int32 i = 0; i < moduelsCount; i++) - { - mono_aot_register_module((void**)modules[i]); - } - Allocator::Free(modules); - LOG(Info, "Mono AOT module loaded in {0}ms", (int32)(DateTime::Now() - aotModuleLoadStartTime).GetTotalMilliseconds()); -#endif - - // TODO: setup C# debugger - - // Connect to mono engine callback system - mono_trace_set_log_handler(OnLogCallback, nullptr); - mono_trace_set_print_handler(OnPrintCallback); - mono_trace_set_printerr_handler(OnPrintErrorCallback); - - // Initialize Mono VM - StringAnsi baseDirectory(Globals::ProjectFolder); - const char* appctxKeys[] = - { - "RUNTIME_IDENTIFIER", - "APP_CONTEXT_BASE_DIRECTORY", - }; - const char* appctxValues[] = - { - MACRO_TO_STR(DOTNET_HOST_RUNTIME_IDENTIFIER), - baseDirectory.Get(), - }; - static_assert(ARRAY_COUNT(appctxKeys) == ARRAY_COUNT(appctxValues), "Invalid appctx setup"); - monovm_initialize(ARRAY_COUNT(appctxKeys), appctxKeys, appctxValues); - - // Init managed runtime -#if PLATFORM_ANDROID || PLATFORM_IOS - const char* monoVersion = "mobile"; -#else - const char* monoVersion = ""; // ignored -#endif - MonoDomainHandle = mono_jit_init_version("Flax", monoVersion); - if (!MonoDomainHandle) - { - LOG(Fatal, "Failed to initialize Mono."); - return true; - } - - // Log info - char* buildInfo = mono_get_runtime_build_info(); - LOG(Info, "Mono runtime version: {0}", String(buildInfo)); - mono_free(buildInfo); - - return false; -} - -void CoreCLR::ShutdownHostfxr() -{ - mono_jit_cleanup(MonoDomainHandle); - MonoDomainHandle = nullptr; - -#ifdef USE_MONO_AOT_MODULE - Platform::FreeLibrary(MonoAotModuleHandle); -#endif -} - -void* CoreCLR::GetStaticMethodPointer(const String& methodName) -{ - MISSING_CODE("TODO: CoreCLR::GetStaticMethodPointer for Mono host runtime"); - return nullptr; -} - -#endif - -void CoreCLR::RegisterNativeLibrary(const char* moduleName, const char* modulePath) -{ - static void* RegisterNativeLibraryPtr = CoreCLR::GetStaticMethodPointer(TEXT("RegisterNativeLibrary")); - CoreCLR::CallStaticMethod(RegisterNativeLibraryPtr, moduleName, modulePath); -} - -void* CoreCLR::Allocate(int32 size) -{ - static void* AllocMemoryPtr = CoreCLR::GetStaticMethodPointer(TEXT("AllocMemory")); - return CoreCLR::CallStaticMethod(AllocMemoryPtr, size); -} - -void CoreCLR::Free(void* ptr) -{ - if (!ptr) - return; - static void* FreeMemoryPtr = CoreCLR::GetStaticMethodPointer(TEXT("FreeMemory")); - CoreCLR::CallStaticMethod(FreeMemoryPtr, ptr); -} - -#endif diff --git a/Source/Engine/Scripting/DotNet/CoreCLR.h b/Source/Engine/Scripting/DotNet/CoreCLR.h deleted file mode 100644 index b1cc01ab5..000000000 --- a/Source/Engine/Scripting/DotNet/CoreCLR.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#pragma once - -#include "Engine/Core/Types/String.h" -#include "Engine/Core/Collections/Array.h" -#include "Engine/Scripting/Types.h" - -#if USE_NETCORE - -#if defined(_WIN32) -#define CORECLR_DELEGATE_CALLTYPE __stdcall -#define FLAX_CORECLR_STRING String -#define FLAX_CORECLR_TEXT(x) TEXT(x) -#else -#define CORECLR_DELEGATE_CALLTYPE -#define FLAX_CORECLR_STRING StringAnsi -#define FLAX_CORECLR_TEXT(x) x -#endif - -/// -/// .NET Runtime hosting library that uses Hostfxr (https://github.com/dotnet/runtime). -/// -class CoreCLR -{ -public: - static bool InitHostfxr(const String& configPath, const String& libraryPath); - static void ShutdownHostfxr(); - - /// - /// Returns the function pointer to the managed static method in NativeInterop class. - /// - static void* GetStaticMethodPointer(const String& methodName); - - /// - /// Calls the managed static method in NativeInterop class with given parameters. - /// - template - static inline RetType CallStaticMethodByName(const String& methodName, Args... args) - { - typedef RetType(CORECLR_DELEGATE_CALLTYPE* fun)(Args...); - return ((fun)GetStaticMethodPointer(methodName))(args...); - } - - /// - /// Calls the managed static method with given parameters. - /// - template - static inline RetType CallStaticMethod(void* methodPtr, Args... args) - { - typedef RetType(CORECLR_DELEGATE_CALLTYPE* fun)(Args...); - return ((fun)methodPtr)(args...); - } - - static void RegisterNativeLibrary(const char* moduleName, const char* modulePath); - - static const char* GetClassFullname(void* klass); - static void* Allocate(int32 size); - static void Free(void* ptr); - static MGCHandle NewGCHandle(void* obj, bool pinned); - static MGCHandle NewGCHandleWeakref(void* obj, bool track_resurrection); - static void* GetGCHandleTarget(const MGCHandle& handle); - static void FreeGCHandle(const MGCHandle& handle); - - static bool HasCustomAttribute(void* klass, void* attribClass); - static bool HasCustomAttribute(void* klass); - static void* GetCustomAttribute(void* klass, void* attribClass); - static Array GetCustomAttributes(void* klass); -}; - -#endif diff --git a/Source/Engine/Scripting/DotNet/MonoApi.cpp b/Source/Engine/Scripting/DotNet/MonoApi.cpp deleted file mode 100644 index 974cb3de0..000000000 --- a/Source/Engine/Scripting/DotNet/MonoApi.cpp +++ /dev/null @@ -1,1641 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "CoreCLR.h" -#if USE_NETCORE -#include "Engine/Scripting/Types.h" -#include "Engine/Core/Collections/Dictionary.h" -#include "Engine/Graphics/RenderView.h" -#include "Engine/Core/Types/StringBuilder.h" -#include -#include - -#pragma warning(disable : 4297) - -struct CoreCLRClass* GetClass(void* type); -struct CoreCLRClass* GetOrCreateClass(void* type); - -struct _MonoString -{ - int32_t length; - mono_unichar2 chars[MONO_ZERO_LEN_ARRAY]; -}; - -struct CoreCLRAssembly; -struct CoreCLRMethod; -struct CoreCLRField; -struct CoreCLRCustomAttribute; -struct CoreCLRProperty; -struct CoreCLRClass; - -// Structures used to pass information from runtime, must match with the structures in managed side -struct NativeClassDefinitions -{ - void* typeHandle; - const char* name; - const char* fullname; - const char* namespace_; - uint32 typeAttributes; -}; - -struct NativeMethodDefinitions -{ - const char* name; - int numParameters; - void* handle; - uint32 methodAttributes; -}; - -struct NativeFieldDefinitions -{ - const char* name; - void* fieldHandle; - void* fieldType; - uint32 fieldAttributes; -}; - -struct NativePropertyDefinitions -{ - const char* name; - void* getterHandle; - void* setterHandle; - uint32 getterAttributes; - uint32 setterAttributes; -}; - -struct ClassAttribute -{ - const char* name; - void* attributeHandle; - void* attributeTypeHandle; -}; - -Dictionary classHandles; -Dictionary assemblyHandles; -uint32 TypeTokenPool = 0; - -struct CoreCLRAssembly -{ -private: - StringAnsi _name; - StringAnsi _fullname; - Array _classes; - void* _assemblyHandle; - -public: - CoreCLRAssembly(void* assemblyHandle, const char* name, const char* fullname) - { - static void* GetManagedClassesPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetManagedClasses")); - - _assemblyHandle = assemblyHandle; - _name = name; - _fullname = fullname; - - NativeClassDefinitions* managedClasses; - int classCount; - CoreCLR::CallStaticMethod(GetManagedClassesPtr, _assemblyHandle, &managedClasses, &classCount); - for (int i = 0; i < classCount; i++) - { - CoreCLRClass* klass = New(managedClasses[i].typeHandle, StringAnsi(managedClasses[i].name), StringAnsi(managedClasses[i].fullname), StringAnsi(managedClasses[i].namespace_), managedClasses[i].typeAttributes, this); - _classes.Add(klass); - - ASSERT(managedClasses[i].typeHandle != nullptr); - classHandles.Add(managedClasses[i].typeHandle, klass); - - CoreCLR::Free((void*)managedClasses[i].name); - CoreCLR::Free((void*)managedClasses[i].fullname); - CoreCLR::Free((void*)managedClasses[i].namespace_); - } - CoreCLR::Free(managedClasses); - - assemblyHandles.Add(_assemblyHandle, this); - } - - ~CoreCLRAssembly() - { - _classes.ClearDelete(); - assemblyHandles.Remove(_assemblyHandle); - } - - void* GetHandle() const - { - return _assemblyHandle; - } - - const StringAnsi& GetName() const - { - return _name; - } - - const StringAnsi& GetFullname() const - { - return _fullname; - } - - const Array& GetClasses() const - { - return _classes; - } - - void AddClass(CoreCLRClass* klass) - { - _classes.Add(klass); - } -}; - -struct CoreCLRClass -{ -private: - StringAnsi _fullname; - StringAnsi _name; - StringAnsi _namespace; - uint32 _typeAttributes; - CoreCLRAssembly* _image; - uint32 _typeToken; - uint32 _size; - void* _typeHandle; - bool _cachedMethods = false; - Array _methods; - bool _cachedFields = false; - Array _fields; - bool _cachedAttributes = false; - Array _attributes; - bool _cachedProperties = false; - Array _properties; - bool _cachedInterfaces = false; - Array _interfaces; - int _monoType; - -public: - CoreCLRClass(void* typeHandle, StringAnsi&& name, StringAnsi&& fullname, StringAnsi&& namespace_, uint32 typeAttributes, CoreCLRAssembly* image) - : _fullname(MoveTemp(fullname)) - , _name(MoveTemp(name)) - , _namespace(MoveTemp(namespace_)) - , _typeAttributes(typeAttributes) - , _image(image) - , _typeHandle(typeHandle) - { - _typeToken = TypeTokenPool++; - _monoType = 0; - _size = 0; - } - - ~CoreCLRClass() - { - _methods.ClearDelete(); - _fields.ClearDelete(); - _attributes.ClearDelete(); - _properties.ClearDelete(); - _interfaces.Clear(); - - classHandles.Remove(_typeHandle); - } - - uint32 GetAttributes() const - { - return _typeAttributes; - } - - uint32 GetTypeToken() const - { - return _typeToken; - } - - int GetSize() - { - if (_size != 0) - return _size; - uint32 align; - _size = mono_class_value_size((MonoClass*)this, &align); - return _size; - } - - const StringAnsi& GetName() const - { - return _name; - } - - const StringAnsi& GetFullname() const - { - return _fullname; - } - - const StringAnsi& GetNamespace() const - { - return _namespace; - } - - void* GetTypeHandle() const - { - return _typeHandle; - } - - const CoreCLRAssembly* GetAssembly() const - { - return _image; - } - - const Array& GetMethods() - { - if (_cachedMethods) - return _methods; - - static void* GetClassMethodsPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassMethods")); - - NativeMethodDefinitions* foundMethods; - int numMethods; - CoreCLR::CallStaticMethod(GetClassMethodsPtr, _typeHandle, &foundMethods, &numMethods); - for (int i = 0; i < numMethods; i++) - { - CoreCLRMethod* method = New(StringAnsi(foundMethods[i].name), foundMethods[i].numParameters, foundMethods[i].handle, foundMethods[i].methodAttributes, this); - _methods.Add(method); - - CoreCLR::Free((void*)foundMethods[i].name); - } - CoreCLR::Free(foundMethods); - - _cachedMethods = true; - return _methods; - } - - const Array& GetFields() - { - if (_cachedFields) - return _fields; - - static void* GetClassFieldsPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassFields")); - - NativeFieldDefinitions* foundFields; - int numFields; - CoreCLR::CallStaticMethod(GetClassFieldsPtr, _typeHandle, &foundFields, &numFields); - for (int i = 0; i < numFields; i++) - { - CoreCLRField* field = New(StringAnsi(foundFields[i].name), foundFields[i].fieldHandle, foundFields[i].fieldType, foundFields[i].fieldAttributes, this); - _fields.Add(field); - - CoreCLR::Free((void*)foundFields[i].name); - } - CoreCLR::Free(foundFields); - - _cachedFields = true; - return _fields; - } - - const Array& GetProperties() - { - if (_cachedProperties) - return _properties; - - static void* GetClassPropertiesPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassProperties")); - - NativePropertyDefinitions* foundProperties; - int numProperties; - CoreCLR::CallStaticMethod(GetClassPropertiesPtr, _typeHandle, &foundProperties, &numProperties); - for (int i = 0; i < numProperties; i++) - { - const NativePropertyDefinitions& foundProp = foundProperties[i]; - CoreCLRProperty* prop = New(StringAnsi(foundProp.name), foundProp.getterHandle, foundProp.setterHandle, foundProp.getterAttributes, foundProp.setterAttributes, this); - _properties.Add(prop); - - CoreCLR::Free((void*)foundProperties[i].name); - } - CoreCLR::Free(foundProperties); - - _cachedProperties = true; - return _properties; - } - - const Array& GetCustomAttributes() - { - if (_cachedAttributes) - return _attributes; - - static void* GetClassAttributesPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassAttributes")); - - ClassAttribute* foundAttributes; - int numAttributes; - CoreCLR::CallStaticMethod(GetClassAttributesPtr, _typeHandle, &foundAttributes, &numAttributes); - for (int i = 0; i < numAttributes; i++) - { - CoreCLRClass* attributeClass = GetClass(foundAttributes[i].attributeTypeHandle); - CoreCLRCustomAttribute* attribute = New(StringAnsi(foundAttributes[i].name), foundAttributes[i].attributeHandle, this, attributeClass); - _attributes.Add(attribute); - - CoreCLR::Free((void*)foundAttributes[i].name); - } - CoreCLR::Free(foundAttributes); - - _cachedAttributes = true; - return _attributes; - } - - const Array& GetInterfaces() - { - if (_cachedInterfaces) - return _interfaces; - - static void* GetClassInterfacesPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassInterfaces")); - - void** foundInterfaces; - int numInterfaces; - CoreCLR::CallStaticMethod(GetClassInterfacesPtr, _typeHandle, &foundInterfaces, &numInterfaces); - for (int i = 0; i < numInterfaces; i++) - { - CoreCLRClass* interfaceClass = classHandles[foundInterfaces[i]]; - _interfaces.Add(interfaceClass); - } - CoreCLR::Free(foundInterfaces); - - _cachedInterfaces = true; - return _interfaces; - } - - int GetMonoType() - { - if (_monoType == 0) - { - static void* GetTypeMonoTypeEnumPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetTypeMonoTypeEnum")); - _monoType = CoreCLR::CallStaticMethod(GetTypeMonoTypeEnumPtr, _typeHandle); - } - return _monoType; - } -}; - -struct CoreCLRMethod -{ -private: - StringAnsi _name; - int _numParams; - CoreCLRClass* _class; - void* _methodHandle; - bool _cachedParameters = false; - Array _parameterTypes; - void* _returnType; - uint32 _methodAttributes; - -public: - CoreCLRMethod(StringAnsi&& name, int numParams, void* methodHandle, uint32 flags, CoreCLRClass* klass) - : _name(MoveTemp(name)) - , _numParams(numParams) - , _class(klass) - , _methodHandle(methodHandle) - , _methodAttributes(flags) - { - _returnType = nullptr; - } - - const StringAnsi& GetName() const - { - return _name; - } - - const CoreCLRClass* GetClass() const - { - return _class; - } - - uint32 GetAttributes() const - { - return _methodAttributes; - } - - int GetNumParameters() const - { - return _numParams; - } - - void* GetMethodHandle() const - { - return _methodHandle; - } - - const Array& GetParameterTypes() - { - if (!_cachedParameters) - CacheParameters(); - return _parameterTypes; - } - - void* GetReturnType() - { - if (!_cachedParameters) - CacheParameters(); - return _returnType; - } - -private: - void CacheParameters() - { - static void* GetMethodReturnTypePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetMethodReturnType")); - static void* GetMethodParameterTypesPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetMethodParameterTypes")); - - _returnType = CoreCLR::CallStaticMethod(GetMethodReturnTypePtr, _methodHandle); - - void** parameterTypeHandles; - CoreCLR::CallStaticMethod(GetMethodParameterTypesPtr, _methodHandle, ¶meterTypeHandles); - _parameterTypes.Set(parameterTypeHandles, _numParams); - CoreCLR::Free(parameterTypeHandles); - - _cachedParameters = true; - } -}; - -struct CoreCLRField -{ -private: - StringAnsi _name; - CoreCLRClass* _class; - void* _fieldHandle; - void* _fieldType; - uint32 _fieldAttributes; - -public: - CoreCLRField(StringAnsi name, void* fieldHandle, void* fieldType, uint32 fieldAttributes, CoreCLRClass* klass) - :_name(name), _fieldHandle(fieldHandle), _fieldType(fieldType), _fieldAttributes(fieldAttributes), _class(klass) - { - } - - const StringAnsi& GetName() const - { - return _name; - } - - void* GetType() const - { - return _fieldType; - } - - const CoreCLRClass* GetClass() const - { - return _class; - } - - uint32 GetAttributes() const - { - return _fieldAttributes; - } - - void* GetHandle() const - { - return _fieldHandle; - } -}; - -struct CoreCLRProperty -{ -private: - StringAnsi _name; - CoreCLRClass* _class; - CoreCLRMethod* _getMethod; - CoreCLRMethod* _setMethod; - -public: - CoreCLRProperty(StringAnsi&& name, void* getter, void* setter, uint32 getterAttributes, uint32 setterAttributes, CoreCLRClass* klass) - : _name(MoveTemp(name)) - , _class(klass) - { - if (getter != nullptr) - _getMethod = New(StringAnsi(_name + "Get"), 1, getter, getterAttributes, klass); - else - _getMethod = nullptr; - if (setter != nullptr) - _setMethod = New(StringAnsi(_name + "Set"), 1, setter, setterAttributes, klass); - else - _setMethod = nullptr; - } - - const StringAnsi& GetName() const - { - return _name; - } - - const CoreCLRClass* GetClass() const - { - return _class; - } - - const CoreCLRMethod* GetGetMethod() const - { - return _getMethod; - } - - const CoreCLRMethod* GetSetMethod() const - { - return _setMethod; - } -}; - -struct CoreCLRCustomAttribute -{ -private: - StringAnsi _name; - void* _handle; - CoreCLRClass* _owningClass; - CoreCLRClass* _attributeClass; - -public: - CoreCLRCustomAttribute(StringAnsi&& name, void* handle, CoreCLRClass* owningClass, CoreCLRClass* attributeClass) - : _name(MoveTemp(name)) - , _handle(handle) - , _owningClass(owningClass) - , _attributeClass(attributeClass) - { - } - - void* GetHandle() const - { - return _handle; - } - - const CoreCLRClass* GetClass() const - { - return _attributeClass; - } -}; - -CoreCLRAssembly* GetAssembly(void* assemblyHandle) -{ - CoreCLRAssembly* assembly; - if (assemblyHandles.TryGet(assemblyHandle, assembly)) - return assembly; - return nullptr; -} - -CoreCLRClass* GetClass(void* type) -{ - CoreCLRClass* klass = nullptr; - classHandles.TryGet(type, klass); - return nullptr; -} - -CoreCLRClass* GetOrCreateClass(void* type) -{ - CoreCLRClass* klass; - if (!classHandles.TryGet(type, klass)) - { - static void* GetManagedClassFromTypePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetManagedClassFromType")); - - NativeClassDefinitions classInfo; - void* assemblyHandle; - CoreCLR::CallStaticMethod(GetManagedClassFromTypePtr, type, &classInfo, &assemblyHandle); - CoreCLRAssembly* image = GetAssembly(assemblyHandle); - klass = New(classInfo.typeHandle, StringAnsi(classInfo.name), StringAnsi(classInfo.fullname), StringAnsi(classInfo.namespace_), classInfo.typeAttributes, image); - if (image != nullptr) - image->AddClass(klass); - - if (type != classInfo.typeHandle) - CoreCLR::CallStaticMethod(GetManagedClassFromTypePtr, type, &classInfo); - classHandles.Add(classInfo.typeHandle, klass); - - CoreCLR::Free((void*)classInfo.name); - CoreCLR::Free((void*)classInfo.fullname); - CoreCLR::Free((void*)classInfo.namespace_); - } - ASSERT(klass != nullptr); - return klass; -} - -MGCHandle CoreCLR::NewGCHandle(void* obj, bool pinned) -{ - static void* NewGCHandlePtr = CoreCLR::GetStaticMethodPointer(TEXT("NewGCHandle")); - return (MGCHandle)CoreCLR::CallStaticMethod(NewGCHandlePtr, obj, pinned); -} - -MGCHandle CoreCLR::NewGCHandleWeakref(void* obj, bool track_resurrection) -{ - static void* NewGCHandleWeakrefPtr = CoreCLR::GetStaticMethodPointer(TEXT("NewGCHandleWeakref")); - return (MGCHandle)CoreCLR::CallStaticMethod(NewGCHandleWeakrefPtr, obj, track_resurrection); -} - -void* CoreCLR::GetGCHandleTarget(const MGCHandle& handle) -{ - return (void*)handle; -} - -void CoreCLR::FreeGCHandle(const MGCHandle& handle) -{ - static void* FreeGCHandlePtr = CoreCLR::GetStaticMethodPointer(TEXT("FreeGCHandle")); - CoreCLR::CallStaticMethod(FreeGCHandlePtr, (void*)handle); -} - -const char* CoreCLR::GetClassFullname(void* klass) -{ - return ((CoreCLRClass*)klass)->GetFullname().Get(); -} - -bool CoreCLR::HasCustomAttribute(void* klass, void* attribClass) -{ - return CoreCLR::GetCustomAttribute(klass, attribClass) != nullptr; -} - -bool CoreCLR::HasCustomAttribute(void* klass) -{ - return CoreCLR::GetCustomAttribute(klass, nullptr) != nullptr; -} - -void* CoreCLR::GetCustomAttribute(void* klass, void* attribClass) -{ - static void* GetCustomAttributePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetCustomAttribute")); - return CoreCLR::CallStaticMethod(GetCustomAttributePtr, ((CoreCLRClass*)klass)->GetTypeHandle(), ((CoreCLRClass*)attribClass)->GetTypeHandle()); -} - -Array CoreCLR::GetCustomAttributes(void* klass) -{ - const Array& attribs = ((CoreCLRClass*)klass)->GetCustomAttributes(); - Array attributes; - attributes.Resize(attribs.Count(), false); - for (int32 i = 0; i < attribs.Count(); i++) - attributes.Add((MObject*)attribs[i]->GetHandle()); - return attributes; -} - -/* - * loader.h -*/ - -MONO_API MonoMethodSignature* mono_method_signature(MonoMethod* method) -{ - return (MonoMethodSignature*)method; -} - -MONO_API const char* mono_method_get_name(MonoMethod* method) -{ - return ((CoreCLRMethod*)method)->GetName().Get(); -} - -MONO_API MonoClass* mono_method_get_class(MonoMethod* method) -{ - return (MonoClass*)((CoreCLRMethod*)method)->GetClass(); -} - -MONO_API uint32 mono_method_get_flags(MonoMethod* method, uint32* iflags) -{ - return ((CoreCLRMethod*)method)->GetAttributes(); -} - -MONO_API MONO_RT_EXTERNAL_ONLY void mono_add_internal_call(const char* name, const void* method) -{ - // Unused, CoreCRL uses exported symbols linkage via LibraryImport atttribute from C# -} - -/* - * objects.h -*/ - -MONO_API mono_unichar2* mono_string_chars(MonoString* s) -{ - static void* GetStringPointerPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetStringPointer")); - _MonoString* str = (_MonoString*)CoreCLR::CallStaticMethod(GetStringPointerPtr, s); - return str->chars; -} - -MONO_API int mono_string_length(MonoString* s) -{ - static void* GetStringPointerPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetStringPointer")); - _MonoString* str = (_MonoString*)CoreCLR::CallStaticMethod(GetStringPointerPtr, s); - return str->length; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_object_new(MonoDomain* domain, MonoClass* klass) -{ - static void* NewObjectPtr = CoreCLR::GetStaticMethodPointer(TEXT("NewObject")); - return (MonoObject*)CoreCLR::CallStaticMethod(NewObjectPtr, ((CoreCLRClass*)klass)->GetTypeHandle()); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoArray* mono_array_new(MonoDomain* domain, MonoClass* eclass, uintptr_t n) -{ - static void* NewArrayPtr = CoreCLR::GetStaticMethodPointer(TEXT("NewArray")); - return (MonoArray*)CoreCLR::CallStaticMethod(NewArrayPtr, ((CoreCLRClass*)eclass)->GetTypeHandle(), n); -} - -MONO_API char* mono_array_addr_with_size(MonoArray* array, int size, uintptr_t idx) -{ - static void* GetArrayPointerToElementPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetArrayPointerToElement")); - return (char*)CoreCLR::CallStaticMethod(GetArrayPointerToElementPtr, array, size, (int)idx); -} - -MONO_API uintptr_t mono_array_length(MonoArray* array) -{ - static void* GetArrayLengthPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetArrayLength")); - return CoreCLR::CallStaticMethod(GetArrayLengthPtr, array); -} - -MONO_API MonoString* mono_string_empty(MonoDomain* domain) -{ - static void* GetStringEmptyPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetStringEmpty")); - return (MonoString*)CoreCLR::CallStaticMethod(GetStringEmptyPtr); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoString* mono_string_new_utf16(MonoDomain* domain, const mono_unichar2* text, int32_t len) -{ - static void* NewStringUTF16Ptr = CoreCLR::GetStaticMethodPointer(TEXT("NewStringUTF16")); - return (MonoString*)CoreCLR::CallStaticMethod(NewStringUTF16Ptr, text, len); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoString* mono_string_new(MonoDomain* domain, const char* text) -{ - static void* NewStringPtr = CoreCLR::GetStaticMethodPointer(TEXT("NewString")); - return (MonoString*)CoreCLR::CallStaticMethod(NewStringPtr, text); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoString* mono_string_new_len(MonoDomain* domain, const char* text, unsigned int length) -{ - static void* NewStringLengthPtr = CoreCLR::GetStaticMethodPointer(TEXT("NewStringLength")); - return (MonoString*)CoreCLR::CallStaticMethod(NewStringLengthPtr, text, length); -} - -MONO_API MONO_RT_EXTERNAL_ONLY char* mono_string_to_utf8(MonoString* string_obj) -{ - static void* GetStringPointerPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetStringPointer")); - _MonoString* monoString = (_MonoString*)CoreCLR::CallStaticMethod(GetStringPointerPtr, string_obj); - - auto len = monoString->length; - ASSERT(len >= 0) - char* str = (char*)CoreCLR::Allocate(sizeof(char) * (len + 1)); - StringUtils::ConvertUTF162UTF8((Char*)monoString->chars, str, len, len); - str[len] = 0; - - return str; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoString* mono_object_to_string(MonoObject* obj, MonoObject** exc) -{ - ASSERT(false); -} - -MONO_API int mono_object_hash(MonoObject* obj) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_value_box(MonoDomain* domain, MonoClass* klass, void* val) -{ - static void* BoxValuePtr = CoreCLR::GetStaticMethodPointer(TEXT("BoxValue")); - return (MonoObject*)CoreCLR::CallStaticMethod(BoxValuePtr, ((CoreCLRClass*)klass)->GetTypeHandle(), val); -} - -MONO_API void mono_value_copy(void* dest, /*const*/ void* src, MonoClass* klass) -{ - Platform::MemoryCopy(dest, src, ((CoreCLRClass*)klass)->GetSize()); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_object_get_class(MonoObject* obj) -{ - static void* GetObjectTypePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetObjectType")); - void* classHandle = CoreCLR::CallStaticMethod(GetObjectTypePtr, obj); - - CoreCLRClass* klass = GetOrCreateClass((void*)classHandle); - ASSERT(klass != nullptr) - return (MonoClass*)klass; -} - -MONO_API void* mono_object_unbox(MonoObject* obj) -{ - static void* UnboxValuePtr = CoreCLR::GetStaticMethodPointer(TEXT("UnboxValue")); - return CoreCLR::CallStaticMethod(UnboxValuePtr, obj); -} - -MONO_API MONO_RT_EXTERNAL_ONLY void mono_raise_exception(MonoException* ex) -{ - static void* RaiseExceptionPtr = CoreCLR::GetStaticMethodPointer(TEXT("RaiseException")); - CoreCLR::CallStaticMethod(RaiseExceptionPtr, ex); -} - -MONO_API MONO_RT_EXTERNAL_ONLY void mono_runtime_object_init(MonoObject* this_obj) -{ - static void* ObjectInitPtr = CoreCLR::GetStaticMethodPointer(TEXT("ObjectInit")); - CoreCLR::CallStaticMethod(ObjectInitPtr, this_obj); -} - -MONO_API MonoMethod* mono_object_get_virtual_method(MonoObject* obj, MonoMethod* method) -{ - return method; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_runtime_invoke(MonoMethod* method, void* obj, void** params, MonoObject** exc) -{ - static void* InvokeMethodPtr = CoreCLR::GetStaticMethodPointer(TEXT("InvokeMethod")); - return (MonoObject*)CoreCLR::CallStaticMethod(InvokeMethodPtr, obj, ((CoreCLRMethod*)method)->GetMethodHandle(), params, exc); -} - -MONO_API MONO_RT_EXTERNAL_ONLY void* mono_method_get_unmanaged_thunk(MonoMethod* method) -{ - static void* GetMethodUnmanagedFunctionPointerPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetMethodUnmanagedFunctionPointer")); - return CoreCLR::CallStaticMethod(GetMethodUnmanagedFunctionPointerPtr, ((CoreCLRMethod*)method)->GetMethodHandle()); -} - -MONO_API void mono_field_set_value(MonoObject* obj, MonoClassField* field, void* value) -{ - static void* FieldSetValuePtr = CoreCLR::GetStaticMethodPointer(TEXT("FieldSetValue")); - CoreCLR::CallStaticMethod(FieldSetValuePtr, obj, ((CoreCLRField*)field)->GetHandle(), value); -} - -MONO_API void mono_field_get_value(MonoObject* obj, MonoClassField* field, void* value) -{ - static void* FieldGetValuePtr = CoreCLR::GetStaticMethodPointer(TEXT("FieldGetValue")); - CoreCLR::CallStaticMethod(FieldGetValuePtr, obj, ((CoreCLRField*)field)->GetHandle(), value); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_field_get_value_object(MonoDomain* domain, MonoClassField* field, MonoObject* obj) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY void mono_property_set_value(MonoProperty* prop, void* obj, void** params, MonoObject** exc) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_property_get_value(MonoProperty* prop, void* obj, void** params, MonoObject** exc) -{ - ASSERT(false); -} - -MONO_API void mono_gc_wbarrier_set_field(MonoObject* obj, void* field_ptr, MonoObject* value) -{ - CRASH; // Not supported on CoreCRL -} - -MONO_API void mono_gc_wbarrier_set_arrayref(MonoArray* arr, void* slot_ptr, MonoObject* value) -{ - static void* SetArrayValueReferencePtr = CoreCLR::GetStaticMethodPointer(TEXT("SetArrayValueReference")); - CoreCLR::CallStaticMethod(SetArrayValueReferencePtr, arr, slot_ptr, value); -} - -MONO_API void mono_gc_wbarrier_generic_store(void* ptr, MonoObject* value) -{ - // Ignored - *(void**)ptr = value; -} - -MONO_API void mono_gc_wbarrier_value_copy(void* dest, /*const*/ void* src, int count, MonoClass* klass) -{ - // Ignored - int size = ((CoreCLRClass*)klass)->GetSize(); - memcpy(dest, src, count * size); -} - -/* - * appdomain.h -*/ - -MonoDomain* currentDomain = nullptr; - -MONO_API MonoDomain* mono_domain_get(void) -{ - return currentDomain; -} - -MONO_API mono_bool mono_domain_set(MonoDomain* domain, mono_bool force) -{ - currentDomain = domain; - return true; -} - -MONO_API MonoAssembly* mono_domain_assembly_open(MonoDomain* domain, const char* path) -{ - const char* name; - const char* fullname; - static void* LoadAssemblyFromPathPtr = CoreCLR::GetStaticMethodPointer(TEXT("LoadAssemblyFromPath")); - void* assemblyHandle = CoreCLR::CallStaticMethod(LoadAssemblyFromPathPtr, path, &name, &fullname); - CoreCLRAssembly* assembly = New(assemblyHandle, name, fullname); - - CoreCLR::Free((void*)name); - CoreCLR::Free((void*)fullname); - - return (MonoAssembly*)assembly; -} - -static CoreCLRAssembly* corlibimage = nullptr; - -MONO_API MonoImage* mono_get_corlib(void) -{ - if (corlibimage == nullptr) - { - const char* name; - const char* fullname; - static void* GetAssemblyByNamePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetAssemblyByName")); - void* assemblyHandle = CoreCLR::CallStaticMethod(GetAssemblyByNamePtr, "System.Private.CoreLib", &name, &fullname); - corlibimage = New(assemblyHandle, name, fullname); - - CoreCLR::Free((void*)name); - CoreCLR::Free((void*)fullname); - } - - return (MonoImage*)corlibimage; -} - -#define CACHE_CLASS_BY_NAME(name) \ -nullptr; \ -if (klass == nullptr) \ - for (CoreCLRClass* k : corlibimage->GetClasses()) \ - if (k->GetFullname() == name) \ - { \ - klass = k; \ - break; \ - } - -MONO_API MonoClass* mono_get_object_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Object"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_byte_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Byte"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_void_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Void"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_boolean_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Boolean"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_sbyte_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.SByte"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_int16_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Int16"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_uint16_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.UInt16"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_int32_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Int32"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_uint32_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.UInt32"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_intptr_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.IntPtr"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_uintptr_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.UIntPtr"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_int64_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Int64"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_uint64_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.UInt64"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_single_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Single"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_double_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Double"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_char_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.Char"); - return (MonoClass*)klass; -} - -MONO_API MonoClass* mono_get_string_class(void) -{ - static CoreCLRClass* klass = CACHE_CLASS_BY_NAME("System.String"); - return (MonoClass*)klass; -} - -/* - * assembly.h -*/ - -MONO_API MONO_RT_EXTERNAL_ONLY MonoAssembly* mono_assembly_load_from_full(MonoImage* image, const char* fname, MonoImageOpenStatus* status, mono_bool refonly) -{ - auto assembly = (MonoAssembly*)((CoreCLRAssembly*)image); - *status = MONO_IMAGE_OK; - return assembly; -} - -MONO_API void mono_assembly_close(MonoAssembly* assembly) -{ - static void* CloseAssemblyPtr = CoreCLR::GetStaticMethodPointer(TEXT("CloseAssembly")); - CoreCLR::CallStaticMethod(CloseAssemblyPtr, ((CoreCLRAssembly*)assembly)->GetHandle()); - - Delete((CoreCLRAssembly*)assembly); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoImage* mono_assembly_get_image(MonoAssembly* assembly) -{ - return (MonoImage*)((CoreCLRAssembly*)assembly); -} - -/* - * threads.h -*/ - -static MonoThread* notImplMonoThreadValue = New(); - -MONO_API MonoThread* mono_thread_current(void) -{ - // Ignored - return notImplMonoThreadValue; -} - -MONO_API MonoThread* mono_thread_attach(MonoDomain* domain) -{ - // Ignored - return notImplMonoThreadValue; -} - -MONO_API void mono_thread_exit(void) -{ - // Ignored -} - -/* - * reflection.h -*/ - -MONO_API MONO_RT_EXTERNAL_ONLY MonoReflectionAssembly* mono_assembly_get_object(MonoDomain* domain, MonoAssembly* assembly) -{ - static void* GetAssemblyObjectPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetAssemblyObject")); - return (MonoReflectionAssembly*)CoreCLR::CallStaticMethod(GetAssemblyObjectPtr, ((CoreCLRAssembly*)assembly)->GetFullname().Get()); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoReflectionType* mono_type_get_object(MonoDomain* domain, MonoType* type) -{ - return (MonoReflectionType*)type; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoArray* mono_custom_attrs_construct(MonoCustomAttrInfo* cinfo) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoCustomAttrInfo* mono_custom_attrs_from_method(MonoMethod* method) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoCustomAttrInfo* mono_custom_attrs_from_class(MonoClass* klass) -{ - MonoCustomAttrInfo* info = (MonoCustomAttrInfo*)New>(((CoreCLRClass*)klass)->GetCustomAttributes()); - return info; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoCustomAttrInfo* mono_custom_attrs_from_property(MonoClass* klass, MonoProperty* property) -{ - ASSERT(false); -} -MONO_API MONO_RT_EXTERNAL_ONLY MonoCustomAttrInfo* mono_custom_attrs_from_event(MonoClass* klass, MonoEvent* event) -{ - ASSERT(false); -} -MONO_API MONO_RT_EXTERNAL_ONLY MonoCustomAttrInfo* mono_custom_attrs_from_field(MonoClass* klass, MonoClassField* field) -{ - ASSERT(false); -} - -MONO_API mono_bool mono_custom_attrs_has_attr(MonoCustomAttrInfo* ainfo, MonoClass* attr_klass) -{ - Array* attribs = (Array*)ainfo; - for (int i = 0; i < attribs->Count(); i++) - { - CoreCLRCustomAttribute* attrib = attribs->At(i); - if (attrib->GetClass() == (CoreCLRClass*)attr_klass) - return true; - } - return false; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoObject* mono_custom_attrs_get_attr(MonoCustomAttrInfo* ainfo, MonoClass* attr_klass) -{ - Array* attribs = (Array*)ainfo; - for (int i = 0; i < attribs->Count(); i++) - { - CoreCLRCustomAttribute* attrib = attribs->At(i); - if (attrib->GetClass() == (CoreCLRClass*)attr_klass) - { - return (MonoObject*)(attrib)->GetHandle(); - } - } - return nullptr; -} - -MONO_API void mono_custom_attrs_free(MonoCustomAttrInfo* ainfo) -{ - Array* attribs = (Array*)ainfo; - Delete(attribs); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoType* mono_reflection_type_get_type(MonoReflectionType* reftype) -{ - return (MonoType*)reftype; -} - -/* - * class.h -*/ - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_class_get(MonoImage* image, uint32 type_token) -{ - int index = type_token - 0x02000000 - 2; //MONO_TOKEN_TYPE_DEF - auto classes = ((CoreCLRAssembly*)image)->GetClasses(); - return (MonoClass*)classes[index]; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_class_from_name(MonoImage* image, const char* name_space_, const char* name_) -{ - StringAnsi name_space(name_space_); - StringAnsi name(name_); - - for (auto klass : ((CoreCLRAssembly*)image)->GetClasses()) - { - if (klass->GetNamespace() == name_space && klass->GetName() == name) - return (MonoClass*)klass; - } - - return nullptr; -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoMethod* mono_class_inflate_generic_method(MonoMethod* method, MonoGenericContext* context) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_array_class_get(MonoClass* element_class, uint32 rank) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClassField* mono_class_get_field_from_name(MonoClass* klass, const char* name) -{ - for (auto field : ((CoreCLRClass*)klass)->GetFields()) - { - if (field->GetName() == name) - return (MonoClassField*)field; - } - return nullptr; -} - -MONO_API MonoProperty* mono_class_get_property_from_name(MonoClass* klass, const char* name) -{ - for (auto prop : ((CoreCLRClass*)klass)->GetProperties()) - { - if (prop->GetName() == name) - return (MonoProperty*)prop; - } - return nullptr; -} - -MONO_API int32_t mono_class_instance_size(MonoClass* klass) -{ - ASSERT(false); -} - -MONO_API int32_t mono_class_value_size(MonoClass* klass, uint32* align) -{ - static void* NativeSizeOfPtr = CoreCLR::GetStaticMethodPointer(TEXT("NativeSizeOf")); - return CoreCLR::CallStaticMethod(NativeSizeOfPtr, ((CoreCLRClass*)klass)->GetTypeHandle(), align); -} - -MONO_API MonoClass* mono_class_from_mono_type(MonoType* type) -{ - CoreCLRClass* klass = GetOrCreateClass((void*)type); - return (MonoClass*)klass; -} - -MONO_API mono_bool mono_class_is_subclass_of(MonoClass* klass, MonoClass* klassc, mono_bool check_interfaces) -{ - static void* TypeIsSubclassOfPtr = CoreCLR::GetStaticMethodPointer(TEXT("TypeIsSubclassOf")); - return CoreCLR::CallStaticMethod(TypeIsSubclassOfPtr, ((CoreCLRClass*)klass)->GetTypeHandle(), ((CoreCLRClass*)klassc)->GetTypeHandle(), check_interfaces); -} - -MONO_API mono_bool mono_class_is_assignable_from(MonoClass *klass, MonoClass *oklass) -{ - static void* TypeIsAssignableFrom = CoreCLR::GetStaticMethodPointer(TEXT("TypeIsAssignableFrom")); - return CoreCLR::CallStaticMethod(TypeIsAssignableFrom, ((CoreCLRClass*)klass)->GetTypeHandle(), ((CoreCLRClass*)oklass)->GetTypeHandle()); -} - -MONO_API char* mono_type_get_name(MonoType* type) -{ - CoreCLRClass* klass = (CoreCLRClass*)mono_type_get_class(type); - return StringAnsi(klass->GetFullname()).Get(); -} - -MONO_API MonoImage* mono_class_get_image(MonoClass* klass) -{ - return (MonoImage*)((CoreCLRClass*)klass)->GetAssembly(); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_class_get_element_class(MonoClass* klass) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY mono_bool mono_class_is_valuetype(MonoClass* klass) -{ - static void* TypeIsValueTypePtr = CoreCLR::GetStaticMethodPointer(TEXT("TypeIsValueType")); - return (mono_bool)CoreCLR::CallStaticMethod(TypeIsValueTypePtr, ((CoreCLRClass*)klass)->GetTypeHandle()); -} - -MONO_API MONO_RT_EXTERNAL_ONLY mono_bool mono_class_is_enum(MonoClass* klass) -{ - static void* TypeIsEnumPtr = CoreCLR::GetStaticMethodPointer(TEXT("TypeIsEnum")); - return (mono_bool)CoreCLR::CallStaticMethod(TypeIsEnumPtr, ((CoreCLRClass*)klass)->GetTypeHandle()); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClass* mono_class_get_parent(MonoClass* klass) -{ - static void* GetClassParentPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassParent")); - void* parentHandle = CoreCLR::CallStaticMethod(GetClassParentPtr, ((CoreCLRClass*)klass)->GetTypeHandle()); - return (MonoClass*)classHandles[parentHandle]; -} - -MONO_API MonoClass* mono_class_get_nesting_type(MonoClass* klass) -{ - // Ignored - return nullptr; -} - -MONO_API uint32 mono_class_get_flags(MonoClass* klass) -{ - return ((CoreCLRClass*)klass)->GetAttributes(); -} - -MONO_API MONO_RT_EXTERNAL_ONLY const char* mono_class_get_name(MonoClass* klass) -{ - return ((CoreCLRClass*)klass)->GetName().Get(); -} - -MONO_API MONO_RT_EXTERNAL_ONLY const char* mono_class_get_namespace(MonoClass* klass) -{ - return ((CoreCLRClass*)klass)->GetNamespace().Get(); -} - -MONO_API MonoType* mono_class_get_type(MonoClass* klass) -{ - return (MonoType*)((CoreCLRClass*)klass)->GetTypeHandle(); -} - -MONO_API uint32 mono_class_get_type_token(MonoClass* klass) -{ - return ((CoreCLRClass*)klass)->GetTypeToken(); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoClassField* mono_class_get_fields(MonoClass* klass, void** iter) -{ - auto fields = ((CoreCLRClass*)klass)->GetFields(); - uintptr_t index = (uintptr_t)(*iter); - if (index >= 0 && index < fields.Count()) - { - *iter = (void*)(index + 1); - return (MonoClassField*)fields[(int)index]; - } - *iter = nullptr; - return nullptr; -} - -MONO_API MonoMethod* mono_class_get_methods(MonoClass* klass, void** iter) -{ - auto methods = ((CoreCLRClass*)klass)->GetMethods(); - uintptr_t index = (uintptr_t)(*iter); - if (index >= 0 && index < methods.Count()) - { - *iter = (void*)(index + 1); - return (MonoMethod*)methods[(int)index]; - } - *iter = nullptr; - return nullptr; -} - -MONO_API MonoProperty* mono_class_get_properties(MonoClass* klass, void** iter) -{ - auto properties = ((CoreCLRClass*)klass)->GetProperties(); - uintptr_t index = (uintptr_t)(*iter); - if (index >= 0 && index < properties.Count()) - { - *iter = (void*)(index + 1); - return (MonoProperty*)properties[(int)index]; - } - *iter = nullptr; - return nullptr; -} - -MONO_API MonoEvent* mono_class_get_events(MonoClass* klass, void** iter) -{ - ASSERT(false); -} - -MONO_API MonoClass* mono_class_get_interfaces(MonoClass* klass, void** iter) -{ - auto interfaces = ((CoreCLRClass*)klass)->GetInterfaces(); - uintptr_t index = (uintptr_t)(*iter); - if (index >= 0 && index < interfaces.Count()) - { - *iter = (void*)(index + 1); - return (MonoClass*)interfaces[(int)index]; - } - *iter = nullptr; - return nullptr; -} - -MONO_API const char* mono_field_get_name(MonoClassField* field) -{ - return ((CoreCLRField*)field)->GetName().Get(); -} - -MONO_API MonoType* mono_field_get_type(MonoClassField* field) -{ - return (MonoType*)((CoreCLRField*)field)->GetClass()->GetTypeHandle(); -} - -MONO_API MonoClass* mono_field_get_parent(MonoClassField* field) -{ - ASSERT(false); -} - -MONO_API uint32 mono_field_get_flags(MonoClassField* field) -{ - return ((CoreCLRField*)field)->GetAttributes(); -} - -MONO_API uint32 mono_field_get_offset(MonoClassField* field) -{ - ASSERT(false); -} - -MONO_API const char* mono_property_get_name(MonoProperty* prop) -{ - return ((CoreCLRProperty*)prop)->GetName().Get(); -} - -MONO_API MonoMethod* mono_property_get_set_method(MonoProperty* prop) -{ - return (MonoMethod*)((CoreCLRProperty*)prop)->GetSetMethod(); -} - -MONO_API MonoMethod* mono_property_get_get_method(MonoProperty* prop) -{ - return (MonoMethod*)((CoreCLRProperty*)prop)->GetGetMethod(); -} - -MONO_API MonoClass* mono_property_get_parent(MonoProperty* prop) -{ - return (MonoClass*)((CoreCLRProperty*)prop)->GetClass(); -} - -MONO_API const char* mono_event_get_name(MonoEvent* event) -{ - ASSERT(false); -} - -MONO_API MonoMethod* mono_event_get_add_method(MonoEvent* event) -{ - ASSERT(false); -} - -MONO_API MonoMethod* mono_event_get_remove_method(MonoEvent* event) -{ - ASSERT(false); -} - -MONO_API MonoClass* mono_event_get_parent(MonoEvent* event) -{ - ASSERT(false); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoMethod* mono_class_get_method_from_name(MonoClass* klass, const char* name, int param_count) -{ - for (CoreCLRMethod* method : ((CoreCLRClass*)klass)->GetMethods()) - { - if (method->GetName() == name && method->GetNumParameters() == param_count) - return (MonoMethod*)method; - } - - return nullptr; -} - -/* - * mono-publib.h -*/ - -MONO_API void mono_free(void* ptr) -{ - CoreCLR::Free(ptr); -} - -/* - * metadata.h -*/ - -MONO_API mono_bool mono_type_is_byref(MonoType* type) -{ - ASSERT(false); -} - -MONO_API int mono_type_get_type(MonoType* type) -{ - CoreCLRClass* klass = GetOrCreateClass((void*)type); - return klass->GetMonoType(); -} - -MONO_API MonoClass* mono_type_get_class(MonoType* type) -{ - return (MonoClass*)classHandles[(void*)type]; -} - -MONO_API mono_bool mono_type_is_struct(MonoType* type) -{ - ASSERT(false); -} - -MONO_API mono_bool mono_type_is_void(MonoType* type) -{ - ASSERT(false); -} - -MONO_API mono_bool mono_type_is_pointer(MonoType* type) -{ - ASSERT(false); -} - -MONO_API mono_bool mono_type_is_reference(MonoType* type) -{ - ASSERT(false); -} - -MONO_API MonoType* mono_signature_get_return_type(MonoMethodSignature* sig) -{ - return (MonoType*)((CoreCLRMethod*)sig)->GetReturnType(); -} - -MONO_API MonoType* mono_signature_get_params(MonoMethodSignature* sig, void** iter) -{ - auto parameterTypes = ((CoreCLRMethod*)sig)->GetParameterTypes(); - uintptr_t index = (uintptr_t)(*iter); - if (index >= 0 && index < parameterTypes.Count()) - { - *iter = (void*)(index+1); - return (MonoType*)parameterTypes[(int)index]; - } - *iter = nullptr; - return nullptr; -} - -MONO_API uint32 mono_signature_get_param_count(MonoMethodSignature* sig) -{ - return ((CoreCLRMethod*)sig)->GetNumParameters(); -} - -MONO_API mono_bool mono_signature_param_is_out(MonoMethodSignature* sig, int param_num) -{ - static void* GetMethodParameterIsOutPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetMethodParameterIsOut")); - return CoreCLR::CallStaticMethod(GetMethodParameterIsOutPtr, ((CoreCLRMethod*)sig)->GetMethodHandle(), param_num); -} - -MONO_API int mono_type_stack_size(MonoType* type, int* alignment) -{ - ASSERT(false); -} - -/* - * exception.h -*/ - -MONO_API MonoException* mono_exception_from_name_msg(MonoImage* image, const char* name_space, const char* name, const char* msg) -{ - ASSERT(false); -} - -MONO_API MonoException* mono_get_exception_null_reference(void) -{ - static void* GetNullReferenceExceptionPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetNullReferenceException")); - return (MonoException*)CoreCLR::CallStaticMethod(GetNullReferenceExceptionPtr); -} - -MONO_API MonoException* mono_get_exception_not_supported(const char* msg) -{ - static void* GetNotSupportedExceptionPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetNotSupportedException")); - return (MonoException*)CoreCLR::CallStaticMethod(GetNotSupportedExceptionPtr); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoException* mono_get_exception_argument_null(const char* arg) -{ - static void* GetArgumentNullExceptionPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetArgumentNullException")); - return (MonoException*)CoreCLR::CallStaticMethod(GetArgumentNullExceptionPtr); -} - -MONO_API MonoException* mono_get_exception_argument(const char* arg, const char* msg) -{ - static void* GetArgumentExceptionPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetArgumentException")); - return (MonoException*)CoreCLR::CallStaticMethod(GetArgumentExceptionPtr); -} - -MONO_API MONO_RT_EXTERNAL_ONLY MonoException* mono_get_exception_argument_out_of_range(const char* arg) -{ - static void* GetArgumentOutOfRangeExceptionPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetArgumentOutOfRangeException")); - return (MonoException*)CoreCLR::CallStaticMethod(GetArgumentOutOfRangeExceptionPtr); -} - -/* - * image.h -*/ - -MONO_API MONO_RT_EXTERNAL_ONLY MonoImage* mono_image_open_from_data_with_name(char* data, uint32 data_len, mono_bool need_copy, MonoImageOpenStatus* status, mono_bool refonly, const char* path) -{ - const char* name; - const char* fullname; - static void* LoadAssemblyImagePtr = CoreCLR::GetStaticMethodPointer(TEXT("LoadAssemblyImage")); - void* assemblyHandle = CoreCLR::CallStaticMethod(LoadAssemblyImagePtr, data, data_len, path, &name, &fullname); - if (!assemblyHandle) - { - *status = MONO_IMAGE_IMAGE_INVALID; - return nullptr; - } - CoreCLRAssembly* assembly = New(assemblyHandle, name, fullname); - - CoreCLR::Free((void*)name); - CoreCLR::Free((void*)fullname); - - *status = MONO_IMAGE_OK; - return (MonoImage*)assembly; -} - -MONO_API void mono_image_close(MonoImage* image) -{ - // Ignored -} -MONO_API const char* mono_image_get_name(MonoImage* image) -{ - return ((CoreCLRAssembly*)image)->GetName().Get(); -} -MONO_API MonoAssembly* mono_image_get_assembly(MonoImage* image) -{ - return (MonoAssembly*)image; -} -MONO_API int mono_image_get_table_rows(MonoImage* image, int table_id) -{ - return ((CoreCLRAssembly*)image)->GetClasses().Count() + 1; -} - -/* - * mono-gc.h -*/ - -MONO_API void mono_gc_collect(int generation) -{ - // Ignored -} - -MONO_API int mono_gc_max_generation(void) -{ - // Ignored - return 0; -} - -MONO_API MonoBoolean mono_gc_pending_finalizers(void) -{ - // Ignored - return false; -} - -MONO_API void mono_gc_finalize_notify(void) -{ - // Ignored -} - -#pragma warning(default : 4297) - -#endif diff --git a/Source/Engine/Scripting/Scripting.Internal.cpp b/Source/Engine/Scripting/Internal/EngineInternalCalls.cpp similarity index 50% rename from Source/Engine/Scripting/Scripting.Internal.cpp rename to Source/Engine/Scripting/Internal/EngineInternalCalls.cpp index 02e2c0835..27bb8aa47 100644 --- a/Source/Engine/Scripting/Scripting.Internal.cpp +++ b/Source/Engine/Scripting/Internal/EngineInternalCalls.cpp @@ -1,24 +1,97 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. -#include "Scripting.h" -#include "ScriptingType.h" -#include "FlaxEngine.Gen.h" -#include "Engine/Scripting/InternalCalls.h" +#include "Engine/Platform/Platform.h" +#include "Engine/Animations/Graph/AnimGraph.h" +#include "Engine/Scripting/Scripting.h" +#include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Scripting/ManagedCLR/MAssembly.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" +#if USE_MONO +#include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MField.h" +#endif +#include "Engine/Scripting/Internal/InternalCalls.h" #include "Engine/Core/ObjectsRemovalService.h" #include "Engine/Profiler/Profiler.h" +#include "FlaxEngine.Gen.h" #if TRACY_ENABLE && !PROFILE_CPU_USE_TRANSIENT_DATA #include "Engine/Core/Collections/ChunkedArray.h" #endif -#include "Engine/Core/Types/Pair.h" #include "Engine/Threading/Threading.h" -#if USE_MONO -#include -#endif + +#if !COMPILE_WITHOUT_CSHARP #if USE_MONO +DEFINE_INTERNAL_CALL(MObject*) UtilsInternal_ExtractArrayFromList(MObject* obj) +{ + MClass* klass = MCore::Object::GetClass(obj); + MField* field = klass->GetField("_items"); + MObject* o; + field->GetValue(obj, &o); + return o; +} +#endif + +DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryCopy(void* dst, const void* src, uint64 size) +{ + Platform::MemoryCopy(dst, src, size); +} + +DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryClear(void* dst, uint64 size) +{ + Platform::MemoryClear(dst, size); +} + +DEFINE_INTERNAL_CALL(int32) PlatformInternal_MemoryCompare(const void* buf1, const void* buf2, uint64 size) +{ + return Platform::MemoryCompare(buf1, buf2, size); +} + +DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, MString* msgObj) +{ + StringView msg; + MUtils::ToString(msgObj, msg); + Log::Logger::Write(level, msg); +} + +DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MString* msgObj, ScriptingObject* obj, MString* stackTrace) +{ + if (msgObj == nullptr) + return; + + // Get info + StringView msg; + MUtils::ToString(msgObj, msg); + //const String objName = obj ? obj->ToString() : String::Empty; + + // Send event + // TODO: maybe option for build to threat warnings and errors as fatal errors? + //const String logMessage = String::Format(TEXT("Debug:{1} {2}"), objName, *msg); + Log::Logger::Write(level, msg); +} + +DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogException(MObject* exception, ScriptingObject* obj) +{ +#if USE_CSHARP + if (exception == nullptr) + return; + + // Get info + MException ex(exception); + const String objName = obj ? obj->ToString() : String::Empty; + + // Print exception including inner exceptions + // TODO: maybe option for build to threat warnings and errors as fatal errors? + ex.Log(LogType::Warning, objName.GetText()); +#endif +} + +#endif + +#if USE_CSHARP namespace { @@ -39,10 +112,11 @@ namespace #endif } -DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(MonoString* nameObj) +DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(MString* nameObj) { #if COMPILE_WITH_PROFILER - const StringView name((const Char*)mono_string_chars(nameObj), mono_string_length(nameObj)); + StringView name; + MUtils::ToString(nameObj, name); ProfilerCPU::BeginEvent(*name); #if TRACY_ENABLE #if PROFILE_CPU_USE_TRANSIENT_DATA @@ -87,10 +161,11 @@ DEFINE_INTERNAL_CALL(void) ProfilerInternal_EndEvent() #endif } -DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(MonoString* nameObj) +DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(MString* nameObj) { #if COMPILE_WITH_PROFILER - const auto index = ProfilerGPU::BeginEvent((const Char*)mono_string_chars(nameObj)); + const StringView nameChars = MCore::String::GetChars(nameObj); + const auto index = ProfilerGPU::BeginEvent(nameChars.Get()); ManagedEventsGPU.Push(index); #endif } @@ -108,9 +183,9 @@ DEFINE_INTERNAL_CALL(bool) ScriptingInternal_HasGameModulesLoaded() return Scripting::HasGameModulesLoaded(); } -DEFINE_INTERNAL_CALL(bool) ScriptingInternal_IsTypeFromGameScripts(MonoReflectionType* type) +DEFINE_INTERNAL_CALL(bool) ScriptingInternal_IsTypeFromGameScripts(MTypeObject* type) { - return Scripting::IsTypeFromGameScripts(Scripting::FindClass(MUtils::GetClass(type))); + return Scripting::IsTypeFromGameScripts(MUtils::GetClass(INTERNAL_TYPE_OBJECT_GET(type))); } DEFINE_INTERNAL_CALL(void) ScriptingInternal_FlushRemovedObjects() @@ -121,6 +196,22 @@ DEFINE_INTERNAL_CALL(void) ScriptingInternal_FlushRemovedObjects() #endif +void registerFlaxEngineInternalCalls() +{ + AnimGraphExecutor::initRuntime(); +#if USE_CSHARP + ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCopy", &PlatformInternal_MemoryCopy); + ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryClear", &PlatformInternal_MemoryClear); + ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCompare", &PlatformInternal_MemoryCompare); +#if USE_MONO + ADD_INTERNAL_CALL("FlaxEngine.Utils::Internal_ExtractArrayFromList", &UtilsInternal_ExtractArrayFromList); +#endif + ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogWrite", &DebugLogHandlerInternal_LogWrite); + ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal_Log); + ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal_LogException); +#endif +} + class ScriptingInternal { public: diff --git a/Source/Engine/Scripting/InternalCalls.h b/Source/Engine/Scripting/Internal/InternalCalls.h similarity index 96% rename from Source/Engine/Scripting/InternalCalls.h rename to Source/Engine/Scripting/Internal/InternalCalls.h index b867ee5c0..f602cab50 100644 --- a/Source/Engine/Scripting/InternalCalls.h +++ b/Source/Engine/Scripting/Internal/InternalCalls.h @@ -2,10 +2,10 @@ #pragma once -#include "Engine/Debug/DebugLog.h" #include "Engine/Core/Log.h" -#include "ScriptingType.h" -#include "Types.h" +#include "Engine/Debug/DebugLog.h" +#include "Engine/Scripting/ScriptingType.h" +#include "Engine/Scripting/Types.h" #if defined(__clang__) // Helper utility to override vtable entry with automatic restore @@ -33,7 +33,7 @@ struct FLAXENGINE_API VTableFunctionInjector #define MSVC_FUNC_EXPORT(name) __pragma(comment(linker, "/EXPORT:" #name "=" __FUNCDNAME__)) #endif -#if USE_MONO +#if USE_CSHARP #if USE_NETCORE #define ADD_INTERNAL_CALL(fullName, method) diff --git a/Source/Engine/Scripting/MainThreadManagedInvokeAction.cpp b/Source/Engine/Scripting/Internal/MainThreadManagedInvokeAction.cpp similarity index 98% rename from Source/Engine/Scripting/MainThreadManagedInvokeAction.cpp rename to Source/Engine/Scripting/Internal/MainThreadManagedInvokeAction.cpp index db2bfb4a8..0854b620e 100644 --- a/Source/Engine/Scripting/MainThreadManagedInvokeAction.cpp +++ b/Source/Engine/Scripting/Internal/MainThreadManagedInvokeAction.cpp @@ -3,7 +3,7 @@ #include "MainThreadManagedInvokeAction.h" #include "Engine/Threading/Threading.h" #include "Engine/Scripting/ScriptingCalls.h" -#include "MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" MainThreadManagedInvokeAction* MainThreadManagedInvokeAction::Invoke(MMethod* method, MObject* instance, LogType exceptionLevel) { diff --git a/Source/Engine/Scripting/MainThreadManagedInvokeAction.h b/Source/Engine/Scripting/Internal/MainThreadManagedInvokeAction.h similarity index 92% rename from Source/Engine/Scripting/MainThreadManagedInvokeAction.h rename to Source/Engine/Scripting/Internal/MainThreadManagedInvokeAction.h index a7924c76b..4b844b61d 100644 --- a/Source/Engine/Scripting/MainThreadManagedInvokeAction.h +++ b/Source/Engine/Scripting/Internal/MainThreadManagedInvokeAction.h @@ -4,8 +4,8 @@ #include "Engine/Threading/MainThreadTask.h" #include "Engine/Core/Log.h" -#include "ManagedCLR/MMethod.h" -#include "ManagedCLR/MUtils.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" +#include "Engine/Scripting/ManagedCLR/MUtils.h" /// /// Helper class for easy invoking managed code on main thread before all game systems update. @@ -71,28 +71,28 @@ public: AddParam(val); } -#if USE_MONO +#if USE_CSHARP FORCE_INLINE void AddParam(const String& value) { - MonoString* val = MUtils::ToString(value); + MString* val = MUtils::ToString(value); AddParam(val); } FORCE_INLINE void AddParam(const StringView& value) { - MonoString* val = MUtils::ToString(value); + MString* val = MUtils::ToString(value); AddParam(val); } - FORCE_INLINE void AddParam(const String& value, MonoDomain* domain) + FORCE_INLINE void AddParam(const String& value, MDomain* domain) { - MonoString* val = MUtils::ToString(value, domain); + MString* val = MUtils::ToString(value, domain); AddParam(val); } - FORCE_INLINE void AddParam(const StringView& value, MonoDomain* domain) + FORCE_INLINE void AddParam(const StringView& value, MDomain* domain) { - MonoString* val = MUtils::ToString(value, domain); + MString* val = MUtils::ToString(value, domain); AddParam(val); } #endif diff --git a/Source/Engine/Scripting/InternalCalls/ManagedBitArray.h b/Source/Engine/Scripting/Internal/ManagedBitArray.h similarity index 69% rename from Source/Engine/Scripting/InternalCalls/ManagedBitArray.h rename to Source/Engine/Scripting/Internal/ManagedBitArray.h index 79818a9c3..ec4227378 100644 --- a/Source/Engine/Scripting/InternalCalls/ManagedBitArray.h +++ b/Source/Engine/Scripting/Internal/ManagedBitArray.h @@ -2,16 +2,9 @@ #pragma once -#include "Engine/Core/Log.h" #include "Engine/Core/Collections/BitArray.h" -#include "Engine/Scripting/ManagedCLR/MAssembly.h" -#include "Engine/Scripting/ManagedCLR/MClass.h" -#include "Engine/Scripting/ManagedCLR/MField.h" -#include "Engine/Scripting/BinaryModule.h" -#if USE_MONO -#include -#include -#include +#include "Engine/Scripting/ManagedCLR/MCore.h" +#if USE_CSHARP struct ManagedBitArray { @@ -26,7 +19,7 @@ struct ManagedBitArray MonoMethod* bitArrayCtor = mono_method_desc_search_in_class(desc, bitArrayClass->GetNative()); mono_method_desc_free(desc); CHECK_RETURN(bitArrayCtor, nullptr); - MonoObject* instance = mono_object_new(mono_domain_get(), bitArrayClass->GetNative()); + MObject* instance = MCore::Object::New(bitArrayClass); CHECK_RETURN(instance, nullptr); int32 length = data.Count(); void* params[1]; @@ -34,10 +27,10 @@ struct ManagedBitArray mono_runtime_invoke(bitArrayCtor, instance, params, nullptr); const MField* arrayField = bitArrayClass->GetField("m_array"); CHECK_RETURN(arrayField, nullptr); - MonoArray* array = nullptr; + MArray* array = nullptr; arrayField->GetValue(instance, &array); CHECK_RETURN(array, nullptr); - const int32 arrayLength = mono_array_length(array); + const int32 arrayLength = MCore::Array::GetLength(array); //mono_value_copy_array(array, 0, (void*)data.Get(), arrayLength); int32* arrayPtr = mono_array_addr(array, int32, 0); //Platform::MemoryCopy(mono_array_addr_with_size(array, sizeof(int32), 0), data.Get(), data.Count() / sizeof(byte)); @@ -45,12 +38,11 @@ struct ManagedBitArray return instance; #else // Convert into bool[] - MonoArray* array = mono_array_new(mono_domain_get(), mono_get_boolean_class(), data.Count()); + MArray* array = MCore::Array::New(MCore::TypeCache::Boolean, data.Count()); + bool* arrayPtr = MCore::Array::GetAddress(array); for (int32 i = 0; i < data.Count(); i++) - { - mono_array_set(array, bool, i, data[i]); - } - return (MonoObject*)array; + arrayPtr[i] = data[i]; + return (MObject*)array; #endif } }; diff --git a/Source/Engine/Scripting/InternalCalls/ManagedDictionary.h b/Source/Engine/Scripting/Internal/ManagedDictionary.h similarity index 50% rename from Source/Engine/Scripting/InternalCalls/ManagedDictionary.h rename to Source/Engine/Scripting/Internal/ManagedDictionary.h index f7535872c..f2e638115 100644 --- a/Source/Engine/Scripting/InternalCalls/ManagedDictionary.h +++ b/Source/Engine/Scripting/Internal/ManagedDictionary.h @@ -4,40 +4,39 @@ #include "Engine/Core/Log.h" #include "Engine/Scripting/Scripting.h" -#include "Engine/Scripting/StdTypesContainer.h" +#if USE_CSHARP #include "Engine/Scripting/BinaryModule.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" #include "Engine/Scripting/ManagedCLR/MAssembly.h" -#include "Engine/Scripting/MException.h" -#if USE_MONO -#include +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/Internal/StdTypesContainer.h" /// /// Utility interop between C++ and C# for Dictionary collection. /// struct FLAXENGINE_API ManagedDictionary { - MonoObject* Instance; + MObject* Instance; - ManagedDictionary(MonoObject* instance = nullptr) + ManagedDictionary(MObject* instance = nullptr) { Instance = instance; } template - static MonoObject* ToManaged(const Dictionary& data, MonoType* keyType, MonoType* valueType) + static MObject* ToManaged(const Dictionary& data, MType* keyType, MType* valueType) { MConverter keysConverter; MConverter valueConverter; ManagedDictionary result = New(keyType, valueType); - MonoClass* keyClass = mono_type_get_class(keyType); - MonoClass* valueClass = mono_type_get_class(valueType); + MClass* keyClass = MCore::Type::GetClass(keyType); + MClass* valueClass = MCore::Type::GetClass(valueType); for (auto i = data.Begin(); i.IsNotEnd(); ++i) { - MonoObject* keyManaged = keysConverter.Box(i->Key, keyClass); - MonoObject* valueManaged = valueConverter.Box(i->Value, valueClass); + MObject* keyManaged = keysConverter.Box(i->Key, keyClass); + MObject* valueManaged = valueConverter.Box(i->Value, valueClass); result.Add(keyManaged, valueManaged); } return result.Instance; @@ -49,82 +48,78 @@ struct FLAXENGINE_API ManagedDictionary /// The managed dictionary object. /// The output array. template - static Dictionary ToNative(MonoObject* managed) + static Dictionary ToNative(MObject* managed) { Dictionary result; const ManagedDictionary wrapper(managed); - MonoArray* managedKeys = wrapper.GetKeys(); - auto length = managedKeys ? (int32)mono_array_length(managedKeys) : 0; + MArray* managedKeys = wrapper.GetKeys(); + int32 length = managedKeys ? MCore::Array::GetLength(managedKeys) : 0; Array keys; keys.Resize(length); result.EnsureCapacity(length); MConverter keysConverter; - for (int32 i = 0; i < keys.Count(); i++) - { - auto& key = keys[i]; - MonoObject* keyManaged = mono_array_get(managedKeys, MonoObject*, i); - keysConverter.Unbox(key, keyManaged); - } MConverter valueConverter; + MObject** managedKeysPtr = MCore::Array::GetAddress(managedKeys); for (int32 i = 0; i < keys.Count(); i++) { - auto& key = keys[i]; - MonoObject* keyManaged = mono_array_get(managedKeys, MonoObject*, i); - MonoObject* valueManaged = wrapper.GetValue(keyManaged); - auto& value = result[key]; + KeyType& key = keys[i]; + MObject* keyManaged = managedKeysPtr[i]; + keysConverter.Unbox(key, keyManaged); + MObject* valueManaged = wrapper.GetValue(keyManaged); + ValueType& value = result[key]; valueConverter.Unbox(value, valueManaged); } return result; } - static MonoReflectionType* GetClass(MonoType* keyType, MonoType* valueType) + static MTypeObject* GetClass(MType* keyType, MType* valueType) { - auto domain = mono_domain_get(); - auto scriptingClass = Scripting::GetStaticClass(); + MClass* scriptingClass = Scripting::GetStaticClass(); CHECK_RETURN(scriptingClass, nullptr); - auto makeGenericMethod = scriptingClass->GetMethod("MakeGenericType", 2); + MMethod* makeGenericMethod = scriptingClass->GetMethod("MakeGenericType", 2); CHECK_RETURN(makeGenericMethod, nullptr); - auto genericType = MUtils::GetType(StdTypesContainer::Instance()->DictionaryClass->GetNative()); + MTypeObject* genericType = MUtils::GetType(StdTypesContainer::Instance()->DictionaryClass); #if USE_NETCORE - auto genericArgs = mono_array_new(domain, mono_get_intptr_class(), 2); + MArray* genericArgs = MCore::Array::New(MCore::TypeCache::IntPtr, 2); #else - auto genericArgs = mono_array_new(domain, mono_get_object_class(), 2); + MArray* genericArgs = MCore::Array::New(MCore::TypeCache::Object, 2); #endif - mono_array_set(genericArgs, MonoReflectionType*, 0, mono_type_get_object(domain, keyType)); - mono_array_set(genericArgs, MonoReflectionType*, 1, mono_type_get_object(domain, valueType)); + MTypeObject** genericArgsPtr = MCore::Array::GetAddress(genericArgs); + genericArgsPtr[0] = INTERNAL_TYPE_GET_OBJECT(keyType); + genericArgsPtr[1] = INTERNAL_TYPE_GET_OBJECT(valueType); void* params[2]; params[0] = genericType; params[1] = genericArgs; MObject* exception = nullptr; - auto dictionaryType = makeGenericMethod->Invoke(nullptr, params, &exception); + MObject* dictionaryType = makeGenericMethod->Invoke(nullptr, params, &exception); if (exception) { MException ex(exception); ex.Log(LogType::Error, TEXT("")); return nullptr; } - return (MonoReflectionType*)dictionaryType; + return (MTypeObject*)dictionaryType; } - static ManagedDictionary New(MonoType* keyType, MonoType* valueType) + static ManagedDictionary New(MType* keyType, MType* valueType) { ManagedDictionary result; - auto dictionaryType = GetClass(keyType, valueType); + MTypeObject* dictionaryType = GetClass(keyType, valueType); if (!dictionaryType) return result; - auto scriptingClass = Scripting::GetStaticClass(); + MClass* scriptingClass = Scripting::GetStaticClass(); CHECK_RETURN(scriptingClass, result); - auto createMethod = StdTypesContainer::Instance()->ActivatorClass->GetMethod("CreateInstance", 2); + MMethod* createMethod = StdTypesContainer::Instance()->ActivatorClass->GetMethod("CreateInstance", 2); CHECK_RETURN(createMethod, result); MObject* exception = nullptr; void* params[2]; params[0] = dictionaryType; params[1] = nullptr; - auto instance = createMethod->Invoke(nullptr, params, &exception); + MObject* instance = createMethod->Invoke(nullptr, params, &exception); if (exception) { MException ex(exception); @@ -136,19 +131,19 @@ struct FLAXENGINE_API ManagedDictionary return result; } - void Add(MonoObject* key, MonoObject* value) + void Add(MObject* key, MObject* value) { CHECK(Instance); - auto scriptingClass = Scripting::GetStaticClass(); + MClass* scriptingClass = Scripting::GetStaticClass(); CHECK(scriptingClass); - auto addDictionaryItemMethod = scriptingClass->GetMethod("AddDictionaryItem", 3); + MMethod* addDictionaryItemMethod = scriptingClass->GetMethod("AddDictionaryItem", 3); CHECK(addDictionaryItemMethod); void* params[3]; params[0] = Instance; params[1] = key; params[2] = value; MObject* exception = nullptr; - mono_runtime_invoke(addDictionaryItemMethod->GetNative(), Instance, params, &exception); + addDictionaryItemMethod->Invoke(Instance, params, &exception); if (exception) { MException ex(exception); @@ -156,27 +151,27 @@ struct FLAXENGINE_API ManagedDictionary } } - MonoArray* GetKeys() const + MArray* GetKeys() const { CHECK_RETURN(Instance, nullptr); - auto scriptingClass = Scripting::GetStaticClass(); + MClass* scriptingClass = Scripting::GetStaticClass(); CHECK_RETURN(scriptingClass, nullptr); - auto getDictionaryKeysMethod = scriptingClass->GetMethod("GetDictionaryKeys", 1); + MMethod* getDictionaryKeysMethod = scriptingClass->GetMethod("GetDictionaryKeys", 1); CHECK_RETURN(getDictionaryKeysMethod, nullptr); void* params[1]; params[0] = Instance; - return (MonoArray*)mono_runtime_invoke(getDictionaryKeysMethod->GetNative(), nullptr, params, nullptr); + return (MArray*)getDictionaryKeysMethod->Invoke( nullptr, params, nullptr); } - MonoObject* GetValue(MonoObject* key) const + MObject* GetValue(MObject* key) const { CHECK_RETURN(Instance, nullptr); - auto klass = mono_object_get_class(Instance); - auto getItemMethod = mono_class_get_method_from_name(klass, "System.Collections.IDictionary.get_Item", 1); + MClass* klass = MCore::Object::GetClass(Instance); + MMethod* getItemMethod = klass->GetMethod("System.Collections.IDictionary.get_Item", 1); CHECK_RETURN(getItemMethod, nullptr); void* params[1]; params[0] = key; - return mono_runtime_invoke(getItemMethod, Instance, params, nullptr); + return getItemMethod->Invoke(Instance, params, nullptr); } }; diff --git a/Source/Engine/Scripting/ManagedSerialization.cpp b/Source/Engine/Scripting/Internal/ManagedSerialization.cpp similarity index 80% rename from Source/Engine/Scripting/ManagedSerialization.cpp rename to Source/Engine/Scripting/Internal/ManagedSerialization.cpp index 3ff1f5bb9..f1543a326 100644 --- a/Source/Engine/Scripting/ManagedSerialization.cpp +++ b/Source/Engine/Scripting/Internal/ManagedSerialization.cpp @@ -1,14 +1,14 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "ManagedSerialization.h" -#if USE_MONO +#if USE_CSHARP #include "Engine/Core/Log.h" #include "Engine/Serialization/Json.h" #include "Engine/Serialization/JsonWriter.h" -#include "StdTypesContainer.h" -#include "MException.h" -#include "ManagedCLR/MMethod.h" -#include +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" +#include "Engine/Scripting/Internal/StdTypesContainer.h" void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MObject* object) { @@ -29,7 +29,7 @@ void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MOb // Call serialization tool MObject* exception = nullptr; // TODO: use method thunk - auto invokeResultStr = (MonoString*)StdTypesContainer::Instance()->Json_Serialize->Invoke(nullptr, params, &exception); + auto invokeResultStr = (MString*)StdTypesContainer::Instance()->Json_Serialize->Invoke(nullptr, params, &exception); if (exception) { MException ex(exception); @@ -42,9 +42,7 @@ void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MOb } // Write result data - const auto invokeResultChars = mono_string_to_utf8(invokeResultStr); - stream.RawValue(invokeResultChars); - mono_free(invokeResultChars); + stream.RawValue(MCore::String::GetChars(invokeResultStr)); } void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, MObject* object, MObject* other) @@ -67,7 +65,7 @@ void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, // Call serialization tool MObject* exception = nullptr; // TODO: use method thunk - auto invokeResultStr = (MonoString*)StdTypesContainer::Instance()->Json_SerializeDiff->Invoke(nullptr, params, &exception); + auto invokeResultStr = (MString*)StdTypesContainer::Instance()->Json_SerializeDiff->Invoke(nullptr, params, &exception); if (exception) { MException ex(exception); @@ -80,9 +78,7 @@ void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, } // Write result data - auto invokeResultChars = mono_string_to_utf8(invokeResultStr); - stream.RawValue(invokeResultChars); - mono_free(invokeResultChars); + stream.RawValue(MCore::String::GetChars(invokeResultStr)); } void ManagedSerialization::Deserialize(ISerializable::DeserializeStream& stream, MObject* object) diff --git a/Source/Engine/Scripting/ManagedSerialization.h b/Source/Engine/Scripting/Internal/ManagedSerialization.h similarity index 96% rename from Source/Engine/Scripting/ManagedSerialization.h rename to Source/Engine/Scripting/Internal/ManagedSerialization.h index 65b21c235..6b58ac697 100644 --- a/Source/Engine/Scripting/ManagedSerialization.h +++ b/Source/Engine/Scripting/Internal/ManagedSerialization.h @@ -3,7 +3,7 @@ #pragma once #include "Engine/Core/ISerializable.h" -#include "ManagedCLR/MTypes.h" +#include "Engine/Scripting/ManagedCLR/MTypes.h" /// /// Managed objects serialization utilities. Helps with C# scripts saving to JSON or loading. @@ -11,8 +11,7 @@ class FLAXENGINE_API ManagedSerialization { public: - -#if USE_MONO +#if USE_CSHARP /// /// Serializes managed object to JSON. /// diff --git a/Source/Engine/Scripting/StdTypesContainer.cpp b/Source/Engine/Scripting/Internal/StdTypesContainer.cpp similarity index 92% rename from Source/Engine/Scripting/StdTypesContainer.cpp rename to Source/Engine/Scripting/Internal/StdTypesContainer.cpp index 526b01817..7197690cc 100644 --- a/Source/Engine/Scripting/StdTypesContainer.cpp +++ b/Source/Engine/Scripting/Internal/StdTypesContainer.cpp @@ -1,11 +1,11 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "StdTypesContainer.h" -#include "Scripting.h" -#include "ScriptingType.h" -#include "BinaryModule.h" -#include "ManagedCLR/MAssembly.h" -#include "ManagedCLR/MClass.h" +#include "Engine/Scripting/Scripting.h" +#include "Engine/Scripting/ScriptingType.h" +#include "Engine/Scripting/BinaryModule.h" +#include "Engine/Scripting/ManagedCLR/MAssembly.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Core/Log.h" #include "FlaxEngine.Gen.h" @@ -47,7 +47,7 @@ void StdTypesContainer::Clear() bool StdTypesContainer::Gather() { -#if !COMPILE_WITHOUT_CSHARP +#if USE_CSHARP #define GET_CLASS(assembly, type, typeName) \ type = ((ManagedBinaryModule*)CONCAT_MACROS(GetBinaryModule, assembly)())->Assembly->GetClass(typeName); \ if (type == nullptr) \ diff --git a/Source/Engine/Scripting/StdTypesContainer.h b/Source/Engine/Scripting/Internal/StdTypesContainer.h similarity index 100% rename from Source/Engine/Scripting/StdTypesContainer.h rename to Source/Engine/Scripting/Internal/StdTypesContainer.h diff --git a/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp b/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp deleted file mode 100644 index bdd9d04c6..000000000 --- a/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "Engine/Platform/Platform.h" -#include "Engine/Animations/Graph/AnimGraph.h" -#include "Engine/Scripting/InternalCalls.h" -#include "Engine/Scripting/MException.h" -#include "Engine/Scripting/ManagedCLR/MUtils.h" - -#if !COMPILE_WITHOUT_CSHARP - -#if USE_MONO && !USE_NETCORE -DEFINE_INTERNAL_CALL(MonoObject*) UtilsInternal_ExtractArrayFromList(MonoObject* obj) -{ - auto klass = mono_object_get_class(obj); - auto field = mono_class_get_field_from_name(klass, "_items"); - MonoObject* o; - mono_field_get_value(obj, field, &o); - return o; -} -#endif - -DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryCopy(void* dst, const void* src, uint64 size) -{ - Platform::MemoryCopy(dst, src, size); -} - -DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryClear(void* dst, uint64 size) -{ - Platform::MemoryClear(dst, size); -} - -DEFINE_INTERNAL_CALL(int32) PlatformInternal_MemoryCompare(const void* buf1, const void* buf2, uint64 size) -{ - return Platform::MemoryCompare(buf1, buf2, size); -} - -DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, MonoString* msgObj) -{ - StringView msg; - MUtils::ToString(msgObj, msg); - Log::Logger::Write(level, msg); -} - -DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MonoString* msgObj, ScriptingObject* obj, MonoString* stackTrace) -{ - if (msgObj == nullptr) - return; - - // Get info - StringView msg; - MUtils::ToString(msgObj, msg); - //const String objName = obj ? obj->ToString() : String::Empty; - - // Send event - // TODO: maybe option for build to threat warnings and errors as fatal errors? - //const String logMessage = String::Format(TEXT("Debug:{1} {2}"), objName, *msg); - Log::Logger::Write(level, msg); -} - -DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogException(MonoException* exception, ScriptingObject* obj) -{ -#if USE_MONO - if (exception == nullptr) - return; - - // Get info - MException ex(exception); - const String objName = obj ? obj->ToString() : String::Empty; - - // Print exception including inner exceptions - // TODO: maybe option for build to threat warnings and errors as fatal errors? - ex.Log(LogType::Warning, objName.GetText()); -#endif -} - -#endif - -void registerFlaxEngineInternalCalls() -{ - AnimGraphExecutor::initRuntime(); -#if USE_MONO - ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCopy", &PlatformInternal_MemoryCopy); - ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryClear", &PlatformInternal_MemoryClear); - ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCompare", &PlatformInternal_MemoryCompare); -#if USE_MONO && !USE_NETCORE - ADD_INTERNAL_CALL("FlaxEngine.Utils::Internal_ExtractArrayFromList", &UtilsInternal::ExtractArrayFromList); -#endif - ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogWrite", &DebugLogHandlerInternal_LogWrite); - ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal_Log); - ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal_LogException); -#endif -} diff --git a/Source/Engine/Scripting/MException.cpp b/Source/Engine/Scripting/MException.cpp deleted file mode 100644 index 2cdc4d55f..000000000 --- a/Source/Engine/Scripting/MException.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MException.h" -#include "ManagedCLR/MUtils.h" -#if USE_MONO -#include -#endif - -MException::MException(MObject* exception) - : InnerException(nullptr) -{ -#if USE_MONO - ASSERT(exception); - - MonoClass* exceptionClass = mono_object_get_class(exception); - MonoProperty* exceptionMsgProp = mono_class_get_property_from_name(exceptionClass, "Message"); - MonoMethod* exceptionMsgGetter = mono_property_get_get_method(exceptionMsgProp); - MonoString* exceptionMsg = (MonoString*)mono_runtime_invoke(exceptionMsgGetter, exception, nullptr, nullptr); - Message = MUtils::ToString(exceptionMsg); - - MonoProperty* exceptionStackProp = mono_class_get_property_from_name(exceptionClass, "StackTrace"); - MonoMethod* exceptionStackGetter = mono_property_get_get_method(exceptionStackProp); - MonoString* exceptionStackTrace = (MonoString*)mono_runtime_invoke(exceptionStackGetter, exception, nullptr, nullptr); - StackTrace = MUtils::ToString(exceptionStackTrace); - - MonoProperty* innerExceptionProp = mono_class_get_property_from_name(exceptionClass, "InnerException"); - MonoMethod* innerExceptionGetter = mono_property_get_get_method(innerExceptionProp); - MonoObject* innerException = (MonoObject*)mono_runtime_invoke(innerExceptionGetter, exception, nullptr, nullptr); - if (innerException) - InnerException = New(innerException); -#endif -} - -MException::~MException() -{ - if (InnerException) - Delete(InnerException); -} diff --git a/Source/Engine/Scripting/ManagedCLR/MAssembly.cpp b/Source/Engine/Scripting/ManagedCLR/MAssembly.cpp deleted file mode 100644 index 87bef8895..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MAssembly.cpp +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MAssembly.h" -#include "MClass.h" -#include "MDomain.h" -#include "MUtils.h" -#include "Engine/Core/Log.h" -#include "Engine/Core/Types/TimeSpan.h" -#include "Engine/Platform/FileSystem.h" -#include "Engine/Debug/Exceptions/InvalidOperationException.h" -#include "Engine/Debug/Exceptions/FileNotFoundException.h" -#include "Engine/Debug/Exceptions/CLRInnerException.h" -#include "Engine/Scripting/ManagedCLR/MCore.h" -#include "Engine/Scripting/Scripting.h" -#include "Engine/Platform/StringUtils.h" -#include "Engine/Platform/File.h" -#include "Engine/Profiler/ProfilerCPU.h" -#include "Engine/Threading/Threading.h" -#if USE_MONO -#include -#include -#include -#endif - -MAssembly::MAssembly(MDomain* domain, const StringAnsiView& name, const MAssemblyOptions& options) - : _domain(domain) - , _isLoaded(false) - , _isLoading(false) - , _isDependency(false) - , _isFileLocked(false) - , _hasCachedClasses(false) - , _reloadCount(0) - , _name(name) - , _options(options) -{ -} - -MAssembly::~MAssembly() -{ - Unload(); -} - -String MAssembly::ToString() const -{ - return _name.ToString(); -} - -bool MAssembly::Load(const String& assemblyPath) -{ - if (IsLoaded()) - return false; - PROFILE_CPU(); - ZoneText(*assemblyPath, assemblyPath.Length()); - - // Check file path - if (!FileSystem::FileExists(assemblyPath)) - { - Log::FileNotFoundException ex(assemblyPath); - return true; - } - - // Start - const auto startTime = DateTime::NowUTC(); - OnLoading(); - - // Load - bool failed; - if (_options.KeepManagedFileLocked) - failed = LoadDefault(assemblyPath); - else - failed = LoadWithImage(assemblyPath); - if (failed) - { - OnLoadFailed(); - return true; - } - - // End - OnLoaded(startTime); - return false; -} - -#if USE_MONO - -bool MAssembly::Load(MonoImage* monoImage) -{ - if (IsLoaded()) - return false; - PROFILE_CPU(); -#if TRACY_ENABLE - const StringAnsiView monoImageName(mono_image_get_name(monoImage)); - ZoneText(*monoImageName, monoImageName.Length()); -#endif - - // Ensure to be unloaded - Unload(); - - // Start - const auto startTime = DateTime::NowUTC(); - OnLoading(); - - // Load - _monoAssembly = mono_image_get_assembly(monoImage); - if (_monoAssembly == nullptr) - { - OnLoadFailed(); - return true; - } - _monoImage = monoImage; - _isDependency = true; - _hasCachedClasses = false; - - // End - OnLoaded(startTime); - return false; -} - -#endif - -void MAssembly::Unload(bool isReloading) -{ - if (!IsLoaded()) - return; - PROFILE_CPU(); - - Unloading(this); - - // Close runtime -#if USE_MONO - if (_monoImage) - { - if (isReloading) - { - LOG(Info, "Unloading managed assembly \'{0}\' (is reloading)", String(_name)); - - mono_assembly_close(_monoAssembly); - } - else - { - // NOTE: do not try to close all the opened images - // that will cause the domain unload to crash because - // the images have already been closed (double free) - } - - _monoAssembly = nullptr; - _monoImage = nullptr; - } -#endif - - // Cleanup - _debugData.Resize(0); - _assemblyPath.Clear(); - _isFileLocked = false; - _isDependency = false; - _isLoading = false; - _isLoaded = false; - _hasCachedClasses = false; - _classes.ClearDelete(); - - Unloaded(this); -} - -MClass* MAssembly::GetClass(const StringAnsiView& fullname) const -{ - // Check state - if (!IsLoaded()) - { - Log::InvalidOperationException(TEXT("MAssembly was not yet loaded or loading was in progress")); - return nullptr; - } - - StringAnsiView key(fullname); - - // Special case for reference - if (fullname[fullname.Length() - 1] == '&') - key = StringAnsiView(key.Get(), key.Length() - 1); - - // Find class by name - const auto& classes = GetClasses(); - MClass* result = nullptr; - classes.TryGet(key, result); - -#if 0 - if (!result) - { - LOG(Warning, "Failed to find class {0} in assembly {1}. Classes:", String(fullname), ToString()); - for (auto i = classes.Begin(); i.IsNotEnd(); ++i) - { - LOG(Warning, " - {0}", String(i->Key)); - } - } -#endif - return result; -} - -#if USE_MONO - -MClass* MAssembly::GetClass(MonoClass* monoClass) const -{ - if (monoClass == nullptr || !IsLoaded() || mono_class_get_image(monoClass) != _monoImage) - return nullptr; - - // Find class by native pointer - const auto& classes = GetClasses(); - const auto typeToken = mono_class_get_type_token(monoClass); - for (auto i = classes.Begin(); i.IsNotEnd(); ++i) - { - MonoClass* e = i->Value->GetNative(); - if (e == monoClass || mono_class_get_type_token(e) == typeToken) - { - return i->Value; - } - } - -#if 0 - { - LOG(Warning, "Failed to find class {0}.{1} in assembly {2}. Classes:", String(mono_class_get_namespace(monoClass)), String(mono_class_get_name(monoClass)), ToString()); - for (auto i = classes.Begin(); i.IsNotEnd(); ++i) - { - LOG(Warning, " - {0}", String(i->Key)); - } - } -#endif - return nullptr; -} - -MonoReflectionAssembly* MAssembly::GetNative() const -{ - if (!_monoAssembly) - return nullptr; - return mono_assembly_get_object(mono_domain_get(), _monoAssembly); -} - -#endif - -const MAssembly::ClassesDictionary& MAssembly::GetClasses() const -{ - if (_hasCachedClasses || !IsLoaded()) - return _classes; - PROFILE_CPU(); - const auto startTime = DateTime::NowUTC(); - -#if USE_MONO -#if TRACY_ENABLE - const StringAnsiView monoImageName(mono_image_get_name(_monoImage)); - ZoneText(*monoImageName, monoImageName.Length()); -#endif - ScopeLock lock(_locker); - if (_hasCachedClasses) - return _classes; - ASSERT(_classes.IsEmpty()); - const int32 numRows = mono_image_get_table_rows(_monoImage, MONO_TABLE_TYPEDEF); - _classes.EnsureCapacity(numRows * 4); - for (int32 i = 1; i < numRows; i++) // Skip class - { - MonoClass* klass = mono_class_get(_monoImage, (i + 1) | MONO_TOKEN_TYPE_DEF); - - // Peek the typename - MString fullname; - MUtils::GetClassFullname(klass, fullname); - - // Create class object - auto mclass = New(this, klass, fullname); - _classes.Add(fullname, mclass); - } -#endif - - const auto endTime = DateTime::NowUTC(); - LOG(Info, "Caching classes for assembly {0} took {1}ms", String(_name), (int32)(endTime - startTime).GetTotalMilliseconds()); - -#if 0 - for (auto i = _classes.Begin(); i.IsNotEnd(); ++i) - LOG(Info, "Class: {0}", String(i->Value->GetFullName())); -#endif - - _hasCachedClasses = true; - return _classes; -} - -bool MAssembly::LoadDefault(const String& assemblyPath) -{ -#if USE_MONO - // With this method of loading we need to make sure, we won't try to load assembly again if its loaded somewhere. - auto assembly = mono_domain_assembly_open(_domain->GetNative(), assemblyPath.ToStringAnsi().Get()); - if (!assembly) - { - return true; - } - auto assemblyImage = mono_assembly_get_image(assembly); - if (!assembly) - { - mono_assembly_close(assembly); - return true; - } - _monoAssembly = assembly; - _monoImage = assemblyImage; -#endif - - // Set state - _isDependency = false; - _hasCachedClasses = false; - _isFileLocked = true; - _assemblyPath = assemblyPath; - - // Register in domain - _domain->_assemblies[_name] = this; - - return false; -} - -bool MAssembly::LoadWithImage(const String& assemblyPath) -{ - // Lock file only for loading operation - _isFileLocked = true; - - // Load assembly file data - Array data; - File::ReadAllBytes(assemblyPath, data); - -#if USE_MONO - // Init Mono image - MonoImageOpenStatus status; - const auto name = assemblyPath.ToStringAnsi(); - const auto assemblyImage = mono_image_open_from_data_with_name(reinterpret_cast(data.Get()), data.Count(), true, &status, false, name.Get()); - if (status != MONO_IMAGE_OK || assemblyImage == nullptr) - { - Log::CLRInnerException(TEXT("Mono assembly image is invalid at ") + assemblyPath); - return true; - } - - // Setup assembly - const auto assembly = mono_assembly_load_from_full(assemblyImage, name.Substring(0, name.Length() - 3).Get(), &status, false); - mono_image_close(assemblyImage); - if (status != MONO_IMAGE_OK || assembly == nullptr) - { - Log::CLRInnerException(TEXT("Mono assembly image is corrupted at ") + assemblyPath); - return true; - } - -#if MONO_DEBUG_ENABLE - // Try to load debug symbols (use portable PDB format) - const auto pdbPath = String(StringUtils::GetPathWithoutExtension(assemblyPath)) + TEXT(".pdb"); - if (FileSystem::FileExists(pdbPath)) - { - // Load .pdb file - File::ReadAllBytes(pdbPath, _debugData); - - // Attach debugging symbols to image - if (_debugData.HasItems()) - { - mono_debug_open_image_from_memory(assemblyImage, _debugData.Get(), _debugData.Count()); - } - } - - // TODO: load pdbs for custom third-party libs referenced by game assemblies for debugging -#if 0 - // Hack to load debug information for Newtonsoft.Json (enable it to debug C# code of json lib) - if (assemblyPath.EndsWith(TEXT("FlaxEngine.CSharp.dll"))) - { - static Array NewtonsoftJsonDebugData; - File::ReadAllBytes(String(StringUtils::GetDirectoryName(assemblyPath)) / TEXT("Newtonsoft.Json.pdb"), NewtonsoftJsonDebugData); - if (NewtonsoftJsonDebugData.HasItems()) - { - StringAnsi tmp(String(StringUtils::GetDirectoryName(assemblyPath)) / TEXT("Newtonsoft.Json.dll")); - MonoAssembly* a = mono_assembly_open(tmp.Get(), &status); - if (a) - { - mono_debug_open_image_from_memory(mono_assembly_get_image(a), NewtonsoftJsonDebugData.Get(), NewtonsoftJsonDebugData.Count()); - } - } - } -#endif -#endif - _monoAssembly = assembly; - _monoImage = assemblyImage; -#endif - - // Set state - _isDependency = false; - _hasCachedClasses = false; - _isFileLocked = false; - _assemblyPath = assemblyPath; - - return false; -} - -void MAssembly::OnLoading() -{ - Loading(this); - - _isLoading = true; - - // Pick a domain - if (_domain == nullptr) - _domain = MCore::GetActiveDomain(); -} - -void MAssembly::OnLoaded(const DateTime& startTime) -{ - // Register in domain - _domain->_assemblies[_name] = this; - - _isLoaded = true; - _isLoading = false; - - if (_options.PreCacheOnLoad) - GetClasses(); - - const auto endTime = DateTime::NowUTC(); - LOG(Info, "Assembly {0} loaded in {1}ms", String(_name), (int32)(endTime - startTime).GetTotalMilliseconds()); - - Loaded(this); -} - -void MAssembly::OnLoadFailed() -{ - _isLoading = false; - - LoadFailed(this); -} diff --git a/Source/Engine/Scripting/ManagedCLR/MAssembly.h b/Source/Engine/Scripting/ManagedCLR/MAssembly.h index 4f0a8d57f..8f2a3185d 100644 --- a/Source/Engine/Scripting/ManagedCLR/MAssembly.h +++ b/Source/Engine/Scripting/ManagedCLR/MAssembly.h @@ -3,7 +3,6 @@ #pragma once #include "MTypes.h" -#include "MAssemblyOptions.h" #include "Engine/Core/Delegate.h" #include "Engine/Core/Types/String.h" #include "Engine/Core/Collections/Array.h" @@ -16,44 +15,41 @@ class FLAXENGINE_API MAssembly { friend MDomain; -public: + friend Scripting; - typedef Dictionary ClassesDictionary; +public: + typedef Dictionary ClassesDictionary; private: - #if USE_MONO MonoAssembly* _monoAssembly = nullptr; MonoImage* _monoImage = nullptr; +#elif USE_NETCORE + StringAnsi _fullname; + void* _handle = nullptr; #endif MDomain* _domain; int32 _isLoaded : 1; int32 _isLoading : 1; - int32 _isDependency : 1; - int32 _isFileLocked : 1; mutable int32 _hasCachedClasses : 1; mutable ClassesDictionary _classes; CriticalSection _locker; int32 _reloadCount; - MString _name; + StringAnsi _name; String _assemblyPath; Array _debugData; - const MAssemblyOptions _options; - public: - /// /// Initializes a new instance of the class. /// /// The assembly domain. /// The assembly name. - /// The assembly options. - MAssembly(MDomain* domain, const StringAnsiView& name, const MAssemblyOptions& options); + MAssembly(MDomain* domain, const StringAnsiView& name); /// /// Finalizes an instance of the class. @@ -61,7 +57,6 @@ public: ~MAssembly(); public: - /// /// Managed assembly actions delegate type. /// @@ -93,7 +88,6 @@ public: AssemblyDelegate Unloaded; public: - /// /// Returns true if assembly is during loading state. /// @@ -113,7 +107,7 @@ public: /// /// Gets the assembly name. /// - FORCE_INLINE const MString& GetName() const + FORCE_INLINE const StringAnsi& GetName() const { return _name; } @@ -143,39 +137,30 @@ public: } #if USE_MONO - /// - /// Gets the Mono assembly. - /// FORCE_INLINE MonoAssembly* GetMonoAssembly() const { return _monoAssembly; } - /// - /// Gets the Mono image. - /// FORCE_INLINE MonoImage* GetMonoImage() const { return _monoImage; } +#elif USE_NETCORE + FORCE_INLINE void* GetHandle() const + { + return _handle; + } #endif - /// - /// Gets the options that assembly was created with. - /// - FORCE_INLINE const MAssemblyOptions& GetOptions() const - { - return _options; - } - public: - /// /// Loads assembly for domain. /// /// The assembly path. + /// The optional path to the native code assembly (eg. if C# assembly contains bindings). /// True if cannot load, otherwise false - bool Load(const String& assemblyPath); + bool Load(const String& assemblyPath, const StringView& nativePath = StringView::Empty); #if USE_MONO /// @@ -193,7 +178,6 @@ public: void Unload(bool isReloading = false); public: - /// /// Attempts to find a managed class with the specified namespace and name in this assembly. Returns null if one cannot be found. /// @@ -212,30 +196,18 @@ public: /// /// Gets the native of the assembly (for the current domain). Can be used to pass to the scripting backend as a parameter. /// - /// The native assembly object. MonoReflectionAssembly* GetNative() const; #endif /// /// Gets the classes lookup cache. Performs full initialization if not cached. The result cache contains all classes from the assembly. /// - /// The cache. const ClassesDictionary& GetClasses() const; private: - - /// - /// Loads the assembly for domain. - /// - /// True if failed, otherwise false. - bool LoadDefault(const String& assemblyPath); - - /// - /// Loads the assembly for domain from non-blocking image. - /// - /// True if failed, otherwise false. - bool LoadWithImage(const String& assemblyPath); - + bool LoadCorlib(); + bool LoadImage(const String& assemblyPath, const StringView& nativePath); + bool UnloadImage(bool isReloading); void OnLoading(); void OnLoaded(const struct DateTime& startTime); void OnLoadFailed(); diff --git a/Source/Engine/Scripting/ManagedCLR/MAssemblyOptions.h b/Source/Engine/Scripting/ManagedCLR/MAssemblyOptions.h deleted file mode 100644 index b5fe04d2c..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MAssemblyOptions.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#pragma once - -#include "Engine/Core/Types/BaseTypes.h" - -/// -/// The options for creation of the managed assembly. -/// -struct MAssemblyOptions -{ - /// - /// Should assembly cache classes on Load method. - /// - int32 PreCacheOnLoad : 1; - - /// - /// Locks DLL/exe file with managed code. - /// - int32 KeepManagedFileLocked : 1; - - /// - /// Initializes a new instance of the struct. - /// - /// if set to true to precache assembly metadata on load. - /// if set to true keep managed file locked after load. - MAssemblyOptions(bool preCacheOnLoad = true, bool keepManagedFileLocked = false) - : PreCacheOnLoad(preCacheOnLoad) - , KeepManagedFileLocked(keepManagedFileLocked) - { - } -}; diff --git a/Source/Engine/Scripting/ManagedCLR/MClass.cpp b/Source/Engine/Scripting/ManagedCLR/MClass.cpp deleted file mode 100644 index 809bd1b1f..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MClass.cpp +++ /dev/null @@ -1,442 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MClass.h" -#include "MType.h" -#include "MTypes.h" -#include "MField.h" -#include "MProperty.h" -#include "MMethod.h" -#include "MEvent.h" -#include "Engine/Scripting/Scripting.h" -#include "Engine/Core/Log.h" -#if USE_MONO -#include -#include -#define GET_CUSTOM_ATTR() (MonoCustomAttrInfo*)(_attrInfo ? _attrInfo : _attrInfo = mono_custom_attrs_from_class(_monoClass)) -#endif -#if USE_NETCORE -#include "Engine/Scripting/DotNet/CoreCLR.h" -#endif - -#if USE_MONO -MClass::MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MString& fullname) - : _assembly(parentAssembly) - , _fullname(fullname) - , _visibility(MVisibility::Private) - , _hasCachedProperties(false) - , _hasCachedFields(false) - , _hasCachedMethods(false) - , _hasCachedAttributes(false) - , _hasCachedEvents(false) - , _isStatic(false) - , _isSealed(false) - , _isAbstract(false) - , _isInterface(false) -{ - _monoClass = monoClass; - ASSERT(monoClass); - - const uint32_t flags = mono_class_get_flags(monoClass); - - switch (flags & MONO_TYPE_ATTR_VISIBILITY_MASK) - { - case MONO_TYPE_ATTR_NOT_PUBLIC: - case MONO_TYPE_ATTR_NESTED_PRIVATE: - _visibility = MVisibility::Private; - break; - case MONO_TYPE_ATTR_PUBLIC: - case MONO_TYPE_ATTR_NESTED_PUBLIC: - _visibility = MVisibility::Public; - break; - case MONO_TYPE_ATTR_NESTED_FAMILY: - case MONO_TYPE_ATTR_NESTED_ASSEMBLY: - _visibility = MVisibility::Internal; - break; - case MONO_TYPE_ATTR_NESTED_FAM_OR_ASSEM: - _visibility = MVisibility::ProtectedInternal; - break; - case MONO_TYPE_ATTR_NESTED_FAM_AND_ASSEM: - _visibility = MVisibility::PrivateProtected; - break; - default: - CRASH; - } - - const uint32_t staticClassFlags = MONO_TYPE_ATTR_ABSTRACT | MONO_TYPE_ATTR_SEALED; - _isStatic = (flags & staticClassFlags) == staticClassFlags; - _isSealed = !_isStatic && (flags & MONO_TYPE_ATTR_SEALED) == MONO_TYPE_ATTR_SEALED; - _isAbstract = !_isStatic && (flags & MONO_TYPE_ATTR_ABSTRACT) == MONO_TYPE_ATTR_ABSTRACT; - _isInterface = (flags & MONO_TYPE_ATTR_CLASS_SEMANTIC_MASK) == MONO_TYPE_ATTR_INTERFACE; -} -#endif - -MClass::~MClass() -{ -#if !COMPILE_WITHOUT_CSHARP -#if USE_MONO - if (_attrInfo) - mono_custom_attrs_free((MonoCustomAttrInfo*)_attrInfo); -#endif - _fields.ClearDelete(); - _properties.ClearDelete(); - _methods.ClearDelete(); - _attributes.ClearDelete(); - _events.ClearDelete(); -#endif -} - -bool MClass::IsGeneric() const -{ - return _fullname.FindLast('`') != -1; -} - -MType MClass::GetType() const -{ -#if USE_MONO - return MType(mono_class_get_type(_monoClass)); -#else - return MType(); -#endif -} - -MClass* MClass::GetBaseClass() const -{ -#if USE_MONO - MonoClass* monoBase = mono_class_get_parent(_monoClass); - if (monoBase == nullptr) - return nullptr; - return Scripting::FindClass(monoBase); -#else - return nullptr; -#endif -} - -bool MClass::IsSubClassOf(const MClass* klass) const -{ -#if USE_MONO - return klass && mono_class_is_subclass_of(_monoClass, klass->GetNative(), false) != 0; -#else - return false; -#endif -} - -#if USE_MONO -bool MClass::IsSubClassOf(const MonoClass* monoClass) const -{ - return monoClass && mono_class_is_subclass_of(_monoClass, (MonoClass*)monoClass, true) != 0; -} -#endif - -bool MClass::HasInterface(const MClass* klass) const -{ -#if USE_MONO - return klass && mono_class_is_assignable_from(klass->GetNative(), _monoClass) != 0; -#else - return false; -#endif -} - -bool MClass::IsInstanceOfType(MObject* object) const -{ - if (object == nullptr) - return false; -#if USE_MONO - MonoClass* monoClass = mono_object_get_class(object); - return mono_class_is_subclass_of(monoClass, _monoClass, false) != 0; -#else - return false; -#endif -} - -uint32 MClass::GetInstanceSize() const -{ -#if USE_MONO - uint32 dummy = 0; - if (mono_class_is_valuetype(_monoClass)) - return mono_class_value_size(_monoClass, &dummy); - return mono_class_instance_size(_monoClass); -#else - return 0; -#endif -} - -MMethod* MClass::FindMethod(const char* name, int32 numParams, bool checkBaseClasses) -{ - auto method = GetMethod(name, numParams); - if (!method && checkBaseClasses) - { - auto base = GetBaseClass(); - if (base) - method = base->FindMethod(name, numParams, true); - } - return method; -} - -MMethod* MClass::GetMethod(const char* name, int32 numParams) -{ - // Lookup for cached method - for (int32 i = 0; i < _methods.Count(); i++) - { - if (_methods[i]->GetName() == name && _methods[i]->GetParametersCount() == numParams) - return _methods[i]; - } - -#if USE_MONO - // Find Mono method - MonoMethod* monoMethod = mono_class_get_method_from_name(_monoClass, name, numParams); - if (monoMethod == nullptr) - return nullptr; - - // Create method - auto method = New(monoMethod, name, this); - _methods.Add(method); - return method; -#else - return nullptr; -#endif -} - -const Array& MClass::GetMethods() -{ - if (_hasCachedMethods) - return _methods; - -#if USE_MONO - void* iter = nullptr; - MonoMethod* curClassMethod; - while ((curClassMethod = mono_class_get_methods(_monoClass, &iter))) - { - // Check if has not been added - bool isMissing = true; - for (int32 i = 0; i < _methods.Count(); i++) - { - if (_methods[i]->GetNative() == curClassMethod) - { - isMissing = false; - break; - } - } - - if (isMissing) - { - // Create method - auto method = New(curClassMethod, this); - _methods.Add(method); - } - } -#endif - - _hasCachedMethods = true; - return _methods; -} - -MField* MClass::GetField(const char* name) -{ - // Lookup for cached field - for (int32 i = 0; i < _fields.Count(); i++) - { - if (_fields[i]->GetName() == name) - return _fields[i]; - } - -#if USE_MONO - // Find mono field - MonoClassField* field = mono_class_get_field_from_name(_monoClass, name); - if (field == nullptr) - return nullptr; - - // Create field - auto mfield = New(field, name, this); - _fields.Add(mfield); - return mfield; -#else - return nullptr; -#endif -} - -const Array& MClass::GetFields() -{ - if (_hasCachedFields) - return _fields; - -#if USE_MONO - void* iter = nullptr; - MonoClassField* curClassField; - while ((curClassField = mono_class_get_fields(_monoClass, &iter))) - { - const char* fieldName = mono_field_get_name(curClassField); - GetField(fieldName); - } -#endif - - _hasCachedFields = true; - return _fields; -} - -MEvent* MClass::GetEvent(const char* name) -{ - GetEvents(); - for (int32 i = 0; i < _events.Count(); i++) - { - if (_events[i]->GetName() == name) - return _events[i]; - } - return nullptr; -} - -const Array& MClass::GetEvents() -{ - if (_hasCachedEvents) - return _events; - -#if USE_MONO - void* iter = nullptr; - MonoEvent* curEvent; - while ((curEvent = mono_class_get_events(_monoClass, &iter))) - { - const char* name = mono_event_get_name(curEvent); - bool missing = true; - for (int32 i = 0; i < _events.Count(); i++) - { - if (_events[i]->GetName() == name) - { - missing = false; - break; - } - } - if (missing) - { - auto result = New(curEvent, name, this); - _events.Add(result); - } - } -#endif - - _hasCachedEvents = true; - return _events; -} - -MProperty* MClass::GetProperty(const char* name) -{ - // Lookup for cached property - for (int32 i = 0; i < _properties.Count(); i++) - { - if (_properties[i]->GetName() == name) - return _properties[i]; - } - -#if USE_MONO - // Find mono property - MonoProperty* monoProperty = mono_class_get_property_from_name(_monoClass, name); - if (monoProperty == nullptr) - return nullptr; - - // Create method - auto mproperty = New(monoProperty, name, this); - _properties.Add(mproperty); - - return mproperty; -#else - return nullptr; -#endif -} - -const Array& MClass::GetProperties() -{ - if (_hasCachedProperties) - return _properties; -#if USE_MONO - void* iter = nullptr; - MonoProperty* curClassProperty; - while ((curClassProperty = mono_class_get_properties(_monoClass, &iter))) - { - const char* propertyName = mono_property_get_name(curClassProperty); - GetProperty(propertyName); - } -#endif - _hasCachedProperties = true; - return _properties; -} - -MObject* MClass::CreateInstance() const -{ -#if USE_MONO - MonoObject* obj = mono_object_new(mono_domain_get(), _monoClass); - if (!mono_class_is_valuetype(_monoClass)) - mono_runtime_object_init(obj); - return obj; -#else - return nullptr; -#endif -} - -MObject* MClass::CreateInstance(void** params, uint32 numParams) -{ -#if USE_MONO - MonoObject* obj = mono_object_new(mono_domain_get(), _monoClass); - const auto constructor = GetMethod(".ctor", numParams); - ASSERT(constructor); - constructor->Invoke(obj, params, nullptr); - return obj; -#else - return nullptr; -#endif -} - -bool MClass::HasAttribute(const MClass* monoClass) const -{ -#if USE_NETCORE - return CoreCLR::HasCustomAttribute(_monoClass, monoClass->GetNative()); -#elif USE_MONO - MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); - return attrInfo != nullptr && mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; -#else - return false; -#endif -} - -bool MClass::HasAttribute() const -{ -#if USE_NETCORE - return CoreCLR::HasCustomAttribute(_monoClass); -#elif USE_MONO - MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); - return attrInfo && attrInfo->num_attrs > 0; -#else - return false; -#endif -} - -MObject* MClass::GetAttribute(const MClass* monoClass) const -{ -#if USE_NETCORE - return (MObject*)CoreCLR::GetCustomAttribute(_monoClass, monoClass->GetNative()); -#elif USE_MONO - MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); - return attrInfo ? mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()) : nullptr; -#else - return nullptr; -#endif -} - -const Array& MClass::GetAttributes() -{ - if (_hasCachedAttributes) - return _attributes; - _hasCachedAttributes = true; -#if USE_NETCORE - _attributes = MoveTemp(CoreCLR::GetCustomAttributes(_monoClass)); -#elif USE_MONO - MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); - if (attrInfo == nullptr) - return _attributes; - - MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); - const auto length = (uint32)mono_array_length(monoAttributesArray); - _attributes.Resize(length); - for (uint32 i = 0; i < length; i++) - _attributes[i] = mono_array_get(monoAttributesArray, MonoObject *, i); - mono_custom_attrs_free(attrInfo); -#endif - return _attributes; -} diff --git a/Source/Engine/Scripting/ManagedCLR/MClass.h b/Source/Engine/Scripting/ManagedCLR/MClass.h index b275081ad..49b153731 100644 --- a/Source/Engine/Scripting/ManagedCLR/MClass.h +++ b/Source/Engine/Scripting/ManagedCLR/MClass.h @@ -10,44 +10,49 @@ /// class FLAXENGINE_API MClass { + friend MCore; private: - #if USE_MONO MonoClass* _monoClass; mutable void* _attrInfo = nullptr; +#elif USE_NETCORE + void* _handle; + StringAnsi _name; + StringAnsi _namespace_; + uint32 _types = 0; + mutable uint32 _size = 0; #endif const MAssembly* _assembly; - MString _fullname; + StringAnsi _fullname; - Array _methods; - Array _fields; - Array _properties; - Array _attributes; - Array _events; + mutable Array _methods; + mutable Array _fields; + mutable Array _properties; + mutable Array _attributes; + mutable Array _events; + mutable Array _interfaces; MVisibility _visibility; - int32 _hasCachedProperties : 1; - int32 _hasCachedFields : 1; - int32 _hasCachedMethods : 1; - int32 _hasCachedAttributes : 1; - int32 _hasCachedEvents : 1; + mutable int32 _hasCachedProperties : 1; + mutable int32 _hasCachedFields : 1; + mutable int32 _hasCachedMethods : 1; + mutable int32 _hasCachedAttributes : 1; + mutable int32 _hasCachedEvents : 1; + mutable int32 _hasCachedInterfaces : 1; int32 _isStatic : 1; int32 _isSealed : 1; int32 _isAbstract : 1; int32 _isInterface : 1; + int32 _isValueType : 1; + int32 _isEnum : 1; public: - #if USE_MONO - /// - /// Initializes a new instance of the class. - /// - /// The parent assembly. - /// The Mono class. - /// The fullname. - MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MString& fullname); + MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const StringAnsi& fullname); +#elif USE_NETCORE + MClass(const MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes typeAttributes); #endif /// @@ -56,7 +61,6 @@ public: ~MClass(); public: - /// /// Gets the parent assembly. /// @@ -68,11 +72,21 @@ public: /// /// Gets the full name of the class (namespace and typename). /// - FORCE_INLINE const MString& GetFullName() const + FORCE_INLINE const StringAnsi& GetFullName() const { return _fullname; } + /// + /// Gets the name of the class. + /// + StringAnsiView GetName() const; + + /// + /// Gets the namespace of the class. + /// + StringAnsiView GetNamespace() const; + #if USE_MONO /// /// Gets the Mono class handle. @@ -81,6 +95,11 @@ public: { return _monoClass; } +#elif USE_NETCORE + FORCE_INLINE void* GetNative() const + { + return _handle; + } #endif /// @@ -123,15 +142,34 @@ public: return _isInterface != 0; } + /// + /// Gets if class is value type (eg. enum or structure) but not reference type (eg. class, string, array, interface) + /// + FORCE_INLINE bool IsValueType() const + { + return _isValueType != 0; + } + + /// + /// Gets if class is enumeration + /// + FORCE_INLINE bool IsEnum() const + { + return _isEnum != 0; + } + /// /// Gets if class is generic /// - bool IsGeneric() const; + bool IsGeneric() const + { + return _fullname.FindLast('`') != -1; + } /// /// Gets the class type. /// - MType GetType() const; + MType* GetType() const; /// /// Returns the base class of this class. Null if this class has no base. @@ -142,17 +180,9 @@ public: /// Checks if this class is a sub class of the specified class (including any derived types). /// /// The class. + /// True if check interfaces, otherwise just base class. /// True if this class is a sub class of the specified class. - bool IsSubClassOf(const MClass* klass) const; - -#if USE_MONO - /// - /// Checks if this class is a sub class of the specified class (including any derived types). - /// - /// The Mono class. - /// True if this class is a sub class of the specified class. - bool IsSubClassOf(const MonoClass* monoClass) const; -#endif + bool IsSubClassOf(const MClass* klass, bool checkInterfaces = false) const; /// /// Checks if this class implements the specified interface (including any base types). @@ -173,8 +203,12 @@ public: /// uint32 GetInstanceSize() const; -public: + /// + /// Returns the class of the array type elements. + /// + MClass* GetElementClass() const; +public: /// /// Returns an object referencing a method with the specified name and number of parameters. Optionally checks the base classes. /// @@ -182,7 +216,17 @@ public: /// The method parameters count. /// True if check base classes when searching for the given method. /// The method or null if failed to find it. - MMethod* FindMethod(const char* name, int32 numParams, bool checkBaseClasses); + MMethod* FindMethod(const char* name, int32 numParams, bool checkBaseClasses = true) const + { + MMethod* method = GetMethod(name, numParams); + if (!method && checkBaseClasses) + { + MClass* base = GetBaseClass(); + if (base) + method = base->FindMethod(name, numParams, true); + } + return method; + } /// /// Returns an object referencing a method with the specified name and number of parameters. @@ -191,88 +235,73 @@ public: /// The method name. /// The method parameters count. /// The method or null if failed to get it. - MMethod* GetMethod(const char* name, int32 numParams = 0); + MMethod* GetMethod(const char* name, int32 numParams = 0) const; /// /// Returns all methods belonging to this class. /// - /// - /// Be aware this will not include the methods of any base classes. - /// + /// Be aware this will not include the methods of any base classes. /// The list of methods. - const Array& GetMethods(); + const Array& GetMethods() const; /// /// Returns an object referencing a field with the specified name. /// - /// - /// Does not query base class fields. - /// Returns null if field cannot be found. - /// + /// Does not query base class fields. Returns null if field cannot be found. /// The field name. /// The field or null if failed. - MField* GetField(const char* name); + MField* GetField(const char* name) const; /// /// Returns all fields belonging to this class. /// - /// - /// Be aware this will not include the fields of any base classes. - /// + /// Be aware this will not include the fields of any base classes. /// The list of fields. - const Array& GetFields(); + const Array& GetFields() const; /// /// Returns an object referencing a event with the specified name. /// /// The event name. /// The event object. - MEvent* GetEvent(const char* name); + MEvent* GetEvent(const char* name) const; /// /// Returns all events belonging to this class. /// /// The list of events. - const Array& GetEvents(); + const Array& GetEvents() const; /// /// Returns an object referencing a property with the specified name. /// - /// - /// Does not query base class properties. - /// Returns null if property cannot be found. - /// + /// Does not query base class properties. Returns null if property cannot be found. /// The property name. /// The property. - MProperty* GetProperty(const char* name); + MProperty* GetProperty(const char* name) const; /// /// Returns all properties belonging to this class. /// - /// - /// Be aware this will not include the properties of any base classes. - /// + /// Be aware this will not include the properties of any base classes. /// The list of properties. - const Array& GetProperties(); + const Array& GetProperties() const; + + /// + /// Returns all interfaces implemented by this class (excluding interfaces from base classes). + /// + /// Be aware this will not include the interfaces of any base classes. + /// The list of interfaces. + const Array& GetInterfaces() const; public: - /// /// Creates a new instance of this class and constructs it. /// /// The created managed object. MObject* CreateInstance() const; - /// - /// Creates a new instance of this class and then constructs it using the constructor with the specified number of parameters. - /// - /// The array containing pointers to constructor parameters. Array length must be equal to number of parameters. - /// The number of parameters the constructor accepts. - /// The created managed object. - MObject* CreateInstance(void** params, uint32 numParams); - public: - /// /// Checks if class has an attribute of the specified type. /// @@ -297,5 +326,5 @@ public: /// Returns an instance of all attributes connected with given class. Returns null if the class doesn't have any attributes. /// /// The array of attribute objects. - const Array& GetAttributes(); + const Array& GetAttributes() const; }; diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.cpp b/Source/Engine/Scripting/ManagedCLR/MCore.cpp index b052bde63..bc2f934d6 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MCore.cpp @@ -1,48 +1,260 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "MCore.h" +#include "MAssembly.h" +#include "MClass.h" +#include "MEvent.h" #include "MDomain.h" -#include "Engine/Core/Log.h" -#include "Engine/Core/Types/String.h" +#include "MException.h" +#include "MMethod.h" +#include "MProperty.h" +#include "Engine/Core/Math/Math.h" #include "Engine/Core/Types/DateTime.h" -#include "Engine/Engine/CommandLine.h" -#include "Engine/Engine/Globals.h" -#include "Engine/Debug/Exceptions/Exceptions.h" -#include "Engine/Threading/Threading.h" -#include "Engine/Platform/Thread.h" -#include "Engine/Scripting/MException.h" -#include "Engine/Profiler/ProfilerCPU.h" -#include "Engine/Platform/FileSystem.h" -#if USE_NETCORE -#include "Engine/Scripting/DotNet/CoreCLR.h" -#endif -#if USE_MONO -#ifdef USE_MONO_AOT_MODULE #include "Engine/Core/Types/TimeSpan.h" -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if !USE_MONO_DYNAMIC_LIB -#include -#endif -#endif - -#ifdef USE_MONO_AOT_MODULE -void* MonoAotModuleHandle = nullptr; -#endif +#include "Engine/Platform/FileSystem.h" +#include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Debug/Exceptions/FileNotFoundException.h" +#include "Engine/Debug/Exceptions/InvalidOperationException.h" MDomain* MRootDomain = nullptr; MDomain* MActiveDomain = nullptr; -Array> MDomains; +Array> MDomains; + +MClass* MCore::TypeCache::Void = nullptr; +MClass* MCore::TypeCache::Object = nullptr; +MClass* MCore::TypeCache::Byte = nullptr; +MClass* MCore::TypeCache::Boolean = nullptr; +MClass* MCore::TypeCache::SByte = nullptr; +MClass* MCore::TypeCache::Char = nullptr; +MClass* MCore::TypeCache::Int16 = nullptr; +MClass* MCore::TypeCache::UInt16 = nullptr; +MClass* MCore::TypeCache::Int32 = nullptr; +MClass* MCore::TypeCache::UInt32 = nullptr; +MClass* MCore::TypeCache::Int64 = nullptr; +MClass* MCore::TypeCache::UInt64 = nullptr; +MClass* MCore::TypeCache::IntPtr = nullptr; +MClass* MCore::TypeCache::UIntPtr = nullptr; +MClass* MCore::TypeCache::Single = nullptr; +MClass* MCore::TypeCache::Double = nullptr; +MClass* MCore::TypeCache::String = nullptr; + +MAssembly::MAssembly(MDomain* domain, const StringAnsiView& name) + : _domain(domain) + , _isLoaded(false) + , _isLoading(false) + , _hasCachedClasses(false) + , _reloadCount(0) + , _name(name) +{ +} + +MAssembly::~MAssembly() +{ + Unload(); +} + +String MAssembly::ToString() const +{ + return _name.ToString(); +} + +bool MAssembly::Load(const String& assemblyPath, const StringView& nativePath) +{ + if (IsLoaded()) + return false; + PROFILE_CPU(); + ZoneText(*assemblyPath, assemblyPath.Length()); + + if (!FileSystem::FileExists(assemblyPath)) + { + Log::FileNotFoundException ex(assemblyPath); + return true; + } + + const auto startTime = DateTime::NowUTC(); + OnLoading(); + + if (LoadImage(assemblyPath, nativePath)) + { + OnLoadFailed(); + return true; + } + + OnLoaded(startTime); + return false; +} + +void MAssembly::Unload(bool isReloading) +{ + if (!IsLoaded()) + return; + PROFILE_CPU(); + + Unloading(this); + + // Close runtime + UnloadImage(isReloading); + + // Cleanup + _debugData.Resize(0); + _assemblyPath.Clear(); + _isLoading = false; + _isLoaded = false; + _hasCachedClasses = false; + _classes.ClearDelete(); + + Unloaded(this); +} + +MClass* MAssembly::GetClass(const StringAnsiView& fullname) const +{ + // Check state + if (!IsLoaded()) + { + Log::InvalidOperationException(TEXT("MAssembly was not yet loaded or loading was in progress")); + return nullptr; + } + + StringAnsiView key(fullname); + + // Special case for reference + if (fullname[fullname.Length() - 1] == '&') + key = StringAnsiView(key.Get(), key.Length() - 1); + + // Find class by name + const auto& classes = GetClasses(); + MClass* result = nullptr; + classes.TryGet(key, result); + +#if 0 + if (!result) + { + LOG(Warning, "Failed to find class {0} in assembly {1}. Classes:", String(fullname), ToString()); + for (auto i = classes.Begin(); i.IsNotEnd(); ++i) + { + LOG(Warning, " - {0}", String(i->Key)); + } + } +#endif + return result; +} + +void MAssembly::OnLoading() +{ + Loading(this); + + _isLoading = true; + + // Pick a domain + if (_domain == nullptr) + _domain = MCore::GetActiveDomain(); +} + +void MAssembly::OnLoaded(const DateTime& startTime) +{ + // Register in domain + _domain->_assemblies[_name] = this; + + _isLoaded = true; + _isLoading = false; + + const auto endTime = DateTime::NowUTC(); + LOG(Info, "Assembly {0} loaded in {1}ms", String(_name), (int32)(endTime - startTime).GetTotalMilliseconds()); + + // Pre-cache classes + GetClasses(); + + Loaded(this); +} + +void MAssembly::OnLoadFailed() +{ + _isLoading = false; + + LoadFailed(this); +} + +MEvent* MClass::GetEvent(const char* name) const +{ + GetEvents(); + for (int32 i = 0; i < _events.Count(); i++) + { + if (_events[i]->GetName() == name) + return _events[i]; + } + return nullptr; +} + +MObject* MClass::CreateInstance() const +{ + MObject* obj = MCore::Object::New(this); + if (!IsValueType()) + MCore::Object::Init(obj); + return obj; +} + +MType* MEvent::GetType() const +{ + if (GetAddMethod() != nullptr) + return GetAddMethod()->GetReturnType(); + if (GetRemoveMethod() != nullptr) + return GetRemoveMethod()->GetReturnType(); + return nullptr; +} + +void MException::Log(const LogType type, const Char* target) +{ + // Log inner exceptions chain + auto inner = InnerException; + while (inner) + { + auto stackTrace = inner->StackTrace.HasChars() ? *inner->StackTrace : TEXT(""); + Log::Logger::Write(LogType::Warning, String::Format(TEXT("Inner exception. {0}\nStack strace:\n{1}\n"), inner->Message, stackTrace)); + inner = inner->InnerException; + } + + // Send stack trace only to log file + auto stackTrace = StackTrace.HasChars() ? *StackTrace : TEXT(""); + Log::Logger::Write(LogType::Warning, String::Format(TEXT("Exception has been thrown during {0}. {1}\nStack strace:\n{2}"), target, Message, stackTrace)); + Log::Logger::Write(type, String::Format(TEXT("Exception has been thrown during {0}.\n{1}"), target, Message)); +} + +MType* MProperty::GetType() const +{ + if (GetGetMethod() != nullptr) + return GetGetMethod()->GetReturnType(); + return GetSetMethod()->GetReturnType(); +} + +MVisibility MProperty::GetVisibility() const +{ + if (GetGetMethod() && GetSetMethod()) + { + return static_cast( + Math::Max( + static_cast(GetGetMethod()->GetVisibility()), + static_cast(GetSetMethod()->GetVisibility()) + )); + } + if (GetGetMethod()) + { + return GetGetMethod()->GetVisibility(); + } + return GetSetMethod()->GetVisibility(); +} + +bool MProperty::IsStatic() const +{ + if (GetGetMethod()) + { + return GetGetMethod()->IsStatic(); + } + if (GetSetMethod()) + { + return GetSetMethod()->IsStatic(); + } + return false; +} MDomain* MCore::GetRootDomain() { @@ -53,2156 +265,3 @@ MDomain* MCore::GetActiveDomain() { return MActiveDomain; } - -MDomain* MCore::CreateDomain(const MString& domainName) -{ -#if USE_NETCORE - return nullptr; -#else -#if USE_MONO_AOT - LOG(Fatal, "Scripts can run only in single domain mode with AOT mode enabled."); - return nullptr; -#endif - - for (int32 i = 0; i < MDomains.Count(); i++) - { - if (MDomains[i]->GetName() == domainName) - return MDomains[i]; - } - - auto domain = New(domainName); -#if USE_MONO - const auto monoDomain = mono_domain_create_appdomain((char*)domainName.Get(), nullptr); -#if MONO_DEBUG_ENABLE - mono_debug_domain_create(monoDomain); -#endif - ASSERT(monoDomain); - domain->_monoDomain = monoDomain; -#endif - MDomains.Add(domain); - return domain; -#endif -} - -void MCore::UnloadDomain(const MString& domainName) -{ -#if USE_NETCORE -#else - int32 i = 0; - for (; i < MDomains.Count(); i++) - { - if (MDomains[i]->GetName() == domainName) - break; - } - if (i == MDomains.Count()) - return; - - auto domain = MDomains[i]; -#if USE_MONO -#if MONO_DEBUG_ENABLE - //mono_debug_domain_unload(domain->GetNative()); -#endif - //mono_domain_finalize(domain->GetNative(), 2000); - MObject* exception = nullptr; - mono_domain_try_unload(domain->GetNative(), &exception); - if (exception) - { - MException ex(exception); - ex.Log(LogType::Fatal, TEXT("Scripting::Release")); - } -#endif - Delete(domain); - MDomains.RemoveAtKeepOrder(i); -#endif -} - -#if USE_NETCORE -bool MCore::LoadEngine() -{ - PROFILE_CPU(); - const String csharpLibraryPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll"); - const String csharpRuntimeConfigPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.runtimeconfig.json"); - if (!FileSystem::FileExists(csharpLibraryPath)) - LOG(Fatal, "Failed to initialize managed runtime, FlaxEngine.CSharp.dll is missing."); - if (!FileSystem::FileExists(csharpRuntimeConfigPath)) - LOG(Fatal, "Failed to initialize managed runtime, FlaxEngine.CSharp.runtimeconfig.json is missing."); - - // Initialize hostfxr - if (CoreCLR::InitHostfxr(csharpRuntimeConfigPath, csharpLibraryPath)) - return true; - - // Prepare managed side - CoreCLR::CallStaticMethodByName(TEXT("Init")); -#ifdef MCORE_MAIN_MODULE_NAME - // MCORE_MAIN_MODULE_NAME define is injected by Scripting.Build.cs on platforms that use separate shared library for engine symbols - const StringAnsi flaxLibraryPath(Platform::GetMainDirectory() / TEXT(MACRO_TO_STR(MCORE_MAIN_MODULE_NAME))); -#else - const StringAnsi flaxLibraryPath(Platform::GetExecutableFilePath()); -#endif - CoreCLR::RegisterNativeLibrary("FlaxEngine", flaxLibraryPath.Get()); - - MRootDomain = New("Root"); - MDomains.Add(MRootDomain); - - char* buildInfo = CoreCLR::CallStaticMethodByName(TEXT("GetRuntimeInformation")); - LOG(Info, ".NET runtime version: {0}", String(buildInfo)); - CoreCLR::Free(buildInfo); - - return false; -} - -void MCore::UnloadEngine() -{ - if (!MRootDomain) - return; - PROFILE_CPU(); - CoreCLR::CallStaticMethodByName(TEXT("Exit")); - MDomains.ClearDelete(); - MRootDomain = nullptr; - CoreCLR::ShutdownHostfxr(); -} -#elif USE_MONO - -#if 0 - -void* MonoMalloc(size_t size) -{ - return malloc(size); -} - -void* MonoRealloc(void* mem, size_t count) -{ - return realloc(mem, count); -} - -void MonoFree(void* mem) -{ - return free(mem); -} - -void* MonoCalloc(size_t count, size_t size) -{ - return calloc(count, size); -} - -#endif - -#if USE_MONO_PROFILER - -#include "Engine/Core/Types/StringBuilder.h" - -struct FlaxMonoProfiler -{ -}; - -FlaxMonoProfiler Profiler; - -struct StackWalkDataResult -{ - StringBuilder Buffer; -}; - -mono_bool OnStackWalk(MonoMethod* method, int32_t native_offset, int32_t il_offset, mono_bool managed, void* data) -{ - auto result = (StackWalkDataResult*)data; - - if (method) - { - auto mName = mono_method_get_name(method); - auto mKlassNameSpace = mono_class_get_namespace(mono_method_get_class(method)); - auto mKlassName = mono_class_get_name(mono_method_get_class(method)); - result->Buffer.Append(mKlassNameSpace); - result->Buffer.Append(TEXT(".")); - result->Buffer.Append(mKlassName); - result->Buffer.Append(TEXT("::")); - result->Buffer.Append(mName); - result->Buffer.Append(TEXT("\n")); - } - else if (!managed) - { - result->Buffer.Append(TEXT("\n")); - } - - return 0; -} - -void OnGCAllocation(MonoProfiler* profiler, MonoObject* obj) -{ - // Get allocation info - auto klass = mono_object_get_class(obj); - //auto name_space = mono_class_get_namespace(klass); - //auto name = mono_class_get_name(klass); - auto size = mono_class_instance_size(klass); - - //LOG(Info, "GC new: {0}.{1} ({2} bytes)", name_space, name, size); - -#if 0 - if (ProfilerCPU::IsProfilingCurrentThread()) - { - static int details = 0; - if (details) - { - StackWalkDataResult stackTrace; - stackTrace.Buffer.SetCapacity(1024); - mono_stack_walk(&OnStackWalk, &stackTrace); - - const auto msg = String::Format(TEXT("GC new: {0}.{1} ({2} bytes). Stack Trace:\n{3}"), String(name_space), String(name), size, stackTrace.Buffer.ToStringView()); - Platform::Log(*msg); - //LOG_STR(Info, msg); - } - } -#endif - -#if COMPILE_WITH_PROFILER - // Register allocation during the current CPU event - auto thread = ProfilerCPU::GetCurrentThread(); - if (thread != nullptr && thread->Buffer.GetCount() != 0) - { - auto& activeEvent = thread->Buffer.Last().Event(); - if (activeEvent.End < ZeroTolerance) - { - activeEvent.ManagedMemoryAllocation += size; - } - } -#endif -} - -void OnGCEvent(MonoProfiler* profiler, MonoProfilerGCEvent event, uint32_t generation, mono_bool is_serial) -{ -#if COMPILE_WITH_PROFILER - // GC - static int32 ActiveEventIndex; - if (event == MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED) - { - ActiveEventIndex = ProfilerCPU::BeginEvent(TEXT("Garbage Collection")); - } - else if (event == MONO_GC_EVENT_POST_START_WORLD_UNLOCKED) - { - ProfilerCPU::EndEvent(ActiveEventIndex); - } -#endif -} - -#endif - -void OnLogCallback(const char* logDomain, const char* logLevel, const char* message, mono_bool fatal, void* userData) -{ - String currentDomain(logDomain); - String msg(message); - msg.Replace('\n', ' '); - - static const char* monoErrorLevels[] = - { - nullptr, - "error", - "critical", - "warning", - "message", - "info", - "debug" - }; - - uint32 errorLevel = 0; - if (logLevel != nullptr) - { - for (uint32 i = 1; i < 7; i++) - { - if (strcmp(monoErrorLevels[i], logLevel) == 0) - { - errorLevel = i; - break; - } - } - } - - if (currentDomain.IsEmpty()) - { - auto domain = MCore::GetActiveDomain(); - if (domain != nullptr) - { - currentDomain = domain->GetName().Get(); - } - else - { - currentDomain = "null"; - } - } - -#if 0 - // Print C# stack trace (crash may be caused by the managed code) - if (mono_domain_get() && Assemblies::FlaxEngine.Assembly->IsLoaded()) - { - const auto managedStackTrace = DebugLog::GetStackTrace(); - if (managedStackTrace.HasChars()) - { - LOG(Warning, "Managed stack trace:"); - LOG_STR(Warning, managedStackTrace); - } - } -#endif - - if (errorLevel == 0) - { - Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); - } - else if (errorLevel <= 2) - { - Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); - } - else if (errorLevel <= 3) - { - LOG(Warning, "Message: {0} | Domain: {1}", msg, currentDomain); - } - else - { - LOG(Info, "Message: {0} | Domain: {1}", msg, currentDomain); - } -} - -void OnPrintCallback(const char* string, mono_bool isStdout) -{ - LOG_STR(Warning, String(string)); -} - -void OnPrintErrorCallback(const char* string, mono_bool isStdout) -{ - // HACK: ignore this message - if (string && Platform::MemoryCompare(string, "debugger-agent: Unable to listen on ", 36) == 0) - return; - - LOG_STR(Error, String(string)); -} - -#if PLATFORM_LINUX && !USE_MONO_DYNAMIC_LIB - -#include - -#define MONO_THIS_LIB_HANDLE ((void*)(intptr)-1) - -static void* ThisLibHandle = nullptr; - -static void* OnMonoLinuxDlOpen(const char* name, int flags, char** err, void* user_data) -{ - void* result = nullptr; - if (name && StringUtils::Compare(name + StringUtils::Length(name) - 17, "libmono-native.so") == 0) - { - result = MONO_THIS_LIB_HANDLE; - } - return result; -} - -static void* OnMonoLinuxDlSym(void* handle, const char* name, char** err, void* user_data) -{ - void* result = nullptr; - if (handle == MONO_THIS_LIB_HANDLE && ThisLibHandle != nullptr) - { - result = dlsym(ThisLibHandle, name); - } - return result; -} - -#endif - -bool MCore::LoadEngine() -{ - PROFILE_CPU(); - ASSERT(Globals::MonoPath.IsANSI()); - - // Debugging Mono GC - //Platform::SetEnvironmentVariable(TEXT("MONO_GC_DEBUG"), TEXT("6:gc-log.txt,check-remset-consistency,nursery-canaries")); - -#if 0 - // Override memory allocation callback - // TODO: use ENABLE_OVERRIDABLE_ALLOCATORS when building Mono to support memory callbacks or use counters for memory profiling - MonoAllocatorVTable alloc; - alloc.version = MONO_ALLOCATOR_VTABLE_VERSION; - alloc.malloc = MonoMalloc; - alloc.realloc = MonoRealloc; - alloc.free = MonoFree; - alloc.calloc = MonoCalloc; - mono_set_allocator_vtable(&alloc); -#endif - -#if USE_MONO_AOT - mono_jit_set_aot_mode(USE_MONO_AOT_MODE); -#endif - -#ifdef USE_MONO_AOT_MODULE - // Load AOT module - const DateTime aotModuleLoadStartTime = DateTime::Now(); - LOG(Info, "Loading Mono AOT module..."); - void* libAotModule = Platform::LoadLibrary(TEXT(USE_MONO_AOT_MODULE)); - if (libAotModule == nullptr) - { - LOG(Error, "Failed to laod Mono AOT module (" TEXT(USE_MONO_AOT_MODULE) ")"); - return true; - } - MonoAotModuleHandle = libAotModule; - void* getModulesPtr = Platform::GetProcAddress(libAotModule, "GetMonoModules"); - if (getModulesPtr == nullptr) - { - LOG(Error, "Failed to get Mono AOT modules getter."); - return true; - } - typedef int (*GetMonoModulesFunc)(void** buffer, int bufferSize); - const auto getModules = (GetMonoModulesFunc)getModulesPtr; - const int32 moduelsCount = getModules(nullptr, 0); - void** modules = (void**)Allocator::Allocate(moduelsCount * sizeof(void*)); - getModules(modules, moduelsCount); - for (int32 i = 0; i < moduelsCount; i++) - { - mono_aot_register_module((void**)modules[i]); - } - Allocator::Free(modules); - LOG(Info, "Mono AOT module loaded in {0}ms", (int32)(DateTime::Now() - aotModuleLoadStartTime).GetTotalMilliseconds()); -#endif - - // Set mono assemblies path - MString pathLib = (Globals::MonoPath / TEXT("/lib")).ToStringAnsi(); - MString pathEtc = (Globals::MonoPath / TEXT("/etc")).ToStringAnsi(); - mono_set_dirs(pathLib.Get(), pathEtc.Get()); - - // Setup debugger - { - int32 debuggerLogLevel = 0; - if (CommandLine::Options.MonoLog.IsTrue()) - { - LOG(Info, "Using detailed Mono logging"); - mono_trace_set_level_string("debug"); - debuggerLogLevel = 10; - } - else - { - mono_trace_set_level_string("warning"); - } - -#if MONO_DEBUG_ENABLE && !PLATFORM_SWITCH - StringAnsi debuggerIp = "127.0.0.1"; - uint16 debuggerPort = 41000 + Platform::GetCurrentProcessId() % 1000; - if (CommandLine::Options.DebuggerAddress.HasValue()) - { - const auto& address = CommandLine::Options.DebuggerAddress.GetValue(); - const int32 splitIndex = address.Find(':'); - if (splitIndex == INVALID_INDEX) - { - debuggerIp = address.ToStringAnsi(); - } - else - { - debuggerIp = address.Left(splitIndex).ToStringAnsi(); - StringUtils::Parse(address.Right(address.Length() - splitIndex - 1).Get(), &debuggerPort); - } - } - - char buffer[150]; - sprintf(buffer, "--debugger-agent=transport=dt_socket,address=%s:%d,embedding=1,server=y,suspend=%s,loglevel=%d", debuggerIp.Get(), debuggerPort, CommandLine::Options.WaitForDebugger ? "y,timeout=5000" : "n", debuggerLogLevel); - - const char* options[] = { - "--soft-breakpoints", - //"--optimize=float32", - buffer - }; - mono_jit_parse_options(ARRAY_COUNT(options), (char**)options); - - mono_debug_init(MONO_DEBUG_FORMAT_MONO, 0); - LOG(Info, "Mono debugger server at {0}:{1}", String(debuggerIp), debuggerPort); -#endif - - // Connects to mono engine callback system - mono_trace_set_log_handler(OnLogCallback, nullptr); - mono_trace_set_print_handler(OnPrintCallback); - mono_trace_set_printerr_handler(OnPrintErrorCallback); - } - -#if USE_MONO_PROFILER - // Setup profiler options - bool useExternalProfiler = false; - { - String monoEnvOptions; - if (!Platform::GetEnvironmentVariable(TEXT("MONO_ENV_OPTIONS"), monoEnvOptions)) - { - const StringView prefix(TEXT("--profile=")); - if (monoEnvOptions.StartsWith(prefix)) - { - monoEnvOptions = monoEnvOptions.Substring(prefix.Length()); - LOG(Info, "Loading Mono profiler with options \'{0}\'", monoEnvOptions); - StringAnsi monoEnvOptionsAnsi(monoEnvOptions); - mono_profiler_load(monoEnvOptionsAnsi.Get()); - useExternalProfiler = true; - } - } - } -#endif - -#if PLATFORM_ANDROID - // Disable any AOT code on Android - mono_jit_set_aot_mode(MONO_AOT_MODE_NONE); - - // Hint to use default system assemblies location - const MString assembliesPath = (Globals::MonoPath / TEXT("/lib/mono/2.1")).ToStringAnsi(); - mono_set_assemblies_path(*assembliesPath); -#elif PLATFORM_LINUX - // Adjust GC threads suspending mode on Linux - Platform::SetEnvironmentVariable(TEXT("MONO_THREADS_SUSPEND"), TEXT("preemptive")); - -#if !USE_MONO_DYNAMIC_LIB - // Hook for missing library (when using static linking) - ThisLibHandle = dlopen(nullptr, RTLD_LAZY); - mono_dl_fallback_register(OnMonoLinuxDlOpen, OnMonoLinuxDlSym, nullptr, nullptr); -#endif -#elif PLATFORM_MAC - // Adjust GC threads suspending mode on Mac - Platform::SetEnvironmentVariable(TEXT("MONO_THREADS_SUSPEND"), TEXT("preemptive")); -#endif - const char* configPath = nullptr; -#if PLATFORM_SWITCH - MString configPathBuf = (Globals::MonoPath / TEXT("/etc/mono/config")).ToStringAnsi(); - configPath = *configPathBuf; - const MString assembliesPath = (Globals::MonoPath / TEXT("/lib/mono/4.5")).ToStringAnsi(); - mono_set_assemblies_path(*assembliesPath); -#endif - mono_config_parse(configPath); - -#if USE_MONO_PROFILER - // Init profiler - if (!useExternalProfiler) - { - const MonoProfilerHandle profilerHandle = mono_profiler_create((MonoProfiler*)&Profiler); - mono_profiler_set_gc_allocation_callback(profilerHandle, &OnGCAllocation); - mono_profiler_set_gc_event_callback(profilerHandle, &OnGCEvent); - mono_profiler_enable_allocations(); - } -#endif - - // Init managed runtime -#if PLATFORM_ANDROID - const char* monoVersion = "mobile"; -#else - const char* monoVersion = "v4.0.30319"; -#endif - auto monoRootDomain = mono_jit_init_version("Flax", monoVersion); - ASSERT(monoRootDomain); - MRootDomain = New("Root"); - MRootDomain->_monoDomain = monoRootDomain; - MDomains.Add(MRootDomain); - -#if !USE_NETCORE - auto exePath = Platform::GetExecutableFilePath(); - auto configDir = StringUtils::GetDirectoryName(exePath).ToStringAnsi(); - auto configFilename = StringUtils::GetFileName(exePath).ToStringAnsi() + ".config"; -#if PLATFORM_UWP - // Change the app root to Mono sub directory to prevent loading .Net Core assemblies from the AppX root folder - configDir += "\\Mono"; -#elif PLATFORM_SWITCH - // Make config file path absolute - configFilename = exePath.ToStringAnsi() + ".config"; -#endif - mono_domain_set_config(monoRootDomain, configDir.Get(), configFilename.Get()); - mono_thread_set_main(mono_thread_current()); -#endif - - // Info - char* buildInfo = mono_get_runtime_build_info(); - LOG(Info, "Mono runtime version: {0}", String(buildInfo)); - mono_free(buildInfo); - - return false; -} - -#if PLATFORM_WINDOWS && USE_EDITOR -long MonoHackSehExceptionHandler(class EXCEPTION_POINTERS* ep) -{ - LOG(Error, "Mono crashed on exit"); - return 1; -} -#endif - -void MCore::UnloadEngine() -{ - // Only root domain should be alive at this point - for (auto domain : MDomains) - { - if (domain != MRootDomain) - Delete(domain); - } - MDomains.Clear(); - - if (MRootDomain) - { -#if PLATFORM_WINDOWS && USE_EDITOR - // TODO: reduce issues with hot-reloading C# DLLs because sometimes it crashes on exit - __try -#endif - { - mono_jit_cleanup(MRootDomain->GetNative()); - } -#if PLATFORM_WINDOWS && USE_EDITOR - __except (MonoHackSehExceptionHandler(nullptr)) - { - } -#endif - Delete(MRootDomain); - MRootDomain = nullptr; - } - -#ifdef USE_MONO_AOT_MODULE - Platform::FreeLibrary(MonoAotModuleHandle); -#endif - -#if PLATFORM_LINUX && !USE_MONO_DYNAMIC_LIB - if (ThisLibHandle) - { - dlclose(ThisLibHandle); - ThisLibHandle = nullptr; - } -#endif -} - -#else - -bool MCore::LoadEngine() -{ - MRootDomain = New("Root"); - MDomains.Add(MRootDomain); - return false; -} - -void MCore::UnloadEngine() -{ - MDomains.ClearDelete(); - MRootDomain = nullptr; -} - -#endif - -void MCore::AttachThread() -{ -#if USE_MONO - if (!IsInMainThread() && !mono_domain_get()) - { - const auto domain = GetActiveDomain(); - ASSERT(domain); - mono_thread_attach(domain->GetNative()); - } -#endif -} - -void MCore::ExitThread() -{ -#if USE_MONO - if (!IsInMainThread() && mono_domain_get()) - { - LOG(Info, "Thread 0x{0:x} exits the managed runtime", Platform::GetCurrentThreadID()); - // TODO: use mono_thread_detach but modify mono to call mono_thread_info_detach there so the thread goes into STATE_DETACHED - mono_thread_exit(); - } -#endif -} - -void MCore::GC::Collect() -{ -#if USE_MONO - PROFILE_CPU(); - mono_gc_collect(mono_gc_max_generation()); -#endif -} - -void MCore::GC::Collect(int32 generation) -{ -#if USE_MONO - PROFILE_CPU(); - mono_gc_collect(generation); -#endif -} - -void MCore::GC::WaitForPendingFinalizers() -{ -#if USE_MONO - PROFILE_CPU(); - if (mono_gc_pending_finalizers()) - { - mono_gc_finalize_notify(); - do - { - Platform::Sleep(1); - } while (mono_gc_pending_finalizers()); - } -#endif -} - -#if USE_MONO && PLATFORM_WIN32 && !USE_MONO_DYNAMIC_LIB && !USE_NETCORE - -// Export Mono functions -#pragma comment(linker, "/export:mono_add_internal_call") -#pragma comment(linker, "/export:mono_array_addr_with_size") -#pragma comment(linker, "/export:mono_array_calc_byte_len") -#pragma comment(linker, "/export:mono_array_class_get") -#pragma comment(linker, "/export:mono_array_clone") -#pragma comment(linker, "/export:mono_array_clone_checked") -#pragma comment(linker, "/export:mono_array_clone_in_domain") -#pragma comment(linker, "/export:mono_array_element_size") -#pragma comment(linker, "/export:mono_array_full_copy") -#pragma comment(linker, "/export:mono_array_handle_length") -#pragma comment(linker, "/export:mono_array_handle_memcpy_refs") -#pragma comment(linker, "/export:mono_array_handle_pin_with_size") -#pragma comment(linker, "/export:mono_array_length") -#pragma comment(linker, "/export:mono_array_new") -#pragma comment(linker, "/export:mono_array_new_1") -#pragma comment(linker, "/export:mono_array_new_2") -#pragma comment(linker, "/export:mono_array_new_3") -#pragma comment(linker, "/export:mono_array_new_4") -#pragma comment(linker, "/export:mono_array_new_checked") -#pragma comment(linker, "/export:mono_array_new_full") -#pragma comment(linker, "/export:mono_array_new_full_checked") -#pragma comment(linker, "/export:mono_array_new_full_handle") -#pragma comment(linker, "/export:mono_array_new_handle") -#pragma comment(linker, "/export:mono_array_new_specific") -#pragma comment(linker, "/export:mono_array_new_specific_checked") -#pragma comment(linker, "/export:mono_array_new_specific_handle") -#pragma comment(linker, "/export:mono_array_new_va") -#pragma comment(linker, "/export:mono_array_to_byte_byvalarray") -#pragma comment(linker, "/export:mono_array_to_lparray") -#pragma comment(linker, "/export:mono_array_to_savearray") -#pragma comment(linker, "/export:mono_assembly_addref") -#pragma comment(linker, "/export:mono_assembly_binding_applies_to_image") -#pragma comment(linker, "/export:mono_assembly_candidate_predicate_sn_same_name") -#pragma comment(linker, "/export:mono_assembly_cleanup_domain_bindings") -#pragma comment(linker, "/export:mono_assembly_close") -#pragma comment(linker, "/export:mono_assembly_close_except_image_pools") -#pragma comment(linker, "/export:mono_assembly_close_finish") -#pragma comment(linker, "/export:mono_assembly_fill_assembly_name") -#pragma comment(linker, "/export:mono_assembly_fill_assembly_name_full") -#pragma comment(linker, "/export:mono_assembly_foreach") -#pragma comment(linker, "/export:mono_assembly_get_assemblyref") -#pragma comment(linker, "/export:mono_assembly_get_assemblyref_checked") -#pragma comment(linker, "/export:mono_assembly_get_image") -#pragma comment(linker, "/export:mono_assembly_get_image_internal") -#pragma comment(linker, "/export:mono_assembly_get_main") -#pragma comment(linker, "/export:mono_assembly_get_name") -#pragma comment(linker, "/export:mono_assembly_get_name_internal") -#pragma comment(linker, "/export:mono_assembly_get_object") -#pragma comment(linker, "/export:mono_assembly_get_object_handle") -#pragma comment(linker, "/export:mono_assembly_getrootdir") -#pragma comment(linker, "/export:mono_assembly_has_reference_assembly_attribute") -#pragma comment(linker, "/export:mono_assembly_has_skip_verification") -#pragma comment(linker, "/export:mono_assembly_init_weak_fields") -#pragma comment(linker, "/export:mono_assembly_invoke_load_hook") -#pragma comment(linker, "/export:mono_assembly_invoke_search_hook") -#pragma comment(linker, "/export:mono_assembly_invoke_unload_hook") -#pragma comment(linker, "/export:mono_assembly_is_problematic_version") -#pragma comment(linker, "/export:mono_assembly_is_weak_field") -#pragma comment(linker, "/export:mono_assembly_load") -#pragma comment(linker, "/export:mono_assembly_load_corlib") -#pragma comment(linker, "/export:mono_assembly_load_friends") -#pragma comment(linker, "/export:mono_assembly_load_from") -#pragma comment(linker, "/export:mono_assembly_load_from_assemblies_path") -#pragma comment(linker, "/export:mono_assembly_load_from_full") -#pragma comment(linker, "/export:mono_assembly_load_from_predicate") -#pragma comment(linker, "/export:mono_assembly_load_full") -#pragma comment(linker, "/export:mono_assembly_load_full_nosearch") -#pragma comment(linker, "/export:mono_assembly_load_module") -#pragma comment(linker, "/export:mono_assembly_load_module_checked") -#pragma comment(linker, "/export:mono_assembly_load_reference") -#pragma comment(linker, "/export:mono_assembly_load_references") -#pragma comment(linker, "/export:mono_assembly_load_with_partial_name") -#pragma comment(linker, "/export:mono_assembly_load_with_partial_name_internal") -#pragma comment(linker, "/export:mono_assembly_loaded") -#pragma comment(linker, "/export:mono_assembly_loaded_full") -#pragma comment(linker, "/export:mono_assembly_metadata_foreach_custom_attr") -#pragma comment(linker, "/export:mono_assembly_name_free") -#pragma comment(linker, "/export:mono_assembly_name_free_internal") -#pragma comment(linker, "/export:mono_assembly_name_get_culture") -#pragma comment(linker, "/export:mono_assembly_name_get_name") -#pragma comment(linker, "/export:mono_assembly_name_get_pubkeytoken") -#pragma comment(linker, "/export:mono_assembly_name_get_version") -#pragma comment(linker, "/export:mono_assembly_name_new") -#pragma comment(linker, "/export:mono_assembly_name_parse") -#pragma comment(linker, "/export:mono_assembly_name_parse_full") -#pragma comment(linker, "/export:mono_assembly_names_equal") -#pragma comment(linker, "/export:mono_assembly_names_equal_flags") -#pragma comment(linker, "/export:mono_assembly_open") -#pragma comment(linker, "/export:mono_assembly_open_a_lot") -#pragma comment(linker, "/export:mono_assembly_open_from_bundle") -#pragma comment(linker, "/export:mono_assembly_open_full") -#pragma comment(linker, "/export:mono_assembly_open_predicate") -#pragma comment(linker, "/export:mono_assembly_release_gc_roots") -#pragma comment(linker, "/export:mono_assembly_set_main") -#pragma comment(linker, "/export:mono_assembly_setrootdir") -#pragma comment(linker, "/export:mono_class_alloc") -#pragma comment(linker, "/export:mono_class_alloc0") -#pragma comment(linker, "/export:mono_class_array_element_size") -#pragma comment(linker, "/export:mono_class_bind_generic_parameters") -#pragma comment(linker, "/export:mono_class_can_access_class") -#pragma comment(linker, "/export:mono_class_check_context_used") -#pragma comment(linker, "/export:mono_class_check_vtable_constraints") -#pragma comment(linker, "/export:mono_class_compute_bitmap") -#pragma comment(linker, "/export:mono_class_compute_gc_descriptor") -#pragma comment(linker, "/export:mono_class_contextbound_bit_offset") -#pragma comment(linker, "/export:mono_class_create_array") -#pragma comment(linker, "/export:mono_class_create_array_fill_type") -#pragma comment(linker, "/export:mono_class_create_bounded_array") -#pragma comment(linker, "/export:mono_class_create_fnptr") -#pragma comment(linker, "/export:mono_class_create_from_typedef") -#pragma comment(linker, "/export:mono_class_create_generic_inst") -#pragma comment(linker, "/export:mono_class_create_generic_parameter") -#pragma comment(linker, "/export:mono_class_create_ptr") -#pragma comment(linker, "/export:mono_class_data_size") -#pragma comment(linker, "/export:mono_class_describe_statics") -#pragma comment(linker, "/export:mono_class_enum_basetype") -#pragma comment(linker, "/export:mono_class_enum_basetype_internal") -#pragma comment(linker, "/export:mono_class_field_get_special_static_type") -#pragma comment(linker, "/export:mono_class_field_is_special_static") -#pragma comment(linker, "/export:mono_class_fill_runtime_generic_context") -#pragma comment(linker, "/export:mono_class_find_enum_basetype") -#pragma comment(linker, "/export:mono_class_free_ref_info") -#pragma comment(linker, "/export:mono_class_from_generic_parameter") -#pragma comment(linker, "/export:mono_class_from_mono_type") -#pragma comment(linker, "/export:mono_class_from_mono_type_handle") -#pragma comment(linker, "/export:mono_class_from_name") -#pragma comment(linker, "/export:mono_class_from_name_case") -#pragma comment(linker, "/export:mono_class_from_name_case_checked") -#pragma comment(linker, "/export:mono_class_from_name_checked") -#pragma comment(linker, "/export:mono_class_from_typeref") -#pragma comment(linker, "/export:mono_class_from_typeref_checked") -#pragma comment(linker, "/export:mono_class_full_name") -#pragma comment(linker, "/export:mono_class_generic_sharing_enabled") -#pragma comment(linker, "/export:mono_class_get") -#pragma comment(linker, "/export:mono_class_get_and_inflate_typespec_checked") -#pragma comment(linker, "/export:mono_class_get_appdomain_unloaded_exception_class") -#pragma comment(linker, "/export:mono_class_get_byref_type") -#pragma comment(linker, "/export:mono_class_get_cached_class_info") -#pragma comment(linker, "/export:mono_class_get_cctor") -#pragma comment(linker, "/export:mono_class_get_checked") -#pragma comment(linker, "/export:mono_class_get_com_object_class") -#pragma comment(linker, "/export:mono_class_get_context") -#pragma comment(linker, "/export:mono_class_get_declsec_flags") -#pragma comment(linker, "/export:mono_class_get_default_finalize_method") -#pragma comment(linker, "/export:mono_class_get_dim_conflicts") -#pragma comment(linker, "/export:mono_class_get_element_class") -#pragma comment(linker, "/export:mono_class_get_event_info") -#pragma comment(linker, "/export:mono_class_get_event_token") -#pragma comment(linker, "/export:mono_class_get_events") -#pragma comment(linker, "/export:mono_class_get_exception_data") -#pragma comment(linker, "/export:mono_class_get_exception_for_failure") -#pragma comment(linker, "/export:mono_class_get_field") -#pragma comment(linker, "/export:mono_class_get_field_count") -#pragma comment(linker, "/export:mono_class_get_field_def_values") -#pragma comment(linker, "/export:mono_class_get_field_default_value") -#pragma comment(linker, "/export:mono_class_get_field_from_name") -#pragma comment(linker, "/export:mono_class_get_field_from_name_full") -#pragma comment(linker, "/export:mono_class_get_field_token") -#pragma comment(linker, "/export:mono_class_get_fields") -#pragma comment(linker, "/export:mono_class_get_fields_internal") -#pragma comment(linker, "/export:mono_class_get_fields_lazy") -#pragma comment(linker, "/export:mono_class_get_finalizer") -#pragma comment(linker, "/export:mono_class_get_first_field_idx") -#pragma comment(linker, "/export:mono_class_get_first_method_idx") -#pragma comment(linker, "/export:mono_class_get_flags") -#pragma comment(linker, "/export:mono_class_get_full") -#pragma comment(linker, "/export:mono_class_get_generic_class") -#pragma comment(linker, "/export:mono_class_get_generic_container") -#pragma comment(linker, "/export:mono_class_get_generic_type_definition") -#pragma comment(linker, "/export:mono_class_get_idispatch_class") -#pragma comment(linker, "/export:mono_class_get_image") -#pragma comment(linker, "/export:mono_class_get_implemented_interfaces") -#pragma comment(linker, "/export:mono_class_get_inflated_method") -#pragma comment(linker, "/export:mono_class_get_interfaces") -#pragma comment(linker, "/export:mono_class_get_interop_proxy_class") -#pragma comment(linker, "/export:mono_class_get_iunknown_class") -#pragma comment(linker, "/export:mono_class_get_marshal_info") -#pragma comment(linker, "/export:mono_class_get_method_by_index") -#pragma comment(linker, "/export:mono_class_get_method_count") -#pragma comment(linker, "/export:mono_class_get_method_from_name") -#pragma comment(linker, "/export:mono_class_get_method_from_name_checked") -#pragma comment(linker, "/export:mono_class_get_method_from_name_flags") -#pragma comment(linker, "/export:mono_class_get_method_generic") -#pragma comment(linker, "/export:mono_class_get_methods") -#pragma comment(linker, "/export:mono_class_get_methods_by_name") -#pragma comment(linker, "/export:mono_class_get_name") -#pragma comment(linker, "/export:mono_class_get_namespace") -#pragma comment(linker, "/export:mono_class_get_nested_classes_property") -#pragma comment(linker, "/export:mono_class_get_nested_types") -#pragma comment(linker, "/export:mono_class_get_nesting_type") -#pragma comment(linker, "/export:mono_class_get_nullable_param") -#pragma comment(linker, "/export:mono_class_get_object_finalize_slot") -#pragma comment(linker, "/export:mono_class_get_overrides_full") -#pragma comment(linker, "/export:mono_class_get_parent") -#pragma comment(linker, "/export:mono_class_get_properties") -#pragma comment(linker, "/export:mono_class_get_property_default_value") -#pragma comment(linker, "/export:mono_class_get_property_from_name") -#pragma comment(linker, "/export:mono_class_get_property_info") -#pragma comment(linker, "/export:mono_class_get_property_token") -#pragma comment(linker, "/export:mono_class_get_rank") -#pragma comment(linker, "/export:mono_class_get_ref_info") -#pragma comment(linker, "/export:mono_class_get_ref_info_handle") -#pragma comment(linker, "/export:mono_class_get_ref_info_raw") -#pragma comment(linker, "/export:mono_class_get_type") -#pragma comment(linker, "/export:mono_class_get_type_token") -#pragma comment(linker, "/export:mono_class_get_valuetype_class") -#pragma comment(linker, "/export:mono_class_get_variant_class") -#pragma comment(linker, "/export:mono_class_get_virtual_method") -#pragma comment(linker, "/export:mono_class_get_vtable_entry") -#pragma comment(linker, "/export:mono_class_get_vtable_size") -#pragma comment(linker, "/export:mono_class_get_weak_bitmap") -#pragma comment(linker, "/export:mono_class_gtd_get_canonical_inst") -#pragma comment(linker, "/export:mono_class_has_dim_conflicts") -#pragma comment(linker, "/export:mono_class_has_failure") -#pragma comment(linker, "/export:mono_class_has_finalizer") -#pragma comment(linker, "/export:mono_class_has_ref_info") -#pragma comment(linker, "/export:mono_class_has_special_static_fields") -#pragma comment(linker, "/export:mono_class_has_variant_generic_params") -#pragma comment(linker, "/export:mono_class_implements_interface") -#pragma comment(linker, "/export:mono_class_inflate_generic_class_checked") -#pragma comment(linker, "/export:mono_class_inflate_generic_method") -#pragma comment(linker, "/export:mono_class_inflate_generic_method_checked") -#pragma comment(linker, "/export:mono_class_inflate_generic_method_full_checked") -#pragma comment(linker, "/export:mono_class_inflate_generic_type") -#pragma comment(linker, "/export:mono_class_inflate_generic_type_checked") -#pragma comment(linker, "/export:mono_class_inflate_generic_type_with_mempool") -#pragma comment(linker, "/export:mono_class_init") -#pragma comment(linker, "/export:mono_class_init_checked") -#pragma comment(linker, "/export:mono_class_init_sizes") -#pragma comment(linker, "/export:mono_class_instance_size") -#pragma comment(linker, "/export:mono_class_interface_offset") -#pragma comment(linker, "/export:mono_class_interface_offset_with_variance") -#pragma comment(linker, "/export:mono_class_is_assignable_from") -#pragma comment(linker, "/export:mono_class_is_assignable_from_checked") -#pragma comment(linker, "/export:mono_class_is_assignable_from_internal") -#pragma comment(linker, "/export:mono_class_is_assignable_from_slow") -#pragma comment(linker, "/export:mono_class_is_delegate") -#pragma comment(linker, "/export:mono_class_is_enum") -#pragma comment(linker, "/export:mono_class_is_from_assembly") -#pragma comment(linker, "/export:mono_class_is_magic_float") -#pragma comment(linker, "/export:mono_class_is_magic_int") -#pragma comment(linker, "/export:mono_class_is_nullable") -#pragma comment(linker, "/export:mono_class_is_open_constructed_type") -#pragma comment(linker, "/export:mono_class_is_reflection_method_or_constructor") -#pragma comment(linker, "/export:mono_class_is_subclass_of") -#pragma comment(linker, "/export:mono_class_is_valid_enum") -#pragma comment(linker, "/export:mono_class_is_valuetype") -#pragma comment(linker, "/export:mono_class_is_variant_compatible") -#pragma comment(linker, "/export:mono_class_layout_fields") -#pragma comment(linker, "/export:mono_class_load_from_name") -#pragma comment(linker, "/export:mono_class_min_align") -#pragma comment(linker, "/export:mono_class_name_from_token") -#pragma comment(linker, "/export:mono_class_native_size") -#pragma comment(linker, "/export:mono_class_needs_cctor_run") -#pragma comment(linker, "/export:mono_class_num_events") -#pragma comment(linker, "/export:mono_class_num_fields") -#pragma comment(linker, "/export:mono_class_num_methods") -#pragma comment(linker, "/export:mono_class_num_properties") -#pragma comment(linker, "/export:mono_class_publish_gc_descriptor") -#pragma comment(linker, "/export:mono_class_rgctx_get_array_size") -#pragma comment(linker, "/export:mono_class_set_declsec_flags") -#pragma comment(linker, "/export:mono_class_set_dim_conflicts") -#pragma comment(linker, "/export:mono_class_set_event_info") -#pragma comment(linker, "/export:mono_class_set_exception_data") -#pragma comment(linker, "/export:mono_class_set_failure") -#pragma comment(linker, "/export:mono_class_set_field_count") -#pragma comment(linker, "/export:mono_class_set_field_def_values") -#pragma comment(linker, "/export:mono_class_set_first_field_idx") -#pragma comment(linker, "/export:mono_class_set_first_method_idx") -#pragma comment(linker, "/export:mono_class_set_flags") -#pragma comment(linker, "/export:mono_class_set_generic_container") -#pragma comment(linker, "/export:mono_class_set_is_com_object") -#pragma comment(linker, "/export:mono_class_set_marshal_info") -#pragma comment(linker, "/export:mono_class_set_method_count") -#pragma comment(linker, "/export:mono_class_set_nested_classes_property") -#pragma comment(linker, "/export:mono_class_set_nonblittable") -#pragma comment(linker, "/export:mono_class_set_property_info") -#pragma comment(linker, "/export:mono_class_set_ref_info") -#pragma comment(linker, "/export:mono_class_set_ref_info_handle") -#pragma comment(linker, "/export:mono_class_set_type_load_failure") -#pragma comment(linker, "/export:mono_class_set_type_load_failure_causedby_class") -#pragma comment(linker, "/export:mono_class_set_weak_bitmap") -#pragma comment(linker, "/export:mono_class_setup_basic_field_info") -#pragma comment(linker, "/export:mono_class_setup_events") -#pragma comment(linker, "/export:mono_class_setup_fields") -#pragma comment(linker, "/export:mono_class_setup_has_finalizer") -#pragma comment(linker, "/export:mono_class_setup_interface_id") -#pragma comment(linker, "/export:mono_class_setup_interface_offsets") -#pragma comment(linker, "/export:mono_class_setup_interfaces") -#pragma comment(linker, "/export:mono_class_setup_methods") -#pragma comment(linker, "/export:mono_class_setup_mono_type") -#pragma comment(linker, "/export:mono_class_setup_nested_types") -#pragma comment(linker, "/export:mono_class_setup_parent") -#pragma comment(linker, "/export:mono_class_setup_properties") -#pragma comment(linker, "/export:mono_class_setup_runtime_info") -#pragma comment(linker, "/export:mono_class_setup_supertypes") -#pragma comment(linker, "/export:mono_class_setup_vtable") -#pragma comment(linker, "/export:mono_class_setup_vtable_general") -#pragma comment(linker, "/export:mono_class_static_field_address") -#pragma comment(linker, "/export:mono_class_try_get_com_object_class") -#pragma comment(linker, "/export:mono_class_try_get_generic_class") -#pragma comment(linker, "/export:mono_class_try_get_generic_container") -#pragma comment(linker, "/export:mono_class_try_get_safehandle_class") -#pragma comment(linker, "/export:mono_class_try_get_vtable") -#pragma comment(linker, "/export:mono_class_try_load_from_name") -#pragma comment(linker, "/export:mono_class_value_size") -#pragma comment(linker, "/export:mono_class_vtable") -#pragma comment(linker, "/export:mono_class_vtable_checked") -#pragma comment(linker, "/export:mono_custom_attrs_construct") -#pragma comment(linker, "/export:mono_custom_attrs_free") -#pragma comment(linker, "/export:mono_custom_attrs_from_assembly") -#pragma comment(linker, "/export:mono_custom_attrs_from_assembly_checked") -#pragma comment(linker, "/export:mono_custom_attrs_from_builders") -#pragma comment(linker, "/export:mono_custom_attrs_from_class") -#pragma comment(linker, "/export:mono_custom_attrs_from_class_checked") -#pragma comment(linker, "/export:mono_custom_attrs_from_event") -#pragma comment(linker, "/export:mono_custom_attrs_from_event_checked") -#pragma comment(linker, "/export:mono_custom_attrs_from_field") -#pragma comment(linker, "/export:mono_custom_attrs_from_field_checked") -#pragma comment(linker, "/export:mono_custom_attrs_from_index") -#pragma comment(linker, "/export:mono_custom_attrs_from_index_checked") -#pragma comment(linker, "/export:mono_custom_attrs_from_method") -#pragma comment(linker, "/export:mono_custom_attrs_from_method_checked") -#pragma comment(linker, "/export:mono_custom_attrs_from_param") -#pragma comment(linker, "/export:mono_custom_attrs_from_param_checked") -#pragma comment(linker, "/export:mono_custom_attrs_from_property") -#pragma comment(linker, "/export:mono_custom_attrs_from_property_checked") -#pragma comment(linker, "/export:mono_custom_attrs_get_attr") -#pragma comment(linker, "/export:mono_custom_attrs_get_attr_checked") -#pragma comment(linker, "/export:mono_custom_attrs_has_attr") -#pragma comment(linker, "/export:mono_debug_add_aot_method") -#pragma comment(linker, "/export:mono_debug_add_delegate_trampoline") -#pragma comment(linker, "/export:mono_debug_add_method") -#pragma comment(linker, "/export:mono_debug_cleanup") -#pragma comment(linker, "/export:mono_debug_close_image") -#pragma comment(linker, "/export:mono_debug_close_method") -#pragma comment(linker, "/export:mono_debug_close_mono_symbol_file") -#pragma comment(linker, "/export:mono_debug_count") -#pragma comment(linker, "/export:mono_debug_domain_create") -#pragma comment(linker, "/export:mono_debug_domain_unload") -#pragma comment(linker, "/export:mono_debug_enabled") -#pragma comment(linker, "/export:mono_debug_find_method") -#pragma comment(linker, "/export:mono_debug_free_locals") -#pragma comment(linker, "/export:mono_debug_free_method") -#pragma comment(linker, "/export:mono_debug_free_method_async_debug_info") -#pragma comment(linker, "/export:mono_debug_free_method_jit_info") -#pragma comment(linker, "/export:mono_debug_free_source_location") -#pragma comment(linker, "/export:mono_debug_get_handle") -#pragma comment(linker, "/export:mono_debug_get_seq_points") -#pragma comment(linker, "/export:mono_debug_il_offset_from_address") -#pragma comment(linker, "/export:mono_debug_image_has_debug_info") -#pragma comment(linker, "/export:mono_debug_init") -#pragma comment(linker, "/export:mono_debug_init_method") -#pragma comment(linker, "/export:mono_debug_lookup_locals") -#pragma comment(linker, "/export:mono_debug_lookup_method") -#pragma comment(linker, "/export:mono_debug_lookup_method_addresses") -#pragma comment(linker, "/export:mono_debug_lookup_method_async_debug_info") -#pragma comment(linker, "/export:mono_debug_lookup_source_location") -#pragma comment(linker, "/export:mono_debug_lookup_source_location_by_il") -#pragma comment(linker, "/export:mono_debug_method_lookup_location") -#pragma comment(linker, "/export:mono_debug_open_block") -#pragma comment(linker, "/export:mono_debug_open_method") -#pragma comment(linker, "/export:mono_debug_open_mono_symbols") -#pragma comment(linker, "/export:mono_debug_personality") -#pragma comment(linker, "/export:mono_debug_print_stack_frame") -#pragma comment(linker, "/export:mono_debug_print_vars") -#pragma comment(linker, "/export:mono_debug_record_line_number") -#pragma comment(linker, "/export:mono_debug_remove_method") -#pragma comment(linker, "/export:mono_debug_serialize_debug_info") -#pragma comment(linker, "/export:mono_debug_symfile_free_location") -#pragma comment(linker, "/export:mono_debug_symfile_get_seq_points") -#pragma comment(linker, "/export:mono_debug_symfile_is_loaded") -#pragma comment(linker, "/export:mono_debug_symfile_lookup_locals") -#pragma comment(linker, "/export:mono_debug_symfile_lookup_location") -#pragma comment(linker, "/export:mono_debug_symfile_lookup_method") -#pragma comment(linker, "/export:mono_domain_alloc") -#pragma comment(linker, "/export:mono_domain_alloc0") -#pragma comment(linker, "/export:mono_domain_alloc0_lock_free") -#pragma comment(linker, "/export:mono_domain_assembly_open") -#pragma comment(linker, "/export:mono_domain_assembly_open_internal") -#pragma comment(linker, "/export:mono_domain_assembly_postload_search") -#pragma comment(linker, "/export:mono_domain_code_commit") -#pragma comment(linker, "/export:mono_domain_code_foreach") -#pragma comment(linker, "/export:mono_domain_code_reserve") -#pragma comment(linker, "/export:mono_domain_code_reserve_align") -#pragma comment(linker, "/export:mono_domain_create") -#pragma comment(linker, "/export:mono_domain_create_appdomain") -#pragma comment(linker, "/export:mono_domain_finalize") -#pragma comment(linker, "/export:mono_domain_foreach") -#pragma comment(linker, "/export:mono_domain_free") -#pragma comment(linker, "/export:mono_domain_from_appdomain") -#pragma comment(linker, "/export:mono_domain_get") -#pragma comment(linker, "/export:mono_domain_get_assemblies") -#pragma comment(linker, "/export:mono_domain_get_by_id") -#pragma comment(linker, "/export:mono_domain_get_friendly_name") -#pragma comment(linker, "/export:mono_domain_get_id") -#pragma comment(linker, "/export:mono_domain_has_type_resolve") -#pragma comment(linker, "/export:mono_domain_is_unloading") -#pragma comment(linker, "/export:mono_domain_lock") -#pragma comment(linker, "/export:mono_domain_owns_vtable_slot") -#pragma comment(linker, "/export:mono_domain_parse_assembly_bindings") -#pragma comment(linker, "/export:mono_domain_set") -#pragma comment(linker, "/export:mono_domain_set_config") -#pragma comment(linker, "/export:mono_domain_set_config_checked") -#pragma comment(linker, "/export:mono_domain_set_internal") -#pragma comment(linker, "/export:mono_domain_set_internal_with_options") -#pragma comment(linker, "/export:mono_domain_set_options_from_config") -#pragma comment(linker, "/export:mono_domain_try_type_resolve") -#pragma comment(linker, "/export:mono_domain_try_type_resolve_name") -#pragma comment(linker, "/export:mono_domain_try_type_resolve_typebuilder") -#pragma comment(linker, "/export:mono_domain_try_unload") -#pragma comment(linker, "/export:mono_domain_unload") -#pragma comment(linker, "/export:mono_domain_unlock") -#pragma comment(linker, "/export:mono_domain_unset") -#pragma comment(linker, "/export:mono_exception_from_name") -#pragma comment(linker, "/export:mono_exception_from_name_domain") -#pragma comment(linker, "/export:mono_exception_from_name_msg") -#pragma comment(linker, "/export:mono_exception_from_name_two_strings") -#pragma comment(linker, "/export:mono_exception_from_name_two_strings_checked") -#pragma comment(linker, "/export:mono_exception_from_token") -#pragma comment(linker, "/export:mono_exception_from_token_two_strings") -#pragma comment(linker, "/export:mono_exception_from_token_two_strings_checked") -#pragma comment(linker, "/export:mono_exception_get_managed_backtrace") -#pragma comment(linker, "/export:mono_exception_handle_get_native_backtrace") -#pragma comment(linker, "/export:mono_exception_new_argument") -#pragma comment(linker, "/export:mono_exception_new_argument_null") -#pragma comment(linker, "/export:mono_exception_new_by_name_msg") -#pragma comment(linker, "/export:mono_exception_new_invalid_operation") -#pragma comment(linker, "/export:mono_exception_new_serialization") -#pragma comment(linker, "/export:mono_exception_new_thread_abort") -#pragma comment(linker, "/export:mono_exception_new_thread_interrupted") -#pragma comment(linker, "/export:mono_exception_walk_trace") -#pragma comment(linker, "/export:mono_field_from_token") -#pragma comment(linker, "/export:mono_field_from_token_checked") -#pragma comment(linker, "/export:mono_field_full_name") -#pragma comment(linker, "/export:mono_field_get_data") -#pragma comment(linker, "/export:mono_field_get_flags") -#pragma comment(linker, "/export:mono_field_get_name") -#pragma comment(linker, "/export:mono_field_get_object") -#pragma comment(linker, "/export:mono_field_get_object_checked") -#pragma comment(linker, "/export:mono_field_get_object_handle") -#pragma comment(linker, "/export:mono_field_get_offset") -#pragma comment(linker, "/export:mono_field_get_parent") -#pragma comment(linker, "/export:mono_field_get_type") -#pragma comment(linker, "/export:mono_field_get_type_checked") -#pragma comment(linker, "/export:mono_field_get_value") -#pragma comment(linker, "/export:mono_field_get_value_internal") -#pragma comment(linker, "/export:mono_field_get_value_object") -#pragma comment(linker, "/export:mono_field_get_value_object_checked") -#pragma comment(linker, "/export:mono_field_resolve_type") -#pragma comment(linker, "/export:mono_field_set_value") -#pragma comment(linker, "/export:mono_field_static_get_value") -#pragma comment(linker, "/export:mono_field_static_get_value_checked") -#pragma comment(linker, "/export:mono_field_static_get_value_for_thread") -#pragma comment(linker, "/export:mono_field_static_set_value") -#pragma comment(linker, "/export:mono_free") -#pragma comment(linker, "/export:mono_free_address_info") -#pragma comment(linker, "/export:mono_free_altstack") -#pragma comment(linker, "/export:mono_free_bstr") -#pragma comment(linker, "/export:mono_free_loop_info") -#pragma comment(linker, "/export:mono_free_lparray") -#pragma comment(linker, "/export:mono_free_method") -#pragma comment(linker, "/export:mono_free_verify_list") -#pragma comment(linker, "/export:mono_gc_add_memory_pressure") -#pragma comment(linker, "/export:mono_gc_alloc_array") -#pragma comment(linker, "/export:mono_gc_alloc_fixed") -#pragma comment(linker, "/export:mono_gc_alloc_fixed_no_descriptor") -#pragma comment(linker, "/export:mono_gc_alloc_handle_array") -#pragma comment(linker, "/export:mono_gc_alloc_handle_mature") -#pragma comment(linker, "/export:mono_gc_alloc_handle_obj") -#pragma comment(linker, "/export:mono_gc_alloc_handle_pinned_obj") -#pragma comment(linker, "/export:mono_gc_alloc_handle_string") -#pragma comment(linker, "/export:mono_gc_alloc_handle_vector") -#pragma comment(linker, "/export:mono_gc_alloc_mature") -#pragma comment(linker, "/export:mono_gc_alloc_obj") -#pragma comment(linker, "/export:mono_gc_alloc_pinned_obj") -#pragma comment(linker, "/export:mono_gc_alloc_string") -#pragma comment(linker, "/export:mono_gc_alloc_vector") -#pragma comment(linker, "/export:mono_gc_base_cleanup") -#pragma comment(linker, "/export:mono_gc_base_init") -#pragma comment(linker, "/export:mono_gc_bzero_aligned") -#pragma comment(linker, "/export:mono_gc_bzero_atomic") -#pragma comment(linker, "/export:mono_gc_card_table_nursery_check") -#pragma comment(linker, "/export:mono_gc_cleanup") -#pragma comment(linker, "/export:mono_gc_clear_assembly") -#pragma comment(linker, "/export:mono_gc_clear_domain") -#pragma comment(linker, "/export:mono_gc_collect") -#pragma comment(linker, "/export:mono_gc_collection_count") -#pragma comment(linker, "/export:mono_gc_conservatively_scan_area") -#pragma comment(linker, "/export:mono_gc_debug_set") -#pragma comment(linker, "/export:mono_gc_deregister_root") -#pragma comment(linker, "/export:mono_gc_dllmain") -#pragma comment(linker, "/export:mono_gc_ephemeron_array_add") -#pragma comment(linker, "/export:mono_gc_finalize_assembly") -#pragma comment(linker, "/export:mono_gc_finalize_domain") -#pragma comment(linker, "/export:mono_gc_finalize_notify") -#pragma comment(linker, "/export:mono_gc_free_fixed") -#pragma comment(linker, "/export:mono_gc_get_aligned_size_for_allocator") -#pragma comment(linker, "/export:mono_gc_get_bitmap_for_descr") -#pragma comment(linker, "/export:mono_gc_get_card_table") -#pragma comment(linker, "/export:mono_gc_get_description") -#pragma comment(linker, "/export:mono_gc_get_gc_callbacks") -#pragma comment(linker, "/export:mono_gc_get_gc_name") -#pragma comment(linker, "/export:mono_gc_get_generation") -#pragma comment(linker, "/export:mono_gc_get_heap_size") -#pragma comment(linker, "/export:mono_gc_get_logfile") -#pragma comment(linker, "/export:mono_gc_get_los_limit") -#pragma comment(linker, "/export:mono_gc_get_managed_allocator") -#pragma comment(linker, "/export:mono_gc_get_managed_allocator_by_type") -#pragma comment(linker, "/export:mono_gc_get_managed_allocator_types") -#pragma comment(linker, "/export:mono_gc_get_managed_array_allocator") -#pragma comment(linker, "/export:mono_gc_get_nursery") -#pragma comment(linker, "/export:mono_gc_get_range_copy_func") -#pragma comment(linker, "/export:mono_gc_get_restart_signal") -#pragma comment(linker, "/export:mono_gc_get_specific_write_barrier") -#pragma comment(linker, "/export:mono_gc_get_suspend_signal") -#pragma comment(linker, "/export:mono_gc_get_target_card_table") -#pragma comment(linker, "/export:mono_gc_get_used_size") -#pragma comment(linker, "/export:mono_gc_get_vtable") -#pragma comment(linker, "/export:mono_gc_get_vtable_bits") -#pragma comment(linker, "/export:mono_gc_get_write_barrier") -#pragma comment(linker, "/export:mono_gc_init") -#pragma comment(linker, "/export:mono_gc_invoke_finalizers") -#pragma comment(linker, "/export:mono_gc_invoke_with_gc_lock") -#pragma comment(linker, "/export:mono_gc_is_critical_method") -#pragma comment(linker, "/export:mono_gc_is_disabled") -#pragma comment(linker, "/export:mono_gc_is_finalizer_internal_thread") -#pragma comment(linker, "/export:mono_gc_is_finalizer_thread") -#pragma comment(linker, "/export:mono_gc_is_gc_thread") -#pragma comment(linker, "/export:mono_gc_is_moving") -#pragma comment(linker, "/export:mono_gc_is_null") -#pragma comment(linker, "/export:mono_gc_make_descr_for_array") -#pragma comment(linker, "/export:mono_gc_make_descr_for_object") -#pragma comment(linker, "/export:mono_gc_make_descr_for_string") -#pragma comment(linker, "/export:mono_gc_make_descr_from_bitmap") -#pragma comment(linker, "/export:mono_gc_make_root_descr_all_refs") -#pragma comment(linker, "/export:mono_gc_make_root_descr_user") -#pragma comment(linker, "/export:mono_gc_make_vector_descr") -#pragma comment(linker, "/export:mono_gc_max_generation") -#pragma comment(linker, "/export:mono_gc_memmove_aligned") -#pragma comment(linker, "/export:mono_gc_memmove_atomic") -#pragma comment(linker, "/export:mono_gc_params_set") -#pragma comment(linker, "/export:mono_gc_parse_environment_string_extract_number") -#pragma comment(linker, "/export:mono_gc_pending_finalizers") -#pragma comment(linker, "/export:mono_gc_precise_stack_mark_enabled") -#pragma comment(linker, "/export:mono_gc_reference_queue_add") -#pragma comment(linker, "/export:mono_gc_reference_queue_foreach_remove") -#pragma comment(linker, "/export:mono_gc_reference_queue_foreach_remove2") -#pragma comment(linker, "/export:mono_gc_reference_queue_free") -#pragma comment(linker, "/export:mono_gc_reference_queue_new") -#pragma comment(linker, "/export:mono_gc_register_altstack") -#pragma comment(linker, "/export:mono_gc_register_bridge_callbacks") -#pragma comment(linker, "/export:mono_gc_register_finalizer_callbacks") -#pragma comment(linker, "/export:mono_gc_register_for_finalization") -#pragma comment(linker, "/export:mono_gc_register_obj_with_weak_fields") -#pragma comment(linker, "/export:mono_gc_register_object_with_weak_fields") -#pragma comment(linker, "/export:mono_gc_register_root") -#pragma comment(linker, "/export:mono_gc_register_root_wbarrier") -#pragma comment(linker, "/export:mono_gc_run_finalize") -#pragma comment(linker, "/export:mono_gc_scan_for_specific_ref") -#pragma comment(linker, "/export:mono_gc_scan_object") -#pragma comment(linker, "/export:mono_gc_set_desktop_mode") -#pragma comment(linker, "/export:mono_gc_set_gc_callbacks") -#pragma comment(linker, "/export:mono_gc_set_stack_end") -#pragma comment(linker, "/export:mono_gc_set_string_length") -#pragma comment(linker, "/export:mono_gc_skip_thread_changed") -#pragma comment(linker, "/export:mono_gc_skip_thread_changing") -#pragma comment(linker, "/export:mono_gc_stats") -#pragma comment(linker, "/export:mono_gc_suspend_finalizers") -#pragma comment(linker, "/export:mono_gc_thread_attach") -#pragma comment(linker, "/export:mono_gc_thread_detach_with_lock") -#pragma comment(linker, "/export:mono_gc_thread_in_critical_region") -#pragma comment(linker, "/export:mono_gc_toggleref_add") -#pragma comment(linker, "/export:mono_gc_toggleref_register_callback") -#pragma comment(linker, "/export:mono_gc_user_markers_supported") -#pragma comment(linker, "/export:mono_gc_wait_for_bridge_processing") -#pragma comment(linker, "/export:mono_gc_walk_heap") -#pragma comment(linker, "/export:mono_gc_wbarrier_arrayref_copy") -#pragma comment(linker, "/export:mono_gc_wbarrier_generic_nostore") -#pragma comment(linker, "/export:mono_gc_wbarrier_generic_store") -#pragma comment(linker, "/export:mono_gc_wbarrier_generic_store_atomic") -#pragma comment(linker, "/export:mono_gc_wbarrier_object_copy") -#pragma comment(linker, "/export:mono_gc_wbarrier_object_copy_handle") -#pragma comment(linker, "/export:mono_gc_wbarrier_range_copy") -#pragma comment(linker, "/export:mono_gc_wbarrier_set_arrayref") -#pragma comment(linker, "/export:mono_gc_wbarrier_set_field") -#pragma comment(linker, "/export:mono_gc_wbarrier_value_copy") -#pragma comment(linker, "/export:mono_gchandle_free") -#pragma comment(linker, "/export:mono_gchandle_free_domain") -#pragma comment(linker, "/export:mono_gchandle_from_handle") -#pragma comment(linker, "/export:mono_gchandle_get_target") -#pragma comment(linker, "/export:mono_gchandle_get_target_handle") -#pragma comment(linker, "/export:mono_gchandle_is_in_domain") -#pragma comment(linker, "/export:mono_gchandle_new") -#pragma comment(linker, "/export:mono_gchandle_new_weakref") -#pragma comment(linker, "/export:mono_gchandle_set_target") -#pragma comment(linker, "/export:mono_gchandle_set_target_handle") -#pragma comment(linker, "/export:mono_get_addr_from_ftnptr") -#pragma comment(linker, "/export:mono_get_address_info") -#pragma comment(linker, "/export:mono_get_anonymous_container_for_image") -#pragma comment(linker, "/export:mono_get_aot_cache_config") -#pragma comment(linker, "/export:mono_get_array_class") -#pragma comment(linker, "/export:mono_get_assembly_object") -#pragma comment(linker, "/export:mono_get_boolean_class") -#pragma comment(linker, "/export:mono_get_byte_class") -#pragma comment(linker, "/export:mono_get_cached_unwind_info") -#pragma comment(linker, "/export:mono_get_call_filter") -#pragma comment(linker, "/export:mono_get_char_class") -#pragma comment(linker, "/export:mono_get_config_dir") -#pragma comment(linker, "/export:mono_get_constant_value_from_blob") -#pragma comment(linker, "/export:mono_get_context_capture_method") -#pragma comment(linker, "/export:mono_get_corlib") -#pragma comment(linker, "/export:mono_get_dbnull_object") -#pragma comment(linker, "/export:mono_get_delegate_begin_invoke") -#pragma comment(linker, "/export:mono_get_delegate_begin_invoke_checked") -#pragma comment(linker, "/export:mono_get_delegate_end_invoke") -#pragma comment(linker, "/export:mono_get_delegate_end_invoke_checked") -#pragma comment(linker, "/export:mono_get_delegate_invoke") -#pragma comment(linker, "/export:mono_get_delegate_invoke_checked") -#pragma comment(linker, "/export:mono_get_delegate_virtual_invoke_impl") -#pragma comment(linker, "/export:mono_get_delegate_virtual_invoke_impl_name") -#pragma comment(linker, "/export:mono_get_double_class") -#pragma comment(linker, "/export:mono_get_eh_callbacks") -#pragma comment(linker, "/export:mono_get_enum_class") -#pragma comment(linker, "/export:mono_get_exception_appdomain_unloaded") -#pragma comment(linker, "/export:mono_get_exception_argument") -#pragma comment(linker, "/export:mono_get_exception_argument_null") -#pragma comment(linker, "/export:mono_get_exception_argument_out_of_range") -#pragma comment(linker, "/export:mono_get_exception_arithmetic") -#pragma comment(linker, "/export:mono_get_exception_array_type_mismatch") -#pragma comment(linker, "/export:mono_get_exception_bad_image_format") -#pragma comment(linker, "/export:mono_get_exception_bad_image_format2") -#pragma comment(linker, "/export:mono_get_exception_cannot_unload_appdomain") -#pragma comment(linker, "/export:mono_get_exception_class") -#pragma comment(linker, "/export:mono_get_exception_divide_by_zero") -#pragma comment(linker, "/export:mono_get_exception_execution_engine") -#pragma comment(linker, "/export:mono_get_exception_field_access") -#pragma comment(linker, "/export:mono_get_exception_field_access_msg") -#pragma comment(linker, "/export:mono_get_exception_file_not_found") -#pragma comment(linker, "/export:mono_get_exception_file_not_found2") -#pragma comment(linker, "/export:mono_get_exception_index_out_of_range") -#pragma comment(linker, "/export:mono_get_exception_invalid_cast") -#pragma comment(linker, "/export:mono_get_exception_invalid_operation") -#pragma comment(linker, "/export:mono_get_exception_io") -#pragma comment(linker, "/export:mono_get_exception_method_access") -#pragma comment(linker, "/export:mono_get_exception_method_access_msg") -#pragma comment(linker, "/export:mono_get_exception_missing_field") -#pragma comment(linker, "/export:mono_get_exception_missing_method") -#pragma comment(linker, "/export:mono_get_exception_not_implemented") -#pragma comment(linker, "/export:mono_get_exception_not_supported") -#pragma comment(linker, "/export:mono_get_exception_null_reference") -#pragma comment(linker, "/export:mono_get_exception_out_of_memory") -#pragma comment(linker, "/export:mono_get_exception_out_of_memory_handle") -#pragma comment(linker, "/export:mono_get_exception_overflow") -#pragma comment(linker, "/export:mono_get_exception_reflection_type_load") -#pragma comment(linker, "/export:mono_get_exception_reflection_type_load_checked") -#pragma comment(linker, "/export:mono_get_exception_runtime_wrapped") -#pragma comment(linker, "/export:mono_get_exception_runtime_wrapped_handle") -#pragma comment(linker, "/export:mono_get_exception_security") -#pragma comment(linker, "/export:mono_get_exception_serialization") -#pragma comment(linker, "/export:mono_get_exception_stack_overflow") -#pragma comment(linker, "/export:mono_get_exception_synchronization_lock") -#pragma comment(linker, "/export:mono_get_exception_thread_abort") -#pragma comment(linker, "/export:mono_get_exception_thread_interrupted") -#pragma comment(linker, "/export:mono_get_exception_thread_state") -#pragma comment(linker, "/export:mono_get_exception_type_initialization") -#pragma comment(linker, "/export:mono_get_exception_type_initialization_handle") -#pragma comment(linker, "/export:mono_get_exception_type_load") -#pragma comment(linker, "/export:mono_get_generic_trampoline_name") -#pragma comment(linker, "/export:mono_get_generic_trampoline_simple_name") -#pragma comment(linker, "/export:mono_get_hazardous_pointer") -#pragma comment(linker, "/export:mono_get_image_for_generic_param") -#pragma comment(linker, "/export:mono_get_inflated_method") -#pragma comment(linker, "/export:mono_get_int16_class") -#pragma comment(linker, "/export:mono_get_int32_class") -#pragma comment(linker, "/export:mono_get_int64_class") -#pragma comment(linker, "/export:mono_get_intptr_class") -#pragma comment(linker, "/export:mono_get_jit_icall_info") -#pragma comment(linker, "/export:mono_get_lmf") -#pragma comment(linker, "/export:mono_get_local_interfaces") -#pragma comment(linker, "/export:mono_get_machine_config") -#pragma comment(linker, "/export:mono_get_method") -#pragma comment(linker, "/export:mono_get_method_checked") -#pragma comment(linker, "/export:mono_get_method_constrained") -#pragma comment(linker, "/export:mono_get_method_constrained_checked") -#pragma comment(linker, "/export:mono_get_method_constrained_with_method") -#pragma comment(linker, "/export:mono_get_method_from_ip") -#pragma comment(linker, "/export:mono_get_method_full") -#pragma comment(linker, "/export:mono_get_method_object") -#pragma comment(linker, "/export:mono_get_module_file_name") -#pragma comment(linker, "/export:mono_get_native_calli_wrapper") -#pragma comment(linker, "/export:mono_get_object_class") -#pragma comment(linker, "/export:mono_get_object_from_blob") -#pragma comment(linker, "/export:mono_get_optimizations_for_method") -#pragma comment(linker, "/export:mono_get_restore_context") -#pragma comment(linker, "/export:mono_get_rethrow_exception") -#pragma comment(linker, "/export:mono_get_rgctx_fetch_trampoline_name") -#pragma comment(linker, "/export:mono_get_root_domain") -#pragma comment(linker, "/export:mono_get_runtime_build_info") -#pragma comment(linker, "/export:mono_get_runtime_callbacks") -#pragma comment(linker, "/export:mono_get_runtime_info") -#pragma comment(linker, "/export:mono_get_sbyte_class") -#pragma comment(linker, "/export:mono_get_seq_points") -#pragma comment(linker, "/export:mono_get_shared_generic_inst") -#pragma comment(linker, "/export:mono_get_single_class") -#pragma comment(linker, "/export:mono_get_special_static_data") -#pragma comment(linker, "/export:mono_get_special_static_data_for_thread") -#pragma comment(linker, "/export:mono_get_string_class") -#pragma comment(linker, "/export:mono_get_thread_class") -#pragma comment(linker, "/export:mono_get_throw_corlib_exception") -#pragma comment(linker, "/export:mono_get_throw_exception") -#pragma comment(linker, "/export:mono_get_throw_exception_addr") -#pragma comment(linker, "/export:mono_get_trampoline_code") -#pragma comment(linker, "/export:mono_get_trampoline_func") -#pragma comment(linker, "/export:mono_get_uint16_class") -#pragma comment(linker, "/export:mono_get_uint32_class") -#pragma comment(linker, "/export:mono_get_uint64_class") -#pragma comment(linker, "/export:mono_get_uintptr_class") -#pragma comment(linker, "/export:mono_get_void_class") -#pragma comment(linker, "/export:mono_image_add_to_name_cache") -#pragma comment(linker, "/export:mono_image_addref") -#pragma comment(linker, "/export:mono_image_alloc") -#pragma comment(linker, "/export:mono_image_alloc0") -#pragma comment(linker, "/export:mono_image_append_class_to_reflection_info_set") -#pragma comment(linker, "/export:mono_image_build_metadata") -#pragma comment(linker, "/export:mono_image_check_for_module_cctor") -#pragma comment(linker, "/export:mono_image_close") -#pragma comment(linker, "/export:mono_image_close_except_pools") -#pragma comment(linker, "/export:mono_image_close_finish") -#pragma comment(linker, "/export:mono_image_create_pefile") -#pragma comment(linker, "/export:mono_image_create_token") -#pragma comment(linker, "/export:mono_image_ensure_section") -#pragma comment(linker, "/export:mono_image_ensure_section_idx") -#pragma comment(linker, "/export:mono_image_fixup_vtable") -#pragma comment(linker, "/export:mono_image_g_malloc0") -#pragma comment(linker, "/export:mono_image_get_assembly") -#pragma comment(linker, "/export:mono_image_get_entry_point") -#pragma comment(linker, "/export:mono_image_get_filename") -#pragma comment(linker, "/export:mono_image_get_guid") -#pragma comment(linker, "/export:mono_image_get_methodref_token") -#pragma comment(linker, "/export:mono_image_get_name") -#pragma comment(linker, "/export:mono_image_get_public_key") -#pragma comment(linker, "/export:mono_image_get_resource") -#pragma comment(linker, "/export:mono_image_get_strong_name") -#pragma comment(linker, "/export:mono_image_get_table_info") -#pragma comment(linker, "/export:mono_image_get_table_rows") -#pragma comment(linker, "/export:mono_image_has_authenticode_entry") -#pragma comment(linker, "/export:mono_image_init") -#pragma comment(linker, "/export:mono_image_init_name_cache") -#pragma comment(linker, "/export:mono_image_insert_string") -#pragma comment(linker, "/export:mono_image_is_dynamic") -#pragma comment(linker, "/export:mono_image_load_cli_data") -#pragma comment(linker, "/export:mono_image_load_cli_header") -#pragma comment(linker, "/export:mono_image_load_file_for_image") -#pragma comment(linker, "/export:mono_image_load_file_for_image_checked") -#pragma comment(linker, "/export:mono_image_load_metadata") -#pragma comment(linker, "/export:mono_image_load_module") -#pragma comment(linker, "/export:mono_image_load_module_checked") -#pragma comment(linker, "/export:mono_image_load_names") -#pragma comment(linker, "/export:mono_image_load_pe_data") -#pragma comment(linker, "/export:mono_image_loaded") -#pragma comment(linker, "/export:mono_image_loaded_by_guid") -#pragma comment(linker, "/export:mono_image_loaded_by_guid_full") -#pragma comment(linker, "/export:mono_image_loaded_full") -#pragma comment(linker, "/export:mono_image_loaded_internal") -#pragma comment(linker, "/export:mono_image_lock") -#pragma comment(linker, "/export:mono_image_lookup_resource") -#pragma comment(linker, "/export:mono_image_open") -#pragma comment(linker, "/export:mono_image_open_a_lot") -#pragma comment(linker, "/export:mono_image_open_from_data") -#pragma comment(linker, "/export:mono_image_open_from_data_full") -#pragma comment(linker, "/export:mono_image_open_from_data_internal") -#pragma comment(linker, "/export:mono_image_open_from_data_with_name") -#pragma comment(linker, "/export:mono_image_open_from_module_handle") -#pragma comment(linker, "/export:mono_image_open_full") -#pragma comment(linker, "/export:mono_image_open_metadata_only") -#pragma comment(linker, "/export:mono_image_open_raw") -#pragma comment(linker, "/export:mono_image_property_insert") -#pragma comment(linker, "/export:mono_image_property_lookup") -#pragma comment(linker, "/export:mono_image_property_remove") -#pragma comment(linker, "/export:mono_image_rva_map") -#pragma comment(linker, "/export:mono_image_set_alloc") -#pragma comment(linker, "/export:mono_image_set_alloc0") -#pragma comment(linker, "/export:mono_image_set_description") -#pragma comment(linker, "/export:mono_image_set_lock") -#pragma comment(linker, "/export:mono_image_set_strdup") -#pragma comment(linker, "/export:mono_image_set_unlock") -#pragma comment(linker, "/export:mono_image_strdup") -#pragma comment(linker, "/export:mono_image_strdup_printf") -#pragma comment(linker, "/export:mono_image_strdup_vprintf") -#pragma comment(linker, "/export:mono_image_strerror") -#pragma comment(linker, "/export:mono_image_strong_name_position") -#pragma comment(linker, "/export:mono_image_unlock") -#pragma comment(linker, "/export:mono_metadata_blob_heap") -#pragma comment(linker, "/export:mono_metadata_blob_heap_checked") -#pragma comment(linker, "/export:mono_metadata_clean_for_image") -#pragma comment(linker, "/export:mono_metadata_cleanup") -#pragma comment(linker, "/export:mono_metadata_compute_size") -#pragma comment(linker, "/export:mono_metadata_compute_table_bases") -#pragma comment(linker, "/export:mono_metadata_create_anon_gparam") -#pragma comment(linker, "/export:mono_metadata_cross_helpers_run") -#pragma comment(linker, "/export:mono_metadata_custom_attrs_from_index") -#pragma comment(linker, "/export:mono_metadata_declsec_from_index") -#pragma comment(linker, "/export:mono_metadata_decode_blob_size") -#pragma comment(linker, "/export:mono_metadata_decode_row") -#pragma comment(linker, "/export:mono_metadata_decode_row_checked") -#pragma comment(linker, "/export:mono_metadata_decode_row_col") -#pragma comment(linker, "/export:mono_metadata_decode_signed_value") -#pragma comment(linker, "/export:mono_metadata_decode_table_row") -#pragma comment(linker, "/export:mono_metadata_decode_table_row_col") -#pragma comment(linker, "/export:mono_metadata_decode_value") -#pragma comment(linker, "/export:mono_metadata_encode_value") -#pragma comment(linker, "/export:mono_metadata_events_from_typedef") -#pragma comment(linker, "/export:mono_metadata_field_info") -#pragma comment(linker, "/export:mono_metadata_field_info_with_mempool") -#pragma comment(linker, "/export:mono_metadata_free_array") -#pragma comment(linker, "/export:mono_metadata_free_inflated_signature") -#pragma comment(linker, "/export:mono_metadata_free_marshal_spec") -#pragma comment(linker, "/export:mono_metadata_free_method_signature") -#pragma comment(linker, "/export:mono_metadata_free_mh") -#pragma comment(linker, "/export:mono_metadata_free_type") -#pragma comment(linker, "/export:mono_metadata_generic_class_is_valuetype") -#pragma comment(linker, "/export:mono_metadata_generic_context_equal") -#pragma comment(linker, "/export:mono_metadata_generic_context_hash") -#pragma comment(linker, "/export:mono_metadata_generic_inst_equal") -#pragma comment(linker, "/export:mono_metadata_generic_inst_hash") -#pragma comment(linker, "/export:mono_metadata_generic_param_equal") -#pragma comment(linker, "/export:mono_metadata_generic_param_hash") -#pragma comment(linker, "/export:mono_metadata_get_canonical_generic_inst") -#pragma comment(linker, "/export:mono_metadata_get_constant_index") -#pragma comment(linker, "/export:mono_metadata_get_corresponding_event_from_generic_type_definition") -#pragma comment(linker, "/export:mono_metadata_get_corresponding_field_from_generic_type_definition") -#pragma comment(linker, "/export:mono_metadata_get_corresponding_property_from_generic_type_definition") -#pragma comment(linker, "/export:mono_metadata_get_generic_inst") -#pragma comment(linker, "/export:mono_metadata_get_generic_param_row") -#pragma comment(linker, "/export:mono_metadata_get_image_set_for_class") -#pragma comment(linker, "/export:mono_metadata_get_image_set_for_method") -#pragma comment(linker, "/export:mono_metadata_get_inflated_signature") -#pragma comment(linker, "/export:mono_metadata_get_marshal_info") -#pragma comment(linker, "/export:mono_metadata_get_param_attrs") -#pragma comment(linker, "/export:mono_metadata_get_shared_type") -#pragma comment(linker, "/export:mono_metadata_guid_heap") -#pragma comment(linker, "/export:mono_metadata_has_generic_params") -#pragma comment(linker, "/export:mono_metadata_implmap_from_method") -#pragma comment(linker, "/export:mono_metadata_inflate_generic_inst") -#pragma comment(linker, "/export:mono_metadata_init") -#pragma comment(linker, "/export:mono_metadata_interfaces_from_typedef") -#pragma comment(linker, "/export:mono_metadata_interfaces_from_typedef_full") -#pragma comment(linker, "/export:mono_metadata_load_generic_param_constraints_checked") -#pragma comment(linker, "/export:mono_metadata_load_generic_params") -#pragma comment(linker, "/export:mono_metadata_localscope_from_methoddef") -#pragma comment(linker, "/export:mono_metadata_locate") -#pragma comment(linker, "/export:mono_metadata_locate_token") -#pragma comment(linker, "/export:mono_metadata_lookup_generic_class") -#pragma comment(linker, "/export:mono_metadata_method_has_param_attrs") -#pragma comment(linker, "/export:mono_metadata_methods_from_event") -#pragma comment(linker, "/export:mono_metadata_methods_from_property") -#pragma comment(linker, "/export:mono_metadata_nested_in_typedef") -#pragma comment(linker, "/export:mono_metadata_nesting_typedef") -#pragma comment(linker, "/export:mono_metadata_packing_from_typedef") -#pragma comment(linker, "/export:mono_metadata_parse_array") -#pragma comment(linker, "/export:mono_metadata_parse_custom_mod") -#pragma comment(linker, "/export:mono_metadata_parse_field_type") -#pragma comment(linker, "/export:mono_metadata_parse_generic_inst") -#pragma comment(linker, "/export:mono_metadata_parse_marshal_spec") -#pragma comment(linker, "/export:mono_metadata_parse_marshal_spec_full") -#pragma comment(linker, "/export:mono_metadata_parse_method_signature") -#pragma comment(linker, "/export:mono_metadata_parse_method_signature_full") -#pragma comment(linker, "/export:mono_metadata_parse_mh") -#pragma comment(linker, "/export:mono_metadata_parse_mh_full") -#pragma comment(linker, "/export:mono_metadata_parse_param") -#pragma comment(linker, "/export:mono_metadata_parse_signature") -#pragma comment(linker, "/export:mono_metadata_parse_signature_checked") -#pragma comment(linker, "/export:mono_metadata_parse_type") -#pragma comment(linker, "/export:mono_metadata_parse_type_checked") -#pragma comment(linker, "/export:mono_metadata_parse_typedef_or_ref") -#pragma comment(linker, "/export:mono_metadata_properties_from_typedef") -#pragma comment(linker, "/export:mono_metadata_read_constant_value") -#pragma comment(linker, "/export:mono_metadata_signature_alloc") -#pragma comment(linker, "/export:mono_metadata_signature_deep_dup") -#pragma comment(linker, "/export:mono_metadata_signature_dup") -#pragma comment(linker, "/export:mono_metadata_signature_dup_add_this") -#pragma comment(linker, "/export:mono_metadata_signature_dup_full") -#pragma comment(linker, "/export:mono_metadata_signature_dup_mempool") -#pragma comment(linker, "/export:mono_metadata_signature_equal") -#pragma comment(linker, "/export:mono_metadata_signature_size") -#pragma comment(linker, "/export:mono_metadata_str_hash") -#pragma comment(linker, "/export:mono_metadata_string_heap") -#pragma comment(linker, "/export:mono_metadata_string_heap_checked") -#pragma comment(linker, "/export:mono_metadata_token_from_dor") -#pragma comment(linker, "/export:mono_metadata_translate_token_index") -#pragma comment(linker, "/export:mono_metadata_type_dup") -#pragma comment(linker, "/export:mono_metadata_type_dup_with_cmods") -#pragma comment(linker, "/export:mono_metadata_type_equal") -#pragma comment(linker, "/export:mono_metadata_type_equal_full") -#pragma comment(linker, "/export:mono_metadata_type_hash") -#pragma comment(linker, "/export:mono_metadata_typedef_from_field") -#pragma comment(linker, "/export:mono_metadata_typedef_from_method") -#pragma comment(linker, "/export:mono_metadata_user_string") -#pragma comment(linker, "/export:mono_method_add_generic_virtual_invocation") -#pragma comment(linker, "/export:mono_method_alloc_generic_virtual_trampoline") -#pragma comment(linker, "/export:mono_method_body_get_object") -#pragma comment(linker, "/export:mono_method_body_get_object_handle") -#pragma comment(linker, "/export:mono_method_builder_ilgen_init") -#pragma comment(linker, "/export:mono_method_call_message_new") -#pragma comment(linker, "/export:mono_method_can_access_field") -#pragma comment(linker, "/export:mono_method_can_access_field_full") -#pragma comment(linker, "/export:mono_method_can_access_method") -#pragma comment(linker, "/export:mono_method_can_access_method_full") -#pragma comment(linker, "/export:mono_method_check_context_used") -#pragma comment(linker, "/export:mono_method_clear_object") -#pragma comment(linker, "/export:mono_method_construct_object_context") -#pragma comment(linker, "/export:mono_method_desc_free") -#pragma comment(linker, "/export:mono_method_desc_from_method") -#pragma comment(linker, "/export:mono_method_desc_full_match") -#pragma comment(linker, "/export:mono_method_desc_is_full") -#pragma comment(linker, "/export:mono_method_desc_match") -#pragma comment(linker, "/export:mono_method_desc_new") -#pragma comment(linker, "/export:mono_method_desc_search_in_class") -#pragma comment(linker, "/export:mono_method_desc_search_in_image") -#pragma comment(linker, "/export:mono_method_fill_runtime_generic_context") -#pragma comment(linker, "/export:mono_method_from_method_def_or_ref") -#pragma comment(linker, "/export:mono_method_full_name") -#pragma comment(linker, "/export:mono_method_get_base_method") -#pragma comment(linker, "/export:mono_method_get_class") -#pragma comment(linker, "/export:mono_method_get_context") -#pragma comment(linker, "/export:mono_method_get_context_general") -#pragma comment(linker, "/export:mono_method_get_declaring_generic_method") -#pragma comment(linker, "/export:mono_method_get_flags") -#pragma comment(linker, "/export:mono_method_get_full_name") -#pragma comment(linker, "/export:mono_method_get_generic_container") -#pragma comment(linker, "/export:mono_method_get_header") -#pragma comment(linker, "/export:mono_method_get_header_checked") -#pragma comment(linker, "/export:mono_method_get_header_internal") -#pragma comment(linker, "/export:mono_method_get_header_summary") -#pragma comment(linker, "/export:mono_method_get_imt_slot") -#pragma comment(linker, "/export:mono_method_get_index") -#pragma comment(linker, "/export:mono_method_get_last_managed") -#pragma comment(linker, "/export:mono_method_get_marshal_info") -#pragma comment(linker, "/export:mono_method_get_name") -#pragma comment(linker, "/export:mono_method_get_name_full") -#pragma comment(linker, "/export:mono_method_get_object") -#pragma comment(linker, "/export:mono_method_get_object_checked") -#pragma comment(linker, "/export:mono_method_get_object_handle") -#pragma comment(linker, "/export:mono_method_get_param_names") -#pragma comment(linker, "/export:mono_method_get_param_token") -#pragma comment(linker, "/export:mono_method_get_reflection_name") -#pragma comment(linker, "/export:mono_method_get_signature") -#pragma comment(linker, "/export:mono_method_get_signature_checked") -#pragma comment(linker, "/export:mono_method_get_signature_full") -#pragma comment(linker, "/export:mono_method_get_token") -#pragma comment(linker, "/export:mono_method_get_unmanaged_thunk") -#pragma comment(linker, "/export:mono_method_get_vtable_index") -#pragma comment(linker, "/export:mono_method_get_vtable_slot") -#pragma comment(linker, "/export:mono_method_get_wrapper_cache") -#pragma comment(linker, "/export:mono_method_get_wrapper_data") -#pragma comment(linker, "/export:mono_method_has_marshal_info") -#pragma comment(linker, "/export:mono_method_has_no_body") -#pragma comment(linker, "/export:mono_method_header_get_clauses") -#pragma comment(linker, "/export:mono_method_header_get_code") -#pragma comment(linker, "/export:mono_method_header_get_locals") -#pragma comment(linker, "/export:mono_method_header_get_num_clauses") -#pragma comment(linker, "/export:mono_method_is_from_assembly") -#pragma comment(linker, "/export:mono_method_is_generic_impl") -#pragma comment(linker, "/export:mono_method_is_generic_sharable") -#pragma comment(linker, "/export:mono_method_is_generic_sharable_full") -#pragma comment(linker, "/export:mono_method_lookup_or_register_info") -#pragma comment(linker, "/export:mono_method_needs_static_rgctx_invoke") -#pragma comment(linker, "/export:mono_method_print_code") -#pragma comment(linker, "/export:mono_method_return_message_restore") -#pragma comment(linker, "/export:mono_method_same_domain") -#pragma comment(linker, "/export:mono_method_search_in_array_class") -#pragma comment(linker, "/export:mono_method_set_generic_container") -#pragma comment(linker, "/export:mono_method_signature") -#pragma comment(linker, "/export:mono_method_signature_checked") -#pragma comment(linker, "/export:mono_method_verify") -#pragma comment(linker, "/export:mono_method_verify_with_current_settings") -#pragma comment(linker, "/export:mono_object_castclass_mbyref") -#pragma comment(linker, "/export:mono_object_castclass_unbox") -#pragma comment(linker, "/export:mono_object_castclass_with_cache") -#pragma comment(linker, "/export:mono_object_clone") -#pragma comment(linker, "/export:mono_object_clone_checked") -#pragma comment(linker, "/export:mono_object_clone_handle") -#pragma comment(linker, "/export:mono_object_describe") -#pragma comment(linker, "/export:mono_object_describe_fields") -#pragma comment(linker, "/export:mono_object_get_class") -#pragma comment(linker, "/export:mono_object_get_data") -#pragma comment(linker, "/export:mono_object_get_domain") -#pragma comment(linker, "/export:mono_object_get_size") -#pragma comment(linker, "/export:mono_object_get_virtual_method") -#pragma comment(linker, "/export:mono_object_get_vtable") -#pragma comment(linker, "/export:mono_object_handle_get_virtual_method") -#pragma comment(linker, "/export:mono_object_handle_isinst") -#pragma comment(linker, "/export:mono_object_handle_isinst_mbyref") -#pragma comment(linker, "/export:mono_object_handle_pin_unbox") -#pragma comment(linker, "/export:mono_object_hash") -#pragma comment(linker, "/export:mono_object_is_alive") -#pragma comment(linker, "/export:mono_object_is_from_assembly") -#pragma comment(linker, "/export:mono_object_isinst") -#pragma comment(linker, "/export:mono_object_isinst_checked") -#pragma comment(linker, "/export:mono_object_isinst_icall") -#pragma comment(linker, "/export:mono_object_isinst_mbyref") -#pragma comment(linker, "/export:mono_object_isinst_with_cache") -#pragma comment(linker, "/export:mono_object_new") -#pragma comment(linker, "/export:mono_object_new_alloc_by_vtable") -#pragma comment(linker, "/export:mono_object_new_alloc_specific") -#pragma comment(linker, "/export:mono_object_new_alloc_specific_checked") -#pragma comment(linker, "/export:mono_object_new_checked") -#pragma comment(linker, "/export:mono_object_new_fast") -#pragma comment(linker, "/export:mono_object_new_from_token") -#pragma comment(linker, "/export:mono_object_new_handle") -#pragma comment(linker, "/export:mono_object_new_handle_mature") -#pragma comment(linker, "/export:mono_object_new_mature") -#pragma comment(linker, "/export:mono_object_new_pinned") -#pragma comment(linker, "/export:mono_object_new_pinned_handle") -#pragma comment(linker, "/export:mono_object_new_specific") -#pragma comment(linker, "/export:mono_object_new_specific_checked") -#pragma comment(linker, "/export:mono_object_register_finalizer") -#pragma comment(linker, "/export:mono_object_register_finalizer_handle") -#pragma comment(linker, "/export:mono_object_to_string") -#pragma comment(linker, "/export:mono_object_try_to_string") -#pragma comment(linker, "/export:mono_object_unbox") -#pragma comment(linker, "/export:mono_object_xdomain_representation") -#pragma comment(linker, "/export:mono_profiler_call_context_free_buffer") -#pragma comment(linker, "/export:mono_profiler_call_context_get_argument") -#pragma comment(linker, "/export:mono_profiler_call_context_get_local") -#pragma comment(linker, "/export:mono_profiler_call_context_get_result") -#pragma comment(linker, "/export:mono_profiler_call_context_get_this") -#pragma comment(linker, "/export:mono_profiler_cleanup") -#pragma comment(linker, "/export:mono_profiler_coverage_alloc") -#pragma comment(linker, "/export:mono_profiler_coverage_instrumentation_enabled") -#pragma comment(linker, "/export:mono_profiler_create") -#pragma comment(linker, "/export:mono_profiler_enable_allocations") -#pragma comment(linker, "/export:mono_profiler_enable_call_context_introspection") -#pragma comment(linker, "/export:mono_profiler_enable_clauses") -#pragma comment(linker, "/export:mono_profiler_enable_coverage") -#pragma comment(linker, "/export:mono_profiler_enable_sampling") -#pragma comment(linker, "/export:mono_profiler_get_call_instrumentation_flags") -#pragma comment(linker, "/export:mono_profiler_get_coverage_data") -#pragma comment(linker, "/export:mono_profiler_get_sample_mode") -#pragma comment(linker, "/export:mono_profiler_install") -#pragma comment(linker, "/export:mono_profiler_install_allocation") -#pragma comment(linker, "/export:mono_profiler_install_enter_leave") -#pragma comment(linker, "/export:mono_profiler_install_exception") -#pragma comment(linker, "/export:mono_profiler_install_gc") -#pragma comment(linker, "/export:mono_profiler_install_jit_end") -#pragma comment(linker, "/export:mono_profiler_install_thread") -#pragma comment(linker, "/export:mono_profiler_load") -#pragma comment(linker, "/export:mono_profiler_raise_assembly_loaded") -#pragma comment(linker, "/export:mono_profiler_raise_assembly_loading") -#pragma comment(linker, "/export:mono_profiler_raise_assembly_unloaded") -#pragma comment(linker, "/export:mono_profiler_raise_assembly_unloading") -#pragma comment(linker, "/export:mono_profiler_raise_class_failed") -#pragma comment(linker, "/export:mono_profiler_raise_class_loaded") -#pragma comment(linker, "/export:mono_profiler_raise_class_loading") -#pragma comment(linker, "/export:mono_profiler_raise_context_loaded") -#pragma comment(linker, "/export:mono_profiler_raise_context_unloaded") -#pragma comment(linker, "/export:mono_profiler_raise_domain_loaded") -#pragma comment(linker, "/export:mono_profiler_raise_domain_loading") -#pragma comment(linker, "/export:mono_profiler_raise_domain_name") -#pragma comment(linker, "/export:mono_profiler_raise_domain_unloaded") -#pragma comment(linker, "/export:mono_profiler_raise_domain_unloading") -#pragma comment(linker, "/export:mono_profiler_raise_exception_clause") -#pragma comment(linker, "/export:mono_profiler_raise_exception_throw") -#pragma comment(linker, "/export:mono_profiler_raise_gc_allocation") -#pragma comment(linker, "/export:mono_profiler_raise_gc_event") -#pragma comment(linker, "/export:mono_profiler_raise_gc_finalized") -#pragma comment(linker, "/export:mono_profiler_raise_gc_finalized_object") -#pragma comment(linker, "/export:mono_profiler_raise_gc_finalizing") -#pragma comment(linker, "/export:mono_profiler_raise_gc_finalizing_object") -#pragma comment(linker, "/export:mono_profiler_raise_gc_handle_created") -#pragma comment(linker, "/export:mono_profiler_raise_gc_handle_deleted") -#pragma comment(linker, "/export:mono_profiler_raise_gc_moves") -#pragma comment(linker, "/export:mono_profiler_raise_gc_resize") -#pragma comment(linker, "/export:mono_profiler_raise_gc_root_register") -#pragma comment(linker, "/export:mono_profiler_raise_gc_root_unregister") -#pragma comment(linker, "/export:mono_profiler_raise_gc_roots") -#pragma comment(linker, "/export:mono_profiler_raise_image_failed") -#pragma comment(linker, "/export:mono_profiler_raise_image_loaded") -#pragma comment(linker, "/export:mono_profiler_raise_image_loading") -#pragma comment(linker, "/export:mono_profiler_raise_image_unloaded") -#pragma comment(linker, "/export:mono_profiler_raise_image_unloading") -#pragma comment(linker, "/export:mono_profiler_raise_jit_begin") -#pragma comment(linker, "/export:mono_profiler_raise_jit_chunk_created") -#pragma comment(linker, "/export:mono_profiler_raise_jit_chunk_destroyed") -#pragma comment(linker, "/export:mono_profiler_raise_jit_code_buffer") -#pragma comment(linker, "/export:mono_profiler_raise_jit_done") -#pragma comment(linker, "/export:mono_profiler_raise_jit_failed") -#pragma comment(linker, "/export:mono_profiler_raise_method_begin_invoke") -#pragma comment(linker, "/export:mono_profiler_raise_method_end_invoke") -#pragma comment(linker, "/export:mono_profiler_raise_method_enter") -#pragma comment(linker, "/export:mono_profiler_raise_method_exception_leave") -#pragma comment(linker, "/export:mono_profiler_raise_method_free") -#pragma comment(linker, "/export:mono_profiler_raise_method_leave") -#pragma comment(linker, "/export:mono_profiler_raise_method_tail_call") -#pragma comment(linker, "/export:mono_profiler_raise_monitor_acquired") -#pragma comment(linker, "/export:mono_profiler_raise_monitor_contention") -#pragma comment(linker, "/export:mono_profiler_raise_monitor_failed") -#pragma comment(linker, "/export:mono_profiler_raise_runtime_initialized") -#pragma comment(linker, "/export:mono_profiler_raise_runtime_shutdown_begin") -#pragma comment(linker, "/export:mono_profiler_raise_runtime_shutdown_end") -#pragma comment(linker, "/export:mono_profiler_raise_sample_hit") -#pragma comment(linker, "/export:mono_profiler_raise_thread_exited") -#pragma comment(linker, "/export:mono_profiler_raise_thread_name") -#pragma comment(linker, "/export:mono_profiler_raise_thread_started") -#pragma comment(linker, "/export:mono_profiler_raise_thread_stopped") -#pragma comment(linker, "/export:mono_profiler_raise_thread_stopping") -#pragma comment(linker, "/export:mono_profiler_raise_vtable_failed") -#pragma comment(linker, "/export:mono_profiler_raise_vtable_loaded") -#pragma comment(linker, "/export:mono_profiler_raise_vtable_loading") -#pragma comment(linker, "/export:mono_profiler_sampling_enabled") -#pragma comment(linker, "/export:mono_profiler_sampling_thread_post") -#pragma comment(linker, "/export:mono_profiler_sampling_thread_wait") -#pragma comment(linker, "/export:mono_profiler_set_assembly_loaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_assembly_loading_callback") -#pragma comment(linker, "/export:mono_profiler_set_assembly_unloaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_assembly_unloading_callback") -#pragma comment(linker, "/export:mono_profiler_set_call_instrumentation_filter_callback") -#pragma comment(linker, "/export:mono_profiler_set_class_failed_callback") -#pragma comment(linker, "/export:mono_profiler_set_class_loaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_class_loading_callback") -#pragma comment(linker, "/export:mono_profiler_set_cleanup_callback") -#pragma comment(linker, "/export:mono_profiler_set_context_loaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_context_unloaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_coverage_filter_callback") -#pragma comment(linker, "/export:mono_profiler_set_domain_loaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_domain_loading_callback") -#pragma comment(linker, "/export:mono_profiler_set_domain_name_callback") -#pragma comment(linker, "/export:mono_profiler_set_domain_unloaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_domain_unloading_callback") -#pragma comment(linker, "/export:mono_profiler_set_events") -#pragma comment(linker, "/export:mono_profiler_set_exception_clause_callback") -#pragma comment(linker, "/export:mono_profiler_set_exception_throw_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_allocation_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_event_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_finalized_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_finalized_object_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_finalizing_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_finalizing_object_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_handle_created_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_handle_deleted_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_moves_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_resize_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_root_register_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_root_unregister_callback") -#pragma comment(linker, "/export:mono_profiler_set_gc_roots_callback") -#pragma comment(linker, "/export:mono_profiler_set_image_failed_callback") -#pragma comment(linker, "/export:mono_profiler_set_image_loaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_image_loading_callback") -#pragma comment(linker, "/export:mono_profiler_set_image_unloaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_image_unloading_callback") -#pragma comment(linker, "/export:mono_profiler_set_jit_begin_callback") -#pragma comment(linker, "/export:mono_profiler_set_jit_chunk_created_callback") -#pragma comment(linker, "/export:mono_profiler_set_jit_chunk_destroyed_callback") -#pragma comment(linker, "/export:mono_profiler_set_jit_code_buffer_callback") -#pragma comment(linker, "/export:mono_profiler_set_jit_done_callback") -#pragma comment(linker, "/export:mono_profiler_set_jit_failed_callback") -#pragma comment(linker, "/export:mono_profiler_set_method_begin_invoke_callback") -#pragma comment(linker, "/export:mono_profiler_set_method_end_invoke_callback") -#pragma comment(linker, "/export:mono_profiler_set_method_enter_callback") -#pragma comment(linker, "/export:mono_profiler_set_method_exception_leave_callback") -#pragma comment(linker, "/export:mono_profiler_set_method_free_callback") -#pragma comment(linker, "/export:mono_profiler_set_method_leave_callback") -#pragma comment(linker, "/export:mono_profiler_set_method_tail_call_callback") -#pragma comment(linker, "/export:mono_profiler_set_monitor_acquired_callback") -#pragma comment(linker, "/export:mono_profiler_set_monitor_contention_callback") -#pragma comment(linker, "/export:mono_profiler_set_monitor_failed_callback") -#pragma comment(linker, "/export:mono_profiler_set_runtime_initialized_callback") -#pragma comment(linker, "/export:mono_profiler_set_runtime_shutdown_begin_callback") -#pragma comment(linker, "/export:mono_profiler_set_runtime_shutdown_end_callback") -#pragma comment(linker, "/export:mono_profiler_set_sample_hit_callback") -#pragma comment(linker, "/export:mono_profiler_set_sample_mode") -#pragma comment(linker, "/export:mono_profiler_set_thread_exited_callback") -#pragma comment(linker, "/export:mono_profiler_set_thread_name_callback") -#pragma comment(linker, "/export:mono_profiler_set_thread_started_callback") -#pragma comment(linker, "/export:mono_profiler_set_thread_stopped_callback") -#pragma comment(linker, "/export:mono_profiler_set_thread_stopping_callback") -#pragma comment(linker, "/export:mono_profiler_set_vtable_failed_callback") -#pragma comment(linker, "/export:mono_profiler_set_vtable_loaded_callback") -#pragma comment(linker, "/export:mono_profiler_set_vtable_loading_callback") -#pragma comment(linker, "/export:mono_profiler_started") -#pragma comment(linker, "/export:mono_profiler_state") -#pragma comment(linker, "/export:mono_property_bag_add") -#pragma comment(linker, "/export:mono_property_bag_get") -#pragma comment(linker, "/export:mono_property_get_flags") -#pragma comment(linker, "/export:mono_property_get_get_method") -#pragma comment(linker, "/export:mono_property_get_name") -#pragma comment(linker, "/export:mono_property_get_object") -#pragma comment(linker, "/export:mono_property_get_object_checked") -#pragma comment(linker, "/export:mono_property_get_object_handle") -#pragma comment(linker, "/export:mono_property_get_parent") -#pragma comment(linker, "/export:mono_property_get_set_method") -#pragma comment(linker, "/export:mono_property_get_value") -#pragma comment(linker, "/export:mono_property_get_value_checked") -#pragma comment(linker, "/export:mono_property_hash_destroy") -#pragma comment(linker, "/export:mono_property_hash_insert") -#pragma comment(linker, "/export:mono_property_hash_lookup") -#pragma comment(linker, "/export:mono_property_hash_new") -#pragma comment(linker, "/export:mono_property_hash_remove_object") -#pragma comment(linker, "/export:mono_property_set_value") -#pragma comment(linker, "/export:mono_property_set_value_handle") -#pragma comment(linker, "/export:mono_raise_exception") -#pragma comment(linker, "/export:mono_raise_exception_deprecated") -#pragma comment(linker, "/export:mono_raise_exception_with_context") -#pragma comment(linker, "/export:mono_reflection_assembly_get_assembly") -#pragma comment(linker, "/export:mono_reflection_bind_generic_parameters") -#pragma comment(linker, "/export:mono_reflection_call_is_assignable_to") -#pragma comment(linker, "/export:mono_reflection_cleanup_assembly") -#pragma comment(linker, "/export:mono_reflection_cleanup_domain") -#pragma comment(linker, "/export:mono_reflection_create_custom_attr_data_args") -#pragma comment(linker, "/export:mono_reflection_create_custom_attr_data_args_noalloc") -#pragma comment(linker, "/export:mono_reflection_dynimage_basic_init") -#pragma comment(linker, "/export:mono_reflection_emit_init") -#pragma comment(linker, "/export:mono_reflection_free_type_info") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_blob") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_blob_checked") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_by_type") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_by_type_handle") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_data") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_data_checked") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_info") -#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_info_checked") -#pragma comment(linker, "/export:mono_reflection_get_dynamic_overrides") -#pragma comment(linker, "/export:mono_reflection_get_token") -#pragma comment(linker, "/export:mono_reflection_get_token_checked") -#pragma comment(linker, "/export:mono_reflection_get_type") -#pragma comment(linker, "/export:mono_reflection_get_type_checked") -#pragma comment(linker, "/export:mono_reflection_init") -#pragma comment(linker, "/export:mono_reflection_is_usertype") -#pragma comment(linker, "/export:mono_reflection_lookup_dynamic_token") -#pragma comment(linker, "/export:mono_reflection_lookup_signature") -#pragma comment(linker, "/export:mono_reflection_marshal_as_attribute_from_marshal_spec") -#pragma comment(linker, "/export:mono_reflection_method_count_clauses") -#pragma comment(linker, "/export:mono_reflection_methodbuilder_from_ctor_builder") -#pragma comment(linker, "/export:mono_reflection_methodbuilder_from_method_builder") -#pragma comment(linker, "/export:mono_reflection_parse_type") -#pragma comment(linker, "/export:mono_reflection_parse_type_checked") -#pragma comment(linker, "/export:mono_reflection_resolution_scope_from_image") -#pragma comment(linker, "/export:mono_reflection_resolve_object") -#pragma comment(linker, "/export:mono_reflection_resolve_object_handle") -#pragma comment(linker, "/export:mono_reflection_type_from_name") -#pragma comment(linker, "/export:mono_reflection_type_from_name_checked") -#pragma comment(linker, "/export:mono_reflection_type_get_handle") -#pragma comment(linker, "/export:mono_reflection_type_get_type") -#pragma comment(linker, "/export:mono_reflection_type_handle_mono_type") -#pragma comment(linker, "/export:mono_runtime_class_init") -#pragma comment(linker, "/export:mono_runtime_class_init_full") -#pragma comment(linker, "/export:mono_runtime_cleanup") -#pragma comment(linker, "/export:mono_runtime_cleanup_handlers") -#pragma comment(linker, "/export:mono_runtime_create_delegate_trampoline") -#pragma comment(linker, "/export:mono_runtime_create_jump_trampoline") -#pragma comment(linker, "/export:mono_runtime_delegate_invoke") -#pragma comment(linker, "/export:mono_runtime_delegate_invoke_checked") -#pragma comment(linker, "/export:mono_runtime_delegate_try_invoke") -#pragma comment(linker, "/export:mono_runtime_exec_main") -#pragma comment(linker, "/export:mono_runtime_exec_main_checked") -#pragma comment(linker, "/export:mono_runtime_exec_managed_code") -#pragma comment(linker, "/export:mono_runtime_free_method") -#pragma comment(linker, "/export:mono_runtime_get_aotid") -#pragma comment(linker, "/export:mono_runtime_get_caller_no_system_or_reflection") -#pragma comment(linker, "/export:mono_runtime_get_main_args") -#pragma comment(linker, "/export:mono_runtime_get_main_args_handle") -#pragma comment(linker, "/export:mono_runtime_get_no_exec") -#pragma comment(linker, "/export:mono_runtime_init") -#pragma comment(linker, "/export:mono_runtime_init_checked") -#pragma comment(linker, "/export:mono_runtime_init_tls") -#pragma comment(linker, "/export:mono_runtime_install_custom_handlers") -#pragma comment(linker, "/export:mono_runtime_install_custom_handlers_usage") -#pragma comment(linker, "/export:mono_runtime_install_handlers") -#pragma comment(linker, "/export:mono_runtime_invoke") -#pragma comment(linker, "/export:mono_runtime_invoke_array") -#pragma comment(linker, "/export:mono_runtime_invoke_array_checked") -#pragma comment(linker, "/export:mono_runtime_invoke_checked") -#pragma comment(linker, "/export:mono_runtime_invoke_handle") -#pragma comment(linker, "/export:mono_runtime_is_shutting_down") -#pragma comment(linker, "/export:mono_runtime_load") -#pragma comment(linker, "/export:mono_runtime_object_init") -#pragma comment(linker, "/export:mono_runtime_object_init_checked") -#pragma comment(linker, "/export:mono_runtime_object_init_handle") -#pragma comment(linker, "/export:mono_runtime_quit") -#pragma comment(linker, "/export:mono_runtime_resource_check_limit") -#pragma comment(linker, "/export:mono_runtime_resource_limit") -#pragma comment(linker, "/export:mono_runtime_resource_set_callback") -#pragma comment(linker, "/export:mono_runtime_run_main") -#pragma comment(linker, "/export:mono_runtime_run_main_checked") -#pragma comment(linker, "/export:mono_runtime_run_module_cctor") -#pragma comment(linker, "/export:mono_runtime_set_main_args") -#pragma comment(linker, "/export:mono_runtime_set_no_exec") -#pragma comment(linker, "/export:mono_runtime_set_pending_exception") -#pragma comment(linker, "/export:mono_runtime_set_shutting_down") -#pragma comment(linker, "/export:mono_runtime_setup_stat_profiler") -#pragma comment(linker, "/export:mono_runtime_shutdown_stat_profiler") -#pragma comment(linker, "/export:mono_runtime_try_exec_main") -#pragma comment(linker, "/export:mono_runtime_try_invoke") -#pragma comment(linker, "/export:mono_runtime_try_invoke_array") -#pragma comment(linker, "/export:mono_runtime_try_invoke_handle") -#pragma comment(linker, "/export:mono_runtime_try_run_main") -#pragma comment(linker, "/export:mono_runtime_try_shutdown") -#pragma comment(linker, "/export:mono_runtime_unhandled_exception_policy_get") -#pragma comment(linker, "/export:mono_runtime_unhandled_exception_policy_set") -#pragma comment(linker, "/export:mono_signature_explicit_this") -#pragma comment(linker, "/export:mono_signature_full_name") -#pragma comment(linker, "/export:mono_signature_get_call_conv") -#pragma comment(linker, "/export:mono_signature_get_desc") -#pragma comment(linker, "/export:mono_signature_get_param_count") -#pragma comment(linker, "/export:mono_signature_get_params") -#pragma comment(linker, "/export:mono_signature_get_return_type") -#pragma comment(linker, "/export:mono_signature_hash") -#pragma comment(linker, "/export:mono_signature_is_instance") -#pragma comment(linker, "/export:mono_signature_no_pinvoke") -#pragma comment(linker, "/export:mono_signature_param_is_out") -#pragma comment(linker, "/export:mono_signature_vararg_start") -#pragma comment(linker, "/export:mono_stack_mark_pop_value") -#pragma comment(linker, "/export:mono_stack_mark_record_size") -#pragma comment(linker, "/export:mono_stack_walk") -#pragma comment(linker, "/export:mono_stack_walk_async_safe") -#pragma comment(linker, "/export:mono_stack_walk_no_il") -#pragma comment(linker, "/export:mono_string_builder_to_utf16") -#pragma comment(linker, "/export:mono_string_builder_to_utf8") -#pragma comment(linker, "/export:mono_string_chars") -#pragma comment(linker, "/export:mono_string_empty") -#pragma comment(linker, "/export:mono_string_empty_handle") -#pragma comment(linker, "/export:mono_string_empty_wrapper") -#pragma comment(linker, "/export:mono_string_equal") -#pragma comment(linker, "/export:mono_string_from_blob") -#pragma comment(linker, "/export:mono_string_from_bstr") -#pragma comment(linker, "/export:mono_string_from_bstr_icall") -#pragma comment(linker, "/export:mono_string_from_byvalstr") -#pragma comment(linker, "/export:mono_string_from_byvalwstr") -#pragma comment(linker, "/export:mono_string_from_utf16") -#pragma comment(linker, "/export:mono_string_from_utf16_checked") -#pragma comment(linker, "/export:mono_string_from_utf32") -#pragma comment(linker, "/export:mono_string_from_utf32_checked") -#pragma comment(linker, "/export:mono_string_handle_length") -#pragma comment(linker, "/export:mono_string_handle_pin_chars") -#pragma comment(linker, "/export:mono_string_handle_to_utf8") -#pragma comment(linker, "/export:mono_string_hash") -#pragma comment(linker, "/export:mono_string_intern") -#pragma comment(linker, "/export:mono_string_intern_checked") -#pragma comment(linker, "/export:mono_string_is_interned") -#pragma comment(linker, "/export:mono_string_length") -#pragma comment(linker, "/export:mono_string_new") -#pragma comment(linker, "/export:mono_string_new_checked") -#pragma comment(linker, "/export:mono_string_new_handle") -#pragma comment(linker, "/export:mono_string_new_len") -#pragma comment(linker, "/export:mono_string_new_len_checked") -#pragma comment(linker, "/export:mono_string_new_len_wrapper") -#pragma comment(linker, "/export:mono_string_new_size") -#pragma comment(linker, "/export:mono_string_new_size_checked") -#pragma comment(linker, "/export:mono_string_new_utf16") -#pragma comment(linker, "/export:mono_string_new_utf16_checked") -#pragma comment(linker, "/export:mono_string_new_utf16_handle") -#pragma comment(linker, "/export:mono_string_new_utf32") -#pragma comment(linker, "/export:mono_string_new_utf8_len_handle") -#pragma comment(linker, "/export:mono_string_new_wrapper") -#pragma comment(linker, "/export:mono_string_new_wtf8_len_checked") -#pragma comment(linker, "/export:mono_string_to_ansibstr") -#pragma comment(linker, "/export:mono_string_to_bstr") -#pragma comment(linker, "/export:mono_string_to_byvalstr") -#pragma comment(linker, "/export:mono_string_to_byvalwstr") -#pragma comment(linker, "/export:mono_string_to_utf16") -#pragma comment(linker, "/export:mono_string_to_utf32") -#pragma comment(linker, "/export:mono_string_to_utf8") -#pragma comment(linker, "/export:mono_string_to_utf8_checked") -#pragma comment(linker, "/export:mono_string_to_utf8_ignore") -#pragma comment(linker, "/export:mono_string_to_utf8_image") -#pragma comment(linker, "/export:mono_string_to_utf8str") -#pragma comment(linker, "/export:mono_string_to_utf8str_handle") -#pragma comment(linker, "/export:mono_string_utf16_to_builder") -#pragma comment(linker, "/export:mono_string_utf16_to_builder2") -#pragma comment(linker, "/export:mono_string_utf8_to_builder") -#pragma comment(linker, "/export:mono_string_utf8_to_builder2") -#pragma comment(linker, "/export:mono_thread_attach") -#pragma comment(linker, "/export:mono_thread_attach_aborted_cb") -#pragma comment(linker, "/export:mono_thread_callbacks_init") -#pragma comment(linker, "/export:mono_thread_cleanup") -#pragma comment(linker, "/export:mono_thread_cleanup_apartment_state") -#pragma comment(linker, "/export:mono_thread_clear_and_set_state") -#pragma comment(linker, "/export:mono_thread_clr_state") -#pragma comment(linker, "/export:mono_thread_create") -#pragma comment(linker, "/export:mono_thread_create_checked") -#pragma comment(linker, "/export:mono_thread_create_internal") -#pragma comment(linker, "/export:mono_thread_create_internal_handle") -#pragma comment(linker, "/export:mono_thread_current") -#pragma comment(linker, "/export:mono_thread_current_check_pending_interrupt") -#pragma comment(linker, "/export:mono_thread_detach") -#pragma comment(linker, "/export:mono_thread_detach_if_exiting") -#pragma comment(linker, "/export:mono_thread_exit") -#pragma comment(linker, "/export:mono_thread_force_interruption_checkpoint_noraise") -#pragma comment(linker, "/export:mono_thread_get_main") -#pragma comment(linker, "/export:mono_thread_get_managed_id") -#pragma comment(linker, "/export:mono_thread_get_name") -#pragma comment(linker, "/export:mono_thread_get_name_utf8") -#pragma comment(linker, "/export:mono_thread_get_undeniable_exception") -#pragma comment(linker, "/export:mono_thread_has_appdomain_ref") -#pragma comment(linker, "/export:mono_thread_hazardous_queue_free") -#pragma comment(linker, "/export:mono_thread_hazardous_try_free") -#pragma comment(linker, "/export:mono_thread_hazardous_try_free_all") -#pragma comment(linker, "/export:mono_thread_hazardous_try_free_some") -#pragma comment(linker, "/export:mono_thread_init") -#pragma comment(linker, "/export:mono_thread_init_apartment_state") -#pragma comment(linker, "/export:mono_thread_interruption_checkpoint") -#pragma comment(linker, "/export:mono_thread_interruption_checkpoint_bool") -#pragma comment(linker, "/export:mono_thread_interruption_checkpoint_void") -#pragma comment(linker, "/export:mono_thread_interruption_request_flag") -#pragma comment(linker, "/export:mono_thread_interruption_requested") -#pragma comment(linker, "/export:mono_thread_is_foreign") -#pragma comment(linker, "/export:mono_thread_is_gc_unsafe_mode") -#pragma comment(linker, "/export:mono_thread_join") -#pragma comment(linker, "/export:mono_thread_manage") -#pragma comment(linker, "/export:mono_thread_new_init") -#pragma comment(linker, "/export:mono_thread_platform_create_thread") -#pragma comment(linker, "/export:mono_thread_pop_appdomain_ref") -#pragma comment(linker, "/export:mono_thread_push_appdomain_ref") -#pragma comment(linker, "/export:mono_thread_set_main") -#pragma comment(linker, "/export:mono_thread_set_manage_callback") -#pragma comment(linker, "/export:mono_thread_set_name_internal") -#pragma comment(linker, "/export:mono_thread_set_state") -#pragma comment(linker, "/export:mono_thread_small_id_alloc") -#pragma comment(linker, "/export:mono_thread_small_id_free") -#pragma comment(linker, "/export:mono_thread_smr_cleanup") -#pragma comment(linker, "/export:mono_thread_smr_init") -#pragma comment(linker, "/export:mono_thread_stop") -#pragma comment(linker, "/export:mono_thread_test_and_set_state") -#pragma comment(linker, "/export:mono_thread_test_state") -#pragma comment(linker, "/export:mono_type_array_get_and_resolve") -#pragma comment(linker, "/export:mono_type_create_from_typespec") -#pragma comment(linker, "/export:mono_type_create_from_typespec_checked") -#pragma comment(linker, "/export:mono_type_full_name") -#pragma comment(linker, "/export:mono_type_generic_inst_is_valuetype") -#pragma comment(linker, "/export:mono_type_get_array_type") -#pragma comment(linker, "/export:mono_type_get_basic_type_from_generic") -#pragma comment(linker, "/export:mono_type_get_checked") -#pragma comment(linker, "/export:mono_type_get_class") -#pragma comment(linker, "/export:mono_type_get_cmods") -#pragma comment(linker, "/export:mono_type_get_desc") -#pragma comment(linker, "/export:mono_type_get_full_name") -#pragma comment(linker, "/export:mono_type_get_modifiers") -#pragma comment(linker, "/export:mono_type_get_name") -#pragma comment(linker, "/export:mono_type_get_name_full") -#pragma comment(linker, "/export:mono_type_get_object") -#pragma comment(linker, "/export:mono_type_get_object_checked") -#pragma comment(linker, "/export:mono_type_get_object_handle") -#pragma comment(linker, "/export:mono_type_get_ptr_type") -#pragma comment(linker, "/export:mono_type_get_signature") -#pragma comment(linker, "/export:mono_type_get_type") -#pragma comment(linker, "/export:mono_type_get_underlying_type") -#pragma comment(linker, "/export:mono_type_has_exceptions") -#pragma comment(linker, "/export:mono_type_in_image") -#pragma comment(linker, "/export:mono_type_initialization_cleanup") -#pragma comment(linker, "/export:mono_type_initialization_init") -#pragma comment(linker, "/export:mono_type_is_byref") -#pragma comment(linker, "/export:mono_type_is_from_assembly") -#pragma comment(linker, "/export:mono_type_is_generic_parameter") -#pragma comment(linker, "/export:mono_type_is_pointer") -#pragma comment(linker, "/export:mono_type_is_primitive") -#pragma comment(linker, "/export:mono_type_is_reference") -#pragma comment(linker, "/export:mono_type_is_struct") -#pragma comment(linker, "/export:mono_type_is_valid_enum_basetype") -#pragma comment(linker, "/export:mono_type_is_void") -#pragma comment(linker, "/export:mono_type_native_stack_size") -#pragma comment(linker, "/export:mono_type_set_alignment") -#pragma comment(linker, "/export:mono_type_size") -#pragma comment(linker, "/export:mono_type_stack_size") -#pragma comment(linker, "/export:mono_type_stack_size_internal") -#pragma comment(linker, "/export:mono_value_box") -#pragma comment(linker, "/export:mono_value_copy") -#pragma comment(linker, "/export:mono_value_copy_array") -#pragma comment(linker, "/export:mono_jit_info_get_code_start") -#pragma comment(linker, "/export:mono_jit_info_get_code_size") - -#endif diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.h b/Source/Engine/Scripting/ManagedCLR/MCore.h index 3d62db299..93826afe3 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.h +++ b/Source/Engine/Scripting/ManagedCLR/MCore.h @@ -10,7 +10,6 @@ class FLAXENGINE_API MCore { public: - /// /// Gets the root domain. /// @@ -26,16 +25,15 @@ public: /// /// The domain name to create. /// The domain object. - static MDomain* CreateDomain(const MString& domainName); + static MDomain* CreateDomain(const StringAnsi& domainName); /// /// Unloads the domain. /// /// The domain name to remove. - static void UnloadDomain(const MString& domainName); + static void UnloadDomain(const StringAnsi& domainName); public: - /// /// Initialize CLR Engine /// @@ -47,39 +45,139 @@ public: /// static void UnloadEngine(); - /// - /// Attaches CLR runtime to the current thread. Use it to allow invoking managed runtime from native threads. - /// - static void AttachThread(); - - /// - /// Exits the managed runtime thread. Clears the thread data and sets its exit code to 0. Use it before ending the native thread that uses AttachThread. - /// - static void ExitThread(); - public: + /// + /// Utilities for C# object management. + /// + struct FLAXENGINE_API Object + { + static MObject* Box(void* value, const MClass* klass); + static void* Unbox(MObject* obj); + static MObject* New(const MClass* klass); + static void Init(MObject* obj); + static MClass* GetClass(MObject* obj); + static MString* ToString(MObject* obj); + static int32 GetHashCode(MObject* obj); + }; + + /// + /// Utilities for C# string management. + /// + struct FLAXENGINE_API String + { + static MString* GetEmpty(MDomain* domain = nullptr); + static MString* New(const char* str, int32 length, MDomain* domain = nullptr); + static MString* New(const Char* str, int32 length, MDomain* domain = nullptr); + static StringView GetChars(MString* obj); + }; + + /// + /// Utilities for C# array management. + /// + struct FLAXENGINE_API Array + { + static MArray* New(const MClass* elementKlass, int32 length); + static MClass* GetClass(MClass* elementKlass); + static int32 GetLength(const MArray* obj); + static void* GetAddress(const MArray* obj); + + template + FORCE_INLINE static T* GetAddress(const MArray* obj) + { + return (T*)GetAddress(obj); + } + }; + + /// + /// Utilities for GC Handle management. + /// + struct FLAXENGINE_API GCHandle + { + static MGCHandle New(MObject* obj, bool pinned); + static MGCHandle NewWeak(MObject* obj, bool trackResurrection); + static MObject* GetTarget(const MGCHandle& handle); + static void Free(const MGCHandle& handle); + }; /// /// Helper utilities for C# garbage collector. /// - class GC + struct FLAXENGINE_API GC { - public: - - /// - /// Forces an immediate garbage collection of all generations. - /// static void Collect(); - - /// - /// Forces an immediate garbage collection of the given generation. - /// - /// The target generation static void Collect(int32 generation); - - /// - /// Suspends the current thread until the thread that is processing the queue of finalizers has emptied that queue. - /// static void WaitForPendingFinalizers(); + static void WriteRef(void* ptr, MObject* ref); + static void WriteValue(void* dst, void* src, int32 count, const MClass* klass); + static void WriteArrayRef(MArray* dst, MObject* ref, int32 index); +#if USE_NETCORE + static void* AllocateMemory(int32 size, bool coTaskMem = false); + static void FreeMemory(void* ptr, bool coTaskMem = false); +#endif + }; + + /// + /// Utilities for C# threads management. + /// + struct FLAXENGINE_API Thread + { + static void Attach(); + static void Exit(); + static bool IsAttached(); + }; + + /// + /// Helper utilities for C# exceptions throwing. + /// + struct FLAXENGINE_API Exception + { + static void Throw(MObject* exception); + static MObject* GetNullReference(); + static MObject* Get(const char* msg); + static MObject* GetArgument(const char* arg, const char* msg); + static MObject* GetArgumentNull(const char* arg); + static MObject* GetArgumentOutOfRange(const char* arg); + static MObject* GetNotSupported(const char* msg); + }; + + /// + /// Helper utilities for C# types information. + /// + struct FLAXENGINE_API Type + { + static ::String ToString(MType* type); + static MClass* GetClass(MType* type); + static int32 GetSize(MType* type); + static MTypes GetType(MType* type); + static bool IsPointer(MType* type); + static bool IsReference(MType* type); +#if USE_MONO + static MTypeObject* GetObject(MType* type); + static MType* Get(MTypeObject* type); +#endif + }; + + /// + /// Helper types cache from C# corlib and engine. + /// + struct FLAXENGINE_API TypeCache + { + static MClass* Void; + static MClass* Object; + static MClass* Byte; + static MClass* Boolean; + static MClass* SByte; + static MClass* Char; + static MClass* Int16; + static MClass* UInt16; + static MClass* Int32; + static MClass* UInt32; + static MClass* Int64; + static MClass* UInt64; + static MClass* IntPtr; + static MClass* UIntPtr; + static MClass* Single; + static MClass* Double; + static MClass* String; }; }; diff --git a/Source/Engine/Scripting/ManagedCLR/MDomain.cpp b/Source/Engine/Scripting/ManagedCLR/MDomain.cpp deleted file mode 100644 index a0a92dd60..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MDomain.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MDomain.h" -#include "MCore.h" -#include "MAssembly.h" -#include "Engine/Threading/Threading.h" -#include "Engine/Core/Log.h" -#include "Engine/Debug/Exceptions/ArgumentException.h" -#include "Engine/Debug/Exceptions/Exceptions.h" -#if USE_MONO -#include -#endif - -extern MDomain* MActiveDomain; - -MDomain::MDomain(const MString& domainName) - : _domainName(domainName) -{ -} - -bool MDomain::SetCurrentDomain(bool force) -{ -#if USE_MONO - if (mono_domain_set(_monoDomain, force) == 0) - return false; -#endif - MActiveDomain = this; - return true; -} - -MAssembly* MDomain::CreateEmptyAssembly(const MString& assemblyName, const MAssemblyOptions options) -{ - // Validates if assembly is already open - if (_assemblies.ContainsKey(assemblyName)) - { - Log::ArgumentException(String::Format(TEXT("{0} assembly has already been added"), String(assemblyName))); - return _assemblies.At(assemblyName); - } - - // Create shared pointer to the assembly - const auto assembly = New(this, assemblyName, options); - - // Add assembly instance to dictionary - _assemblies.Add(assemblyName, assembly); - - return assembly; -} - -void MDomain::RemoveAssembly(const MString& assemblyName) -{ - auto assembly = _assemblies[assemblyName]; - _assemblies.Remove(assemblyName); - Delete(assembly); -} - -MAssembly* MDomain::GetAssembly(const MString& assemblyName) const -{ - MAssembly* result = nullptr; - if (!_assemblies.TryGet(assemblyName, result)) - { - Log::ArgumentOutOfRangeException(TEXT("Current assembly was not found in given domain")); - } - return result; -} - -void MDomain::Dispatch() const -{ -#if USE_MONO - if (!IsInMainThread()) - { - mono_thread_attach(_monoDomain); - } -#endif -} - -MClass* MDomain::FindClass(const StringAnsiView& fullname) const -{ - for (auto assembly = _assemblies.Begin(); assembly != _assemblies.End(); ++assembly) - { - const auto currentClass = assembly->Value->GetClass(fullname); - if (!currentClass) - { - return currentClass; - } - } - return nullptr; -} diff --git a/Source/Engine/Scripting/ManagedCLR/MDomain.h b/Source/Engine/Scripting/ManagedCLR/MDomain.h index 7be828ed3..e03b8a23a 100644 --- a/Source/Engine/Scripting/ManagedCLR/MDomain.h +++ b/Source/Engine/Scripting/ManagedCLR/MDomain.h @@ -4,7 +4,6 @@ #include "Engine/Core/Collections/Dictionary.h" #include "MTypes.h" -#include "MAssemblyOptions.h" /// /// Domain separates multiple processes within one executed CLR environment. @@ -17,24 +16,24 @@ class FLAXENGINE_API MDomain { friend MCore; friend MAssembly; -public: - typedef Dictionary AssembliesDictionary; +public: + typedef Dictionary AssembliesDictionary; private: - #if USE_MONO MonoDomain* _monoDomain; #endif - MString _domainName; + StringAnsi _domainName; AssembliesDictionary _assemblies; public: - - MDomain(const MString& domainName); + MDomain(const StringAnsi& domainName) + : _domainName(domainName) + { + } public: - #if USE_MONO /// /// Gets native domain class. @@ -48,7 +47,7 @@ public: /// /// Gets current domain name /// - FORCE_INLINE const MString& GetName() const + FORCE_INLINE const StringAnsi& GetName() const { return _domainName; } @@ -62,27 +61,6 @@ public: } public: - - /// - /// Create assembly container from current domain - /// - /// Assembly name to later receive from assemblies dictionary - /// The assembly options container. - /// MAssembly object ready to Load - MAssembly* CreateEmptyAssembly(const MString& assemblyName, const MAssemblyOptions options); - - /// - /// Removes assembly from current domain and request unloading. - /// - /// Assembly name - void RemoveAssembly(const MString& assemblyName); - - /// - /// Gets current domain assembly. - /// - /// The managed assembly or null if not found. - MAssembly* GetAssembly(const MString& assemblyName) const; - /// /// Attaches current CLR domain calls to the current thread. /// @@ -93,9 +71,4 @@ public: /// /// True if succeed in settings, false if failed. bool SetCurrentDomain(bool force = false); - - /// - /// Returns class from current domain. - /// - MClass* FindClass(const StringAnsiView& fullname) const; }; diff --git a/Source/Engine/Scripting/ManagedCLR/MEvent.cpp b/Source/Engine/Scripting/ManagedCLR/MEvent.cpp deleted file mode 100644 index 727f64402..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MEvent.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MEvent.h" -#include "MType.h" -#include "MClass.h" -#if USE_MONO -#include - -MEvent::MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass) - : _monoEvent(monoEvent) - , _addMethod(nullptr) - , _removeMethod(nullptr) - , _parentClass(parentClass) - , _name(name) - , _hasCachedAttributes(false) - , _hasAddMonoMethod(true) - , _hasRemoveMonoMethod(true) -{ -#if BUILD_DEBUG - // Validate input name - ASSERT(StringUtils::Compare(name, mono_event_get_name(monoEvent)) == 0); -#endif -} - -#endif - -MType MEvent::GetType() -{ - if (GetAddMethod() != nullptr) - return GetAddMethod()->GetReturnType(); - if (GetRemoveMethod() != nullptr) - return GetRemoveMethod()->GetReturnType(); - return MType(); -} - -MMethod* MEvent::GetAddMethod() -{ - if (!_hasAddMonoMethod) - return nullptr; - if (_addMethod == nullptr) - { -#if USE_MONO - auto addMonoMethod = mono_event_get_add_method(_monoEvent); - if (addMonoMethod != nullptr) - { - _hasAddMonoMethod = true; - return _addMethod = New(addMonoMethod, _parentClass); - } -#endif - } - return _addMethod; -} - -MMethod* MEvent::GetRemoveMethod() -{ - if (!_hasRemoveMonoMethod) - return nullptr; - if (_removeMethod == nullptr) - { -#if USE_MONO - auto removeMonoMethod = mono_event_get_remove_method(_monoEvent); - if (removeMonoMethod) - { - _hasRemoveMonoMethod = true; - return _removeMethod = New(removeMonoMethod, _parentClass); - } -#endif - } - return _removeMethod; -} - -bool MEvent::HasAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoClass* parentClass = mono_event_get_parent(_monoEvent); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); - if (attrInfo == nullptr) - return false; - - const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; - mono_custom_attrs_free(attrInfo); - return hasAttr; -#else - return false; -#endif -} - -bool MEvent::HasAttribute() const -{ -#if USE_MONO - MonoClass* parentClass = mono_event_get_parent(_monoEvent); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); - if (attrInfo == nullptr) - return false; - - if (attrInfo->num_attrs > 0) - { - mono_custom_attrs_free(attrInfo); - return true; - } - mono_custom_attrs_free(attrInfo); - return false; -#else - return false; -#endif -} - -MObject* MEvent::GetAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoClass* parentClass = mono_event_get_parent(_monoEvent); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); - if (attrInfo == nullptr) - return nullptr; - - MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); - mono_custom_attrs_free(attrInfo); - return foundAttr; -#else - return nullptr; -#endif -} - -const Array& MEvent::GetAttributes() -{ - if (_hasCachedAttributes) - return _attributes; - - _hasCachedAttributes = true; -#if USE_MONO - MonoClass* parentClass = mono_event_get_parent(_monoEvent); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); - if (attrInfo == nullptr) - return _attributes; - - MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); - const auto length = (uint32)mono_array_length(monoAttributesArray); - _attributes.Resize(length); - for (uint32 i = 0; i < length; i++) - _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); - mono_custom_attrs_free(attrInfo); -#endif - return _attributes; -} diff --git a/Source/Engine/Scripting/ManagedCLR/MEvent.h b/Source/Engine/Scripting/ManagedCLR/MEvent.h index 69686cc0e..f6353330d 100644 --- a/Source/Engine/Scripting/ManagedCLR/MEvent.h +++ b/Source/Engine/Scripting/ManagedCLR/MEvent.h @@ -12,35 +12,36 @@ class FLAXENGINE_API MEvent friend MClass; protected: - #if USE_MONO MonoEvent* _monoEvent; +#elif USE_NETCORE + void* _handle; #endif - MMethod* _addMethod; - MMethod* _removeMethod; + mutable MMethod* _addMethod; + mutable MMethod* _removeMethod; MClass* _parentClass; - MString _name; + StringAnsi _name; - int32 _hasCachedAttributes : 1; - int32 _hasAddMonoMethod : 1; - int32 _hasRemoveMonoMethod : 1; + mutable int32 _hasCachedAttributes : 1; + mutable int32 _hasAddMonoMethod : 1; + mutable int32 _hasRemoveMonoMethod : 1; - Array _attributes; + mutable Array _attributes; public: - #if USE_MONO explicit MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass); +#elif USE_NETCORE + MEvent(MClass* parentClass, void* handle, const char* name); #endif public: - /// /// Gets the event name. /// - FORCE_INLINE const MString& GetName() const + FORCE_INLINE const StringAnsi& GetName() const { return _name; } @@ -56,22 +57,22 @@ public: /// /// Gets the event type class. /// - MType GetType(); + MType* GetType() const; /// /// Gets the event add method. /// - MMethod* GetAddMethod(); + MMethod* GetAddMethod() const; /// /// Gets the event remove method. /// - MMethod* GetRemoveMethod(); + MMethod* GetRemoveMethod() const; /// /// Gets event visibility in the class. /// - FORCE_INLINE MVisibility GetVisibility() + FORCE_INLINE MVisibility GetVisibility() const { return GetAddMethod()->GetVisibility(); } @@ -79,7 +80,7 @@ public: /// /// Returns true if event is static. /// - FORCE_INLINE bool IsStatic() + FORCE_INLINE bool IsStatic() const { return GetAddMethod()->IsStatic(); } @@ -95,7 +96,6 @@ public: #endif public: - /// /// Checks if event has an attribute of the specified type. /// @@ -120,5 +120,5 @@ public: /// Returns an instance of all attributes connected with given event. Returns null if the event doesn't have any attributes. /// /// The array of attribute objects. - const Array& GetAttributes(); + const Array& GetAttributes() const; }; diff --git a/Source/Engine/Scripting/MException.h b/Source/Engine/Scripting/ManagedCLR/MException.h similarity index 50% rename from Source/Engine/Scripting/MException.h rename to Source/Engine/Scripting/ManagedCLR/MException.h index 1ad9cc62a..86a531e5f 100644 --- a/Source/Engine/Scripting/MException.h +++ b/Source/Engine/Scripting/ManagedCLR/MException.h @@ -3,8 +3,8 @@ #pragma once #include "Engine/Core/Types/String.h" -#include "ManagedCLR/MTypes.h" #include "Engine/Core/Log.h" +#include "MTypes.h" /// /// Represents errors that occur during script execution. @@ -12,7 +12,6 @@ class FLAXENGINE_API MException { public: - /// /// Gets a message that describes the current exception. /// @@ -29,18 +28,6 @@ public: MException* InnerException; public: - -#if USE_MONO - /// - /// Initializes a new instance of the class. - /// - /// The exception. - explicit MException(MonoException* exception) - : MException((MonoObject*)exception) - { - } -#endif - /// /// Initializes a new instance of the class. /// @@ -53,26 +40,10 @@ public: ~MException(); public: - /// /// Sends exception to the log. /// /// The log message type. /// Execution target name. - void Log(const LogType type, const Char* target) - { - // Log inner exceptions chain - auto inner = InnerException; - while (inner) - { - auto stackTrace = inner->StackTrace.HasChars() ? *inner->StackTrace : TEXT(""); - Log::Logger::Write(LogType::Warning, String::Format(TEXT("Inner exception. {0}\nStack strace:\n{1}\n"), inner->Message, stackTrace)); - inner = inner->InnerException; - } - - // Send stack trace only to log file - auto stackTrace = StackTrace.HasChars() ? *StackTrace : TEXT(""); - Log::Logger::Write(LogType::Warning, String::Format(TEXT("Exception has been thrown during {0}. {1}\nStack strace:\n{2}"), target, Message, stackTrace)); - Log::Logger::Write(type, String::Format(TEXT("Exception has been thrown during {0}.\n{1}"), target, Message)); - } + void Log(const LogType type, const Char* target); }; diff --git a/Source/Engine/Scripting/ManagedCLR/MField.cpp b/Source/Engine/Scripting/ManagedCLR/MField.cpp deleted file mode 100644 index 400d19c56..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MField.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MField.h" -#include "MType.h" -#include "MClass.h" -#if USE_MONO -#include -#include - -MField::MField(MonoClassField* monoField, const char* name, MClass* parentClass) - : _monoField(monoField) - , _monoType(mono_field_get_type(monoField)) - , _parentClass(parentClass) - , _name(name) - , _hasCachedAttributes(false) -{ -#if BUILD_DEBUG - // Validate input name - ASSERT(StringUtils::Compare(name, mono_field_get_name(monoField)) == 0); -#endif - - const uint32_t flags = mono_field_get_flags(monoField); - switch (flags & MONO_FIELD_ATTR_FIELD_ACCESS_MASK) - { - case MONO_FIELD_ATTR_PRIVATE: - _visibility = MVisibility::Private; - break; - case MONO_FIELD_ATTR_FAM_AND_ASSEM: - _visibility = MVisibility::PrivateProtected; - break; - case MONO_FIELD_ATTR_ASSEMBLY: - _visibility = MVisibility::Internal; - break; - case MONO_FIELD_ATTR_FAMILY: - _visibility = MVisibility::Protected; - break; - case MONO_FIELD_ATTR_FAM_OR_ASSEM: - _visibility = MVisibility::ProtectedInternal; - break; - case MONO_FIELD_ATTR_PUBLIC: - _visibility = MVisibility::Public; - break; - default: - CRASH; - } - _isStatic = (flags & MONO_FIELD_ATTR_STATIC) != 0; -} - -#endif - -MType MField::GetType() const -{ -#if USE_MONO - return MType(_monoType); -#else - return MType(); -#endif -} - -int32 MField::GetOffset() const -{ -#if USE_MONO - return mono_field_get_offset(_monoField) - sizeof(MonoObject); -#else - return 0; -#endif -} - -void MField::GetValue(MObject* instance, void* result) const -{ -#if USE_MONO - mono_field_get_value(instance, _monoField, result); -#endif -} - -MObject* MField::GetValueBoxed(MObject* instance) const -{ -#if USE_MONO - return mono_field_get_value_object(mono_domain_get(), _monoField, instance); -#else - return nullptr; -#endif -} - -void MField::SetValue(MObject* instance, void* value) const -{ -#if USE_MONO - mono_field_set_value(instance, _monoField, value); -#endif -} - -bool MField::HasAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoClass* parentClass = mono_field_get_parent(_monoField); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); - if (attrInfo == nullptr) - return false; - - const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; - mono_custom_attrs_free(attrInfo); - return hasAttr; -#else - return false; -#endif -} - -bool MField::HasAttribute() const -{ -#if USE_MONO - MonoClass* parentClass = mono_field_get_parent(_monoField); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); - if (attrInfo == nullptr) - return false; - - if (attrInfo->num_attrs > 0) - { - mono_custom_attrs_free(attrInfo); - return true; - } - mono_custom_attrs_free(attrInfo); -#endif - return false; -} - -MObject* MField::GetAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoClass* parentClass = mono_field_get_parent(_monoField); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); - if (attrInfo == nullptr) - return nullptr; - - MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); - mono_custom_attrs_free(attrInfo); - return foundAttr; -#else - return nullptr; -#endif -} - -const Array& MField::GetAttributes() -{ - if (_hasCachedAttributes) - return _attributes; - - _hasCachedAttributes = true; -#if USE_MONO - MonoClass* parentClass = mono_field_get_parent(_monoField); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); - if (attrInfo == nullptr) - return _attributes; - - MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); - const auto length = (uint32)mono_array_length(monoAttributesArray); - _attributes.Resize(length); - for (uint32 i = 0; i < length; i++) - _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); - mono_custom_attrs_free(attrInfo); -#endif - return _attributes; -} diff --git a/Source/Engine/Scripting/ManagedCLR/MField.h b/Source/Engine/Scripting/ManagedCLR/MField.h index 820b5c9a5..796de27f7 100644 --- a/Source/Engine/Scripting/ManagedCLR/MField.h +++ b/Source/Engine/Scripting/ManagedCLR/MField.h @@ -13,34 +13,36 @@ class FLAXENGINE_API MField friend MClass; protected: - #if USE_MONO MonoClassField* _monoField; MonoType* _monoType; +#elif USE_NETCORE + void* _handle; + void* _type; #endif MClass* _parentClass; - MString _name; + StringAnsi _name; MVisibility _visibility; - int32 _hasCachedAttributes : 1; + mutable int32 _hasCachedAttributes : 1; int32 _isStatic : 1; - Array _attributes; + mutable Array _attributes; public: - #if USE_MONO explicit MField(MonoClassField* monoField, const char* name, MClass* parentClass); +#elif USE_NETCORE + MField(MClass* parentClass, void* handle, const char* name, void* type, MFieldAttributes attributes); #endif public: - /// /// Gets field name. /// - FORCE_INLINE const MString& GetName() const + FORCE_INLINE const StringAnsi& GetName() const { return _name; } @@ -56,7 +58,7 @@ public: /// /// Gets field type class. /// - MType GetType() const; + MType* GetType() const; /// /// Gets the field offset (in bytes) from the start of the parent object. @@ -90,7 +92,6 @@ public: #endif public: - /// /// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null. /// @@ -119,7 +120,6 @@ public: void SetValue(MObject* instance, void* value) const; public: - /// /// Checks if field has an attribute of the specified type. /// @@ -144,5 +144,5 @@ public: /// Returns an instance of all attributes connected with given field. Returns null if the field doesn't have any attributes. /// /// The array of attribute objects. - const Array& GetAttributes(); + const Array& GetAttributes() const; }; diff --git a/Source/Engine/Scripting/ManagedCLR/MMethod.cpp b/Source/Engine/Scripting/ManagedCLR/MMethod.cpp deleted file mode 100644 index ad6353284..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MMethod.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MMethod.h" -#include "MType.h" -#include "MClass.h" -#include "Engine/Profiler/ProfilerCPU.h" -#if USE_MONO -#include -#include - -MMethod::MMethod(MonoMethod* monoMethod, MClass* parentClass) - : MMethod(monoMethod, mono_method_get_name(monoMethod), parentClass) -{ -} - -MMethod::MMethod(MonoMethod* monoMethod, const char* name, MClass* parentClass) - : _monoMethod(monoMethod) - , _parentClass(parentClass) - , _name(name) - , _hasCachedAttributes(false) -{ -#if BUILD_DEBUG - // Validate input name - ASSERT(StringUtils::Compare(name, mono_method_get_name(monoMethod)) == 0); -#endif - - const uint32_t flags = mono_method_get_flags(monoMethod, nullptr); - _isStatic = (flags & MONO_METHOD_ATTR_STATIC) != 0; - switch (flags & MONO_METHOD_ATTR_ACCESS_MASK) - { - case MONO_METHOD_ATTR_PRIVATE: - _visibility = MVisibility::Private; - break; - case MONO_METHOD_ATTR_FAM_AND_ASSEM: - _visibility = MVisibility::PrivateProtected; - break; - case MONO_METHOD_ATTR_ASSEM: - _visibility = MVisibility::Internal; - break; - case MONO_METHOD_ATTR_FAMILY: - _visibility = MVisibility::Protected; - break; - case MONO_METHOD_ATTR_FAM_OR_ASSEM: - _visibility = MVisibility::ProtectedInternal; - break; - case MONO_METHOD_ATTR_PUBLIC: - _visibility = MVisibility::Public; - break; - default: - CRASH; - } - -#if COMPILE_WITH_PROFILER - const MString& className = parentClass->GetFullName(); - ProfilerName.Resize(className.Length() + 2 + _name.Length()); - Platform::MemoryCopy(ProfilerName.Get(), className.Get(), className.Length()); - ProfilerName.Get()[className.Length()] = ':'; - ProfilerName.Get()[className.Length() + 1] = ':'; - Platform::MemoryCopy(ProfilerName.Get() + className.Length() + 2, _name.Get(), _name.Length()); - ProfilerData.name = ProfilerName.Get(); - ProfilerData.function = _name.Get(); - ProfilerData.file = nullptr; - ProfilerData.line = 0; - ProfilerData.color = 0; -#endif -} - -#endif - -MObject* MMethod::Invoke(void* instance, void** params, MObject** exception) const -{ -#if USE_MONO - PROFILE_CPU_SRC_LOC(ProfilerData); - return mono_runtime_invoke(_monoMethod, instance, params, exception); -#else - return nullptr; -#endif -} - -MObject* MMethod::InvokeVirtual(MObject* instance, void** params, MObject** exception) const -{ -#if USE_MONO - PROFILE_CPU_SRC_LOC(ProfilerData); - MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, _monoMethod); - return mono_runtime_invoke(virtualMethod, instance, params, exception); -#else - return nullptr; -#endif -} - -#if !USE_MONO_AOT - -void* MMethod::GetThunk() -{ - if (!_cachedThunk) - { -#if USE_MONO - _cachedThunk = mono_method_get_unmanaged_thunk(_monoMethod); -#endif - } - return _cachedThunk; -} - -#endif - -MType MMethod::GetReturnType() const -{ -#if USE_MONO - MonoMethodSignature* sig = mono_method_signature(_monoMethod); - MonoType* returnType = mono_signature_get_return_type(sig); - return MType(returnType); -#else - return MType(); -#endif -} - -int32 MMethod::GetParametersCount() const -{ -#if USE_MONO - MonoMethodSignature* sig = mono_method_signature(_monoMethod); - return mono_signature_get_param_count(sig); -#else - return 0; -#endif -} - -MType MMethod::GetParameterType(int32 paramIdx) const -{ -#if USE_MONO - MonoMethodSignature* sig = mono_method_signature(_monoMethod); - ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig)); - void* it = nullptr; - mono_signature_get_params(sig, &it); - return MType(((MonoType**)it)[paramIdx]); -#else - return MType(); -#endif -} - -bool MMethod::GetParameterIsOut(int32 paramIdx) const -{ -#if USE_MONO - MonoMethodSignature* sig = mono_method_signature(_monoMethod); - ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig)); - return mono_signature_param_is_out(sig, paramIdx) != 0; -#else - return false; -#endif -} - -bool MMethod::HasAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); - if (attrInfo == nullptr) - return false; - - const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; - mono_custom_attrs_free(attrInfo); - return hasAttr; -#else - return false; -#endif -} - -bool MMethod::HasAttribute() const -{ -#if USE_MONO - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); - if (attrInfo == nullptr) - return false; - - if (attrInfo->num_attrs > 0) - { - mono_custom_attrs_free(attrInfo); - return true; - } - mono_custom_attrs_free(attrInfo); -#endif - return false; -} - -MObject* MMethod::GetAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); - if (attrInfo == nullptr) - return nullptr; - - MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); - mono_custom_attrs_free(attrInfo); - return foundAttr; -#else - return nullptr; -#endif -} - -const Array& MMethod::GetAttributes() -{ - if (_hasCachedAttributes) - return _attributes; - - _hasCachedAttributes = true; -#if USE_MONO - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); - if (attrInfo == nullptr) - return _attributes; - - MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); - const auto length = (uint32)mono_array_length(monoAttributesArray); - _attributes.Resize(length); - for (uint32 i = 0; i < length; i++) - _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); - mono_custom_attrs_free(attrInfo); -#endif - return _attributes; -} diff --git a/Source/Engine/Scripting/ManagedCLR/MMethod.h b/Source/Engine/Scripting/ManagedCLR/MMethod.h index c59c1d882..90804d186 100644 --- a/Source/Engine/Scripting/ManagedCLR/MMethod.h +++ b/Source/Engine/Scripting/ManagedCLR/MMethod.h @@ -18,33 +18,41 @@ class FLAXENGINE_API MMethod friend MEvent; protected: - #if USE_MONO MonoMethod* _monoMethod; +#elif USE_NETCORE + void* _handle; + int32 _paramsCount; + mutable void* _returnType; + mutable Array> _parameterTypes; + void CacheSignature() const; #endif MClass* _parentClass; - MString _name; + StringAnsi _name; MVisibility _visibility; #if !USE_MONO_AOT void* _cachedThunk = nullptr; #endif - int32 _hasCachedAttributes : 1; + mutable int32 _hasCachedAttributes : 1; +#if USE_NETCORE + mutable int32 _hasCachedSignature : 1; +#endif int32 _isStatic : 1; - Array _attributes; + mutable Array _attributes; public: - #if USE_MONO explicit MMethod(MonoMethod* monoMethod, MClass* parentClass); explicit MMethod(MonoMethod* monoMethod, const char* name, MClass* parentClass); +#elif USE_NETCORE + MMethod(MClass* parentClass, StringAnsi&& name, void* handle, int32 paramsCount, MMethodAttributes attributes); #endif public: - #if COMPILE_WITH_PROFILER - MString ProfilerName; + StringAnsi ProfilerName; SourceLocationData ProfilerData; #endif @@ -85,15 +93,22 @@ public: /// /// This is the fastest way of calling managed code. /// Get thunk from class if you want to call static method. You need to call it from method of a instance wrapper to call a specific instance. + /// Thunks return boxed value but for some smaller types (eg. bool, int, float) the return is inlined into pointer. /// /// The method thunk pointer. void* GetThunk(); #endif + /// + /// Creates a method that is inflated out of generic method. + /// + /// The inflated generic method. + MMethod* InflateGeneric() const; + /// /// Gets the method name. /// - FORCE_INLINE const MString& GetName() const + FORCE_INLINE const StringAnsi& GetName() const { return _name; } @@ -109,7 +124,7 @@ public: /// /// Returns the type of the return value. Returns null if method has no return value. /// - MType GetReturnType() const; + MType* GetReturnType() const; /// /// Returns the number of parameters the method expects. @@ -121,7 +136,7 @@ public: /// /// The parameter type. /// The parameter type. - MType GetParameterType(int32 paramIdx) const; + MType* GetParameterType(int32 paramIdx) const; /// /// Returns the value indicating whenever the method parameter at the specified index is marked as output parameter. @@ -157,7 +172,6 @@ public: #endif public: - /// /// Checks if method has an attribute of the specified type. /// @@ -182,5 +196,5 @@ public: /// Returns an instance of all attributes connected with given method. Returns null if the method doesn't have any attributes. /// /// The array of attribute objects. - const Array& GetAttributes(); + const Array& GetAttributes() const; }; diff --git a/Source/Engine/Scripting/ManagedCLR/MProperty.cpp b/Source/Engine/Scripting/ManagedCLR/MProperty.cpp deleted file mode 100644 index 5166ba4e0..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MProperty.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MProperty.h" -#include "Engine/Core/Math/Math.h" -#include "MMethod.h" -#include "MClass.h" -#include "MType.h" -#if USE_MONO -#include - -MProperty::MProperty(MonoProperty* monoProperty, const char* name, MClass* parentClass) - : _monoProperty(monoProperty) - , _getMethod(nullptr) - , _setMethod(nullptr) - , _parentClass(parentClass) - , _name(name) - , _hasCachedAttributes(false) - , _hasSetMethod(true) - , _hasGetMethod(true) -{ -#if BUILD_DEBUG - // Validate input name - ASSERT(StringUtils::Compare(name, mono_property_get_name(monoProperty)) == 0); -#endif - - GetGetMethod(); - GetSetMethod(); -} - -#endif - -MProperty::~MProperty() -{ - if (_getMethod) - Delete(_getMethod); - if (_setMethod) - Delete(_setMethod); -} - -MType MProperty::GetType() -{ - if (GetGetMethod() != nullptr) - return GetGetMethod()->GetReturnType(); - return GetSetMethod()->GetReturnType(); -} - -MMethod* MProperty::GetGetMethod() -{ - if (!_hasGetMethod) - return nullptr; - if (_getMethod == nullptr) - { -#if USE_MONO - auto method = mono_property_get_get_method(_monoProperty); - if (method != nullptr) - { - _hasGetMethod = true; - return _getMethod = New(method, _parentClass); - } -#endif - } - return _getMethod; -} - -MMethod* MProperty::GetSetMethod() -{ - if (!_hasSetMethod) - return nullptr; - if (_setMethod == nullptr) - { -#if USE_MONO - auto method = mono_property_get_set_method(_monoProperty); - if (method != nullptr) - { - _hasSetMethod = true; - return _setMethod = New(method, _parentClass); - } -#endif - } - return _setMethod; -} - -MVisibility MProperty::GetVisibility() -{ - if (GetGetMethod() && GetSetMethod()) - { - return static_cast( - Math::Max( - static_cast(GetGetMethod()->GetVisibility()), - static_cast(GetSetMethod()->GetVisibility()) - )); - } - if (GetGetMethod()) - { - return GetGetMethod()->GetVisibility(); - } - return GetSetMethod()->GetVisibility(); -} - -bool MProperty::IsStatic() -{ - if (GetGetMethod()) - { - return GetGetMethod()->IsStatic(); - } - if (GetSetMethod()) - { - return GetSetMethod()->IsStatic(); - } - return false; -} - -MObject* MProperty::GetValue(MObject* instance, MObject** exception) -{ -#if USE_MONO - return mono_property_get_value(_monoProperty, instance, nullptr, exception); -#else - return nullptr; -#endif -} - -void MProperty::SetValue(MObject* instance, void* value, MObject** exception) -{ -#if USE_MONO - void* params[1]; - params[0] = value; - mono_property_set_value(_monoProperty, instance, params, exception); -#endif -} - -bool MProperty::HasAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoClass* parentClass = mono_property_get_parent(_monoProperty); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); - if (attrInfo == nullptr) - return false; - - const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; - mono_custom_attrs_free(attrInfo); - return hasAttr; -#else - return false; -#endif -} - -bool MProperty::HasAttribute() const -{ -#if USE_MONO - MonoClass* parentClass = mono_property_get_parent(_monoProperty); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); - if (attrInfo == nullptr) - return false; - - if (attrInfo->num_attrs > 0) - { - mono_custom_attrs_free(attrInfo); - return true; - } - mono_custom_attrs_free(attrInfo); - return false; -#else - return false; -#endif -} - -MObject* MProperty::GetAttribute(MClass* monoClass) const -{ -#if USE_MONO - MonoClass* parentClass = mono_property_get_parent(_monoProperty); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); - if (attrInfo == nullptr) - return nullptr; - - MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); - mono_custom_attrs_free(attrInfo); - return foundAttr; -#else - return nullptr; -#endif -} - -const Array& MProperty::GetAttributes() -{ - if (_hasCachedAttributes) - return _attributes; - - _hasCachedAttributes = true; -#if USE_MONO - MonoClass* parentClass = mono_property_get_parent(_monoProperty); - MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); - if (attrInfo == nullptr) - return _attributes; - - MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); - const auto length = (uint32)mono_array_length(monoAttributesArray); - _attributes.Resize(length); - for (uint32 i = 0; i < length; i++) - _attributes[i] = mono_array_get(monoAttributesArray, MonoObject *, i); - mono_custom_attrs_free(attrInfo); -#endif - return _attributes; -} diff --git a/Source/Engine/Scripting/ManagedCLR/MProperty.h b/Source/Engine/Scripting/ManagedCLR/MProperty.h index a5fe2be43..8d3f560d7 100644 --- a/Source/Engine/Scripting/ManagedCLR/MProperty.h +++ b/Source/Engine/Scripting/ManagedCLR/MProperty.h @@ -14,27 +14,27 @@ class FLAXENGINE_API MProperty friend MClass; protected: - #if USE_MONO MonoProperty* _monoProperty; #endif - MMethod* _getMethod; - MMethod* _setMethod; + mutable MMethod* _getMethod; + mutable MMethod* _setMethod; MClass* _parentClass; - MString _name; + StringAnsi _name; - int32 _hasCachedAttributes : 1; - int32 _hasSetMethod : 1; - int32 _hasGetMethod : 1; + mutable int32 _hasCachedAttributes : 1; + mutable int32 _hasSetMethod : 1; + mutable int32 _hasGetMethod : 1; - Array _attributes; + mutable Array _attributes; public: - #if USE_MONO explicit MProperty(MonoProperty* monoProperty, const char* name, MClass* parentClass); +#elif USE_NETCORE + MProperty(MClass* parentClass, const char* name, void* getterHandle, void* setterHandle, MMethodAttributes getterAttributes, MMethodAttributes setterAttributes); #endif /// @@ -43,11 +43,10 @@ public: ~MProperty(); public: - /// /// Gets the property name. /// - FORCE_INLINE const MString& GetName() const + FORCE_INLINE const StringAnsi& GetName() const { return _name; } @@ -63,30 +62,29 @@ public: /// /// Gets property type class. /// - MType GetType(); + MType* GetType() const; /// /// Gets property get method. /// - MMethod* GetGetMethod(); + MMethod* GetGetMethod() const; /// /// Gets property set method. /// - MMethod* GetSetMethod(); + MMethod* GetSetMethod() const; /// /// Gets property visibility in the class. /// - MVisibility GetVisibility(); + MVisibility GetVisibility() const; /// /// Returns true if property is static. /// - bool IsStatic(); + bool IsStatic() const; public: - /// /// Retrieves value currently set in the property on the specified object instance. If property is static object instance can be null. /// @@ -96,7 +94,7 @@ public: /// The object of given type to get value from. /// An optional pointer to the exception value to store exception object reference. /// The returned boxed value object. - MObject* GetValue(MObject* instance, MObject** exception); + MObject* GetValue(MObject* instance, MObject** exception) const; /// /// Sets a value for the property on the specified object instance. If property is static object instance can be null. @@ -107,11 +105,9 @@ public: /// Object of given type to set value to. /// An optional pointer to the exception value to store exception object reference. /// The value to set of undefined type. - void SetValue(MObject* instance, void* value, MObject** exception); - + void SetValue(MObject* instance, void* value, MObject** exception) const; public: - /// /// Checks if property has an attribute of the specified type. /// @@ -136,5 +132,5 @@ public: /// Returns an instance of all attributes connected with given property. Returns null if the property doesn't have any attributes. /// /// The array of attribute objects. - const Array& GetAttributes(); + const Array& GetAttributes() const; }; diff --git a/Source/Engine/Scripting/ManagedCLR/MStaticConverter.h b/Source/Engine/Scripting/ManagedCLR/MStaticConverter.h deleted file mode 100644 index 3c5f248e1..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MStaticConverter.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#pragma once - -#include "Engine/Core/Types/String.h" -#if USE_MONO -#include -#endif - -/// -/// Class for converting mono classes and methods into usable form without instancing a class. -/// Mainly used for reflection where full object are not necessary. -/// -class MStaticConverter -{ -public: - -#if USE_MONO - static MonoClass* GetMonoClassFromObject(MonoObject* monoObject) - { - ASSERT(monoObject); - return mono_object_get_class(monoObject); - } - - static Array GetMonoClassArrayFromObjects(Array monoObjectArray) - { - ASSERT(monoObjectArray.Count() > 0); - Array array = Array(monoObjectArray.Count()); - for (auto i = 0; i < monoObjectArray.Count(); i++) - { - array.Add(GetMonoClassFromObject(monoObjectArray[i])); - } - return array; - } - - static String GetClassName(MonoClass* monoClass) - { - ASSERT(monoClass); - return String(mono_class_get_name(monoClass)); - } - - static Array GetClassNames(Array monoClassArray) - { - ASSERT(monoClassArray.Count() > 0); - Array array = Array(monoClassArray.Count()); - for (auto i = 0; i < monoClassArray.Count(); i++) - { - array.Add(GetClassName(monoClassArray[i])); - } - return array; - } - - static String GetClassNamespace(MonoClass* monoClass) - { - ASSERT(monoClass); - return String(mono_class_get_namespace(monoClass)); - } - - static Array GetClassNamespaces(Array monoClassArray) - { - ASSERT(monoClassArray.Count() > 0); - Array array = Array(monoClassArray.Count()); - for (auto i = 0; i < monoClassArray.Count(); i++) - { - array.Add(GetClassName(monoClassArray[i])); - } - return array; - } -#endif -}; diff --git a/Source/Engine/Scripting/ManagedCLR/MType.cpp b/Source/Engine/Scripting/ManagedCLR/MType.cpp deleted file mode 100644 index dfbc30a4c..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MType.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#include "MType.h" -#include "MUtils.h" -#if USE_MONO -#include - -String MType::ToString() const -{ - return _monoType ? String(mono_type_get_name(_monoType)) : String::Empty; -} - -bool MType::IsStruct() const -{ - ASSERT(_monoType); - return mono_type_is_struct(_monoType) != 0; -} - -bool MType::IsVoid() const -{ - ASSERT(_monoType); - return mono_type_is_void(_monoType) != 0; -} - -bool MType::IsPointer() const -{ - ASSERT(_monoType); - return mono_type_is_pointer(_monoType) != 0; -} - -bool MType::IsReference() const -{ - ASSERT(_monoType); - return mono_type_is_reference(_monoType) != 0; -} - -bool MType::IsByRef() const -{ - ASSERT(_monoType); - return mono_type_is_byref(_monoType) != 0; -} - -#else - -String MType::ToString() const -{ - return String::Empty; -} - -#endif diff --git a/Source/Engine/Scripting/ManagedCLR/MType.h b/Source/Engine/Scripting/ManagedCLR/MType.h deleted file mode 100644 index b0c58db7e..000000000 --- a/Source/Engine/Scripting/ManagedCLR/MType.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. - -#pragma once - -#include "MTypes.h" - -/// -/// Contains information about managed type. -/// -class MType -{ -public: - -#if USE_MONO - MonoType* _monoType; - - /// - /// Initializes a new instance of the class. - /// - /// The Mono type. - MType(MonoType* monoType) - : _monoType(monoType) - { - } - - /// - /// Initializes a new instance of the class. - /// - MType() - : _monoType(nullptr) - { - } -#endif - - /// - /// Finalizes an instance of the class. - /// - ~MType() - { - } - -public: - - String ToString() const; - -#if USE_MONO - /// - /// Gets mono type handle - /// - MonoType* GetNative() const - { - return _monoType; - } - - bool IsStruct() const; - bool IsVoid() const; - bool IsPointer() const; - bool IsReference() const; - bool IsByRef() const; - -public: - - FORCE_INLINE bool operator==(const MType& other) const - { - return _monoType == other._monoType; - } - - FORCE_INLINE bool operator!=(const MType& other) const - { - return _monoType != other._monoType; - } - - FORCE_INLINE operator bool() const - { - return _monoType != nullptr; - } -#endif -}; diff --git a/Source/Engine/Scripting/ManagedCLR/MTypes.h b/Source/Engine/Scripting/ManagedCLR/MTypes.h index 3b1cbb4a3..1ba69fce1 100644 --- a/Source/Engine/Scripting/ManagedCLR/MTypes.h +++ b/Source/Engine/Scripting/ManagedCLR/MTypes.h @@ -6,11 +6,6 @@ #include "Engine/Core/Types/String.h" #include "Engine/Core/Types/StringView.h" -/// -/// String container for names and typenames used by the managed runtime backend (8-bit chars). -/// -typedef StringAnsi MString; - enum class MVisibility { Private, @@ -20,3 +15,51 @@ enum class MVisibility ProtectedInternal, Public, }; + +enum class MTypes : uint32 +{ + End = 0x00, + Void = 0x01, + Boolean = 0x02, + Char = 0x03, + I1 = 0x04, + U1 = 0x05, + I2 = 0x06, + U2 = 0x07, + I4 = 0x08, + U4 = 0x09, + I8 = 0x0a, + U8 = 0x0b, + R4 = 0x0c, + R8 = 0x0d, + String = 0x0e, + Ptr = 0x0f, + ByRef = 0x10, + ValueType = 0x11, + Class = 0x12, + Var = 0x13, + Array = 0x14, + GenericInst = 0x15, + TypeByRef = 0x16, + I = 0x18, + U = 0x19, + Fnptr = 0x1b, + Object = 0x1c, + SzArray = 0x1d, + MVar = 0x1e, + CmodReqd = 0x1f, + CmodOpt = 0x20, + Internal = 0x21, + Modifier = 0x40, + Sentinel = 0x41, + Pinned = 0x45, + Enum = 0x55, +}; + +#if USE_NETCORE + +enum class MTypeAttributes : uint32; +enum class MMethodAttributes : uint32; +enum class MFieldAttributes : uint32; + +#endif diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp index d1c9af027..188135611 100644 --- a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp @@ -2,7 +2,8 @@ #include "MUtils.h" #include "MClass.h" -#include "MType.h" +#include "MCore.h" +#include "MDomain.h" #include "Engine/Core/Log.h" #include "Engine/Core/Types/DataContainer.h" #include "Engine/Core/Types/Version.h" @@ -19,288 +20,233 @@ #include "Engine/Core/Math/Ray.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/ScriptingObject.h" -#include "Engine/Scripting/StdTypesContainer.h" -#include "Engine/Scripting/InternalCalls/ManagedDictionary.h" +#include "Engine/Scripting/Internal/StdTypesContainer.h" +#include "Engine/Scripting/Internal/ManagedDictionary.h" #include "Engine/Utilities/StringConverter.h" #include "Engine/Content/Asset.h" -#if USE_NETCORE -#include "Engine/Scripting/DotNet/CoreCLR.h" -#endif - -#if USE_MONO - -// Inlined mono private types to access MonoType internals - -typedef struct _MonoGenericClass MonoGenericClass; -typedef struct _MonoGenericContext MonoGenericContext; - -struct _MonoGenericInst -{ - unsigned int id; - unsigned int type_argc : 22; - unsigned int is_open : 1; - MonoType* type_argv[MONO_ZERO_LEN_ARRAY]; -}; - -struct _MonoGenericContext -{ - MonoGenericInst* class_inst; - MonoGenericInst* method_inst; -}; - -struct _MonoGenericClass -{ - MonoClass* container_class; - MonoGenericContext context; - unsigned int is_dynamic : 1; - unsigned int is_tb_open : 1; - unsigned int need_sync : 1; - MonoClass* cached_class; - class MonoImageSet* owner; -}; - -struct _MonoType -{ - union - { - MonoClass* klass; - MonoType* type; - MonoArrayType* array; - MonoMethodSignature* method; - MonoGenericParam* generic_param; - MonoGenericClass* generic_class; - } data; - - unsigned int attrs : 16; - MonoTypeEnum type : 8; - unsigned int has_cmods : 1; - unsigned int byref : 1; - unsigned int pinned : 1; -}; +#if USE_CSHARP namespace { // typeName in format System.Collections.Generic.Dictionary`2[KeyType,ValueType] - void GetDictionaryKeyValueTypes(const StringAnsiView& typeName, MonoClass*& keyClass, MonoClass*& valueClass) + void GetDictionaryKeyValueTypes(const StringAnsiView& typeName, MClass*& keyClass, MClass*& valueClass) { const int32 keyStart = typeName.Find('['); const int32 keyEnd = typeName.Find(','); const int32 valueEnd = typeName.Find(']'); const StringAnsiView keyTypename(*typeName + keyStart + 1, keyEnd - keyStart - 1); const StringAnsiView valueTypename(*typeName + keyEnd + 1, valueEnd - keyEnd - 1); - keyClass = Scripting::FindClassNative(keyTypename); - valueClass = Scripting::FindClassNative(valueTypename); + keyClass = Scripting::FindClass(keyTypename); + valueClass = Scripting::FindClass(valueTypename); } } -StringView MUtils::ToString(MonoString* str) +StringView MUtils::ToString(MString* str) { if (str == nullptr) return StringView::Empty; - return StringView((const Char*)mono_string_chars(str), (int32)mono_string_length(str)); + return MCore::String::GetChars(str); } -StringAnsi MUtils::ToStringAnsi(MonoString* str) +StringAnsi MUtils::ToStringAnsi(MString* str) { if (str == nullptr) return StringAnsi::Empty; - return StringAnsi((const Char*)mono_string_chars(str), (int32)mono_string_length(str)); + return StringAnsi(MCore::String::GetChars(str)); } -void MUtils::ToString(MonoString* str, String& result) +void MUtils::ToString(MString* str, String& result) { if (str) - result.Set((const Char*)mono_string_chars(str), (int32)mono_string_length(str)); + { + const StringView chars = MCore::String::GetChars(str); + result.Set(chars.Get(), chars.Length()); + } else result.Clear(); } -void MUtils::ToString(MonoString* str, StringView& result) +void MUtils::ToString(MString* str, StringView& result) { if (str) - { - result = StringView((const Char*)mono_string_chars(str), (int32)mono_string_length(str)); - } + result = MCore::String::GetChars(str); else - { result = StringView(); - } } -void MUtils::ToString(MonoString* str, Variant& result) +void MUtils::ToString(MString* str, Variant& result) { - result.SetString(str ? StringView((const Char*)mono_string_chars(str), (int32)mono_string_length(str)) : StringView::Empty); + result.SetString(str ? MCore::String::GetChars(str) : StringView::Empty); } -void MUtils::ToString(MonoString* str, MString& result) +void MUtils::ToString(MString* str, StringAnsi& result) { if (str) - result.Set((const Char*)mono_string_chars(str), (int32)mono_string_length(str)); + { + const StringView chars = MCore::String::GetChars(str); + result.Set(chars.Get(), chars.Length()); + } else result.Clear(); } -MonoString* MUtils::ToString(const char* str) +MString* MUtils::ToString(const char* str) { if (str == nullptr || *str == 0) - return mono_string_empty(mono_domain_get()); - return mono_string_new(mono_domain_get(), str); + return MCore::String::GetEmpty(); + return MCore::String::New(str, StringUtils::Length(str)); } -MonoString* MUtils::ToString(const StringAnsi& str) +MString* MUtils::ToString(const StringAnsi& str) { if (str.IsEmpty()) - return mono_string_empty(mono_domain_get()); - return mono_string_new(mono_domain_get(), str.Get()); + return MCore::String::GetEmpty(); + return MCore::String::New(str.Get(), str.Length()); } -MonoString* MUtils::ToString(const String& str) +MString* MUtils::ToString(const String& str) { if (str.IsEmpty()) - return mono_string_empty(mono_domain_get()); - return mono_string_new_utf16(mono_domain_get(), (const mono_unichar2*)*str, str.Length()); + return MCore::String::GetEmpty(); + return MCore::String::New(str.Get(), str.Length()); } -MonoString* MUtils::ToString(const String& str, MonoDomain* domain) +MString* MUtils::ToString(const String& str, MDomain* domain) { if (str.IsEmpty()) - return mono_string_empty(domain); - return mono_string_new_utf16(domain, (const mono_unichar2*)*str, str.Length()); + return MCore::String::GetEmpty(domain); + return MCore::String::New(str.Get(), str.Length(), domain); } -MonoString* MUtils::ToString(const StringAnsiView& str) +MString* MUtils::ToString(const StringAnsiView& str) { if (str.IsEmpty()) - return mono_string_empty(mono_domain_get()); - return mono_string_new_len(mono_domain_get(), str.Get(), str.Length()); + return MCore::String::GetEmpty(); + return MCore::String::New(str.Get(), str.Length()); } -MonoString* MUtils::ToString(const StringView& str) +MString* MUtils::ToString(const StringView& str) { if (str.IsEmpty()) - return mono_string_empty(mono_domain_get()); - return mono_string_new_utf16(mono_domain_get(), (const mono_unichar2*)*str, str.Length()); + return MCore::String::GetEmpty(); + return MCore::String::New(str.Get(), str.Length()); } -MonoString* MUtils::ToString(const StringView& str, MonoDomain* domain) +MString* MUtils::ToString(const StringView& str, MDomain* domain) { if (str.IsEmpty()) - return mono_string_empty(domain); - return mono_string_new_utf16(domain, (const mono_unichar2*)*str, str.Length()); + return MCore::String::GetEmpty(domain); + return MCore::String::New(str.Get(), str.Length(), domain); } -ScriptingTypeHandle MUtils::UnboxScriptingTypeHandle(MonoReflectionType* value) +ScriptingTypeHandle MUtils::UnboxScriptingTypeHandle(MTypeObject* value) { - MonoClass* klass = GetClass(value); + MClass* klass = GetClass(value); if (!klass) return ScriptingTypeHandle(); - const MString typeName = MUtils::GetClassFullname(klass); + const StringAnsi& typeName = klass->GetFullName(); const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeName); if (!typeHandle) LOG(Warning, "Unknown scripting type {}", String(typeName)); return typeHandle; } -MonoReflectionType* MUtils::BoxScriptingTypeHandle(const ScriptingTypeHandle& value) +MTypeObject* MUtils::BoxScriptingTypeHandle(const ScriptingTypeHandle& value) { - MonoReflectionType* result = nullptr; + MTypeObject* result = nullptr; if (value) { - MonoType* monoType = mono_class_get_type(value.GetType().ManagedClass->GetNative()); - result = mono_type_get_object(mono_domain_get(), monoType); + MType* mType = value.GetType().ManagedClass->GetType(); + result = INTERNAL_TYPE_GET_OBJECT(mType); } return result; } -VariantType MUtils::UnboxVariantType(MonoReflectionType* value) +VariantType MUtils::UnboxVariantType(MType* type) { - if (value == nullptr) + if (!type) return VariantType(VariantType::Null); - return MoveTemp(UnboxVariantType(mono_reflection_type_get_type(value))); -} - -VariantType MUtils::UnboxVariantType(MonoType* monoType) -{ const auto& stdTypes = *StdTypesContainer::Instance(); - const auto klass = mono_type_get_class(monoType); + MClass* klass = MCore::Type::GetClass(type); + MTypes types = MCore::Type::GetType(type); // Fast type detection for in-built types - switch (monoType->type) + switch (types) { - case MONO_TYPE_VOID: + case MTypes::Void: return VariantType(VariantType::Void); - case MONO_TYPE_BOOLEAN: + case MTypes::Boolean: return VariantType(VariantType::Bool); - case MONO_TYPE_I1: - case MONO_TYPE_I2: + case MTypes::I1: + case MTypes::I2: return VariantType(VariantType::Int16); - case MONO_TYPE_U1: - case MONO_TYPE_U2: + case MTypes::U1: + case MTypes::U2: return VariantType(VariantType::Uint16); - case MONO_TYPE_I4: - case MONO_TYPE_CHAR: + case MTypes::I4: + case MTypes::Char: return VariantType(VariantType::Int); - case MONO_TYPE_U4: + case MTypes::U4: return VariantType(VariantType::Uint); - case MONO_TYPE_I8: + case MTypes::I8: return VariantType(VariantType::Int64); - case MONO_TYPE_U8: + case MTypes::U8: return VariantType(VariantType::Uint64); - case MONO_TYPE_R4: + case MTypes::R4: return VariantType(VariantType::Float); - case MONO_TYPE_R8: + case MTypes::R8: return VariantType(VariantType::Double); - case MONO_TYPE_STRING: + case MTypes::String: return VariantType(VariantType::String); - case MONO_TYPE_PTR: + case MTypes::Ptr: return VariantType(VariantType::Pointer); - case MONO_TYPE_VALUETYPE: - if (klass == stdTypes.GuidClass->GetNative()) + case MTypes::ValueType: + if (klass == stdTypes.GuidClass) return VariantType(VariantType::Guid); - if (klass == stdTypes.Vector2Class->GetNative()) + if (klass == stdTypes.Vector2Class) return VariantType(VariantType::Vector2); - if (klass == stdTypes.Vector3Class->GetNative()) + if (klass == stdTypes.Vector3Class) return VariantType(VariantType::Vector3); - if (klass == stdTypes.Vector4Class->GetNative()) + if (klass == stdTypes.Vector4Class) return VariantType(VariantType::Vector4); - if (klass == Int2::TypeInitializer.GetMonoClass()) + if (klass == Int2::TypeInitializer.GetClass()) return VariantType(VariantType::Int2); - if (klass == Int3::TypeInitializer.GetMonoClass()) + if (klass == Int3::TypeInitializer.GetClass()) return VariantType(VariantType::Int3); - if (klass == Int4::TypeInitializer.GetMonoClass()) + if (klass == Int4::TypeInitializer.GetClass()) return VariantType(VariantType::Int4); - if (klass == Float2::TypeInitializer.GetMonoClass()) + if (klass == Float2::TypeInitializer.GetClass()) return VariantType(VariantType::Float2); - if (klass == Float3::TypeInitializer.GetMonoClass()) + if (klass == Float3::TypeInitializer.GetClass()) return VariantType(VariantType::Float3); - if (klass == Float4::TypeInitializer.GetMonoClass()) + if (klass == Float4::TypeInitializer.GetClass()) return VariantType(VariantType::Float4); - if (klass == Double2::TypeInitializer.GetMonoClass()) + if (klass == Double2::TypeInitializer.GetClass()) return VariantType(VariantType::Double2); - if (klass == Double3::TypeInitializer.GetMonoClass()) + if (klass == Double3::TypeInitializer.GetClass()) return VariantType(VariantType::Double3); - if (klass == Double4::TypeInitializer.GetMonoClass()) + if (klass == Double4::TypeInitializer.GetClass()) return VariantType(VariantType::Double4); - if (klass == stdTypes.ColorClass->GetNative()) + if (klass == stdTypes.ColorClass) return VariantType(VariantType::Color); - if (klass == stdTypes.BoundingBoxClass->GetNative()) + if (klass == stdTypes.BoundingBoxClass) return VariantType(VariantType::BoundingBox); - if (klass == stdTypes.QuaternionClass->GetNative()) + if (klass == stdTypes.QuaternionClass) return VariantType(VariantType::Quaternion); - if (klass == stdTypes.TransformClass->GetNative()) + if (klass == stdTypes.TransformClass) return VariantType(VariantType::Transform); - if (klass == stdTypes.BoundingSphereClass->GetNative()) + if (klass == stdTypes.BoundingSphereClass) return VariantType(VariantType::BoundingSphere); - if (klass == stdTypes.RectangleClass->GetNative()) + if (klass == stdTypes.RectangleClass) return VariantType(VariantType::Rectangle); - if (klass == stdTypes.MatrixClass->GetNative()) + if (klass == stdTypes.MatrixClass) return VariantType(VariantType::Matrix); break; - case MONO_TYPE_OBJECT: + case MTypes::Object: return VariantType(VariantType::ManagedObject); - case MONO_TYPE_SZARRAY: - if (klass == mono_array_class_get(mono_get_byte_class(), 1)) + case MTypes::SzArray: + if (klass == MCore::Array::GetClass(MCore::TypeCache::Byte)) return VariantType(VariantType::Blob); break; } @@ -308,29 +254,28 @@ VariantType MUtils::UnboxVariantType(MonoType* monoType) // Get actual typename for full type info if (!klass) return VariantType(VariantType::Null); - MString fullname; - GetClassFullname(klass, fullname); - switch (monoType->type) + const StringAnsiView fullname = klass->GetFullName(); + switch (types) { - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: + case MTypes::SzArray: + case MTypes::Array: return VariantType(VariantType::Array, fullname); - case MONO_TYPE_ENUM: + case MTypes::Enum: return VariantType(VariantType::Enum, fullname); - case MONO_TYPE_VALUETYPE: + case MTypes::ValueType: return VariantType(VariantType::Structure, fullname); } - if (klass == stdTypes.TypeClass->GetNative()) + if (klass == stdTypes.TypeClass) return VariantType(VariantType::Typename); - if (mono_class_is_subclass_of(klass, Asset::GetStaticClass()->GetNative(), false) != 0) + if (klass->IsSubClassOf(Asset::GetStaticClass())) { - if (klass == Asset::GetStaticClass()->GetNative()) + if (klass == Asset::GetStaticClass()) return VariantType(VariantType::Asset); return VariantType(VariantType::Asset, fullname); } - if (mono_class_is_subclass_of(klass, ScriptingObject::GetStaticClass()->GetNative(), false) != 0) + if (klass->IsSubClassOf(ScriptingObject::GetStaticClass())) { - if (klass == ScriptingObject::GetStaticClass()->GetNative()) + if (klass == ScriptingObject::GetStaticClass()) return VariantType(VariantType::Object); return VariantType(VariantType::Object, fullname); } @@ -340,142 +285,137 @@ VariantType MUtils::UnboxVariantType(MonoType* monoType) return VariantType(); } -MonoReflectionType* MUtils::BoxVariantType(const VariantType& value) +MTypeObject* MUtils::BoxVariantType(const VariantType& value) { if (value.Type == VariantType::Null) return nullptr; - MonoClass* klass = GetClass(value); + MClass* klass = GetClass(value); if (!klass) { LOG(Error, "Invalid native type to box {0}", value); return nullptr; } - MonoType* monoType = mono_class_get_type(klass); - return mono_type_get_object(mono_domain_get(), monoType); + MType* mType = klass->GetType(); + return INTERNAL_TYPE_GET_OBJECT(mType); } -Variant MUtils::UnboxVariant(MonoObject* value) +Variant MUtils::UnboxVariant(MObject* value) { if (value == nullptr) return Variant::Null; const auto& stdTypes = *StdTypesContainer::Instance(); - const auto klass = mono_object_get_class(value); + MClass* klass = MCore::Object::GetClass(value); - MonoType* monoType = mono_class_get_type(klass); - const MonoTypeEnum monoTypeId = (MonoTypeEnum)mono_type_get_type(monoType); -#if USE_NETCORE - void* unboxed = mono_object_unbox(value); -#else - void* unboxed = (byte*)value + sizeof(MonoObject); -#endif + MType* mType = klass->GetType(); + const MTypes mTypes = MCore::Type::GetType(mType); + void* unboxed = MCore::Object::Unbox(value); // Fast type detection for in-built types - switch (monoTypeId) + switch (mTypes) { - case MONO_TYPE_VOID: + case MTypes::Void: return Variant(VariantType(VariantType::Void)); - case MONO_TYPE_BOOLEAN: + case MTypes::Boolean: return *static_cast(unboxed); - case MONO_TYPE_I1: + case MTypes::I1: return *static_cast(unboxed); - case MONO_TYPE_U1: + case MTypes::U1: return *static_cast(unboxed); - case MONO_TYPE_I2: + case MTypes::I2: return *static_cast(unboxed); - case MONO_TYPE_U2: + case MTypes::U2: return *static_cast(unboxed); - case MONO_TYPE_CHAR: + case MTypes::Char: return *static_cast(unboxed); - case MONO_TYPE_I4: + case MTypes::I4: return *static_cast(unboxed); - case MONO_TYPE_U4: + case MTypes::U4: return *static_cast(unboxed); - case MONO_TYPE_I8: + case MTypes::I8: return *static_cast(unboxed); - case MONO_TYPE_U8: + case MTypes::U8: return *static_cast(unboxed); - case MONO_TYPE_R4: + case MTypes::R4: return *static_cast(unboxed); - case MONO_TYPE_R8: + case MTypes::R8: return *static_cast(unboxed); - case MONO_TYPE_STRING: - return Variant(MUtils::ToString((MonoString*)value)); - case MONO_TYPE_PTR: + case MTypes::String: + return Variant(MUtils::ToString((MString*)value)); + case MTypes::Ptr: return *static_cast(unboxed); - case MONO_TYPE_VALUETYPE: - if (klass == stdTypes.GuidClass->GetNative()) + case MTypes::ValueType: + if (klass == stdTypes.GuidClass) return Variant(*static_cast(unboxed)); - if (klass == stdTypes.Vector2Class->GetNative()) + if (klass == stdTypes.Vector2Class) return *static_cast(unboxed); - if (klass == stdTypes.Vector3Class->GetNative()) + if (klass == stdTypes.Vector3Class) return *static_cast(unboxed); - if (klass == stdTypes.Vector4Class->GetNative()) + if (klass == stdTypes.Vector4Class) return *static_cast(unboxed); - if (klass == Int2::TypeInitializer.GetMonoClass()) + if (klass == Int2::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Int3::TypeInitializer.GetMonoClass()) + if (klass == Int3::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Int4::TypeInitializer.GetMonoClass()) + if (klass == Int4::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Float2::TypeInitializer.GetMonoClass()) + if (klass == Float2::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Float3::TypeInitializer.GetMonoClass()) + if (klass == Float3::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Float4::TypeInitializer.GetMonoClass()) + if (klass == Float4::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Double2::TypeInitializer.GetMonoClass()) + if (klass == Double2::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Double3::TypeInitializer.GetMonoClass()) + if (klass == Double3::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == Double4::TypeInitializer.GetMonoClass()) + if (klass == Double4::TypeInitializer.GetClass()) return *static_cast(unboxed); - if (klass == stdTypes.ColorClass->GetNative()) + if (klass == stdTypes.ColorClass) return *static_cast(unboxed); - if (klass == stdTypes.BoundingBoxClass->GetNative()) + if (klass == stdTypes.BoundingBoxClass) return Variant(*static_cast(unboxed)); - if (klass == stdTypes.QuaternionClass->GetNative()) + if (klass == stdTypes.QuaternionClass) return *static_cast(unboxed); - if (klass == stdTypes.TransformClass->GetNative()) + if (klass == stdTypes.TransformClass) return Variant(*static_cast(unboxed)); - if (klass == stdTypes.BoundingSphereClass->GetNative()) + if (klass == stdTypes.BoundingSphereClass) return *static_cast(unboxed); - if (klass == stdTypes.RectangleClass->GetNative()) + if (klass == stdTypes.RectangleClass) return *static_cast(unboxed); - if (klass == stdTypes.MatrixClass->GetNative()) + if (klass == stdTypes.MatrixClass) return Variant(*reinterpret_cast(unboxed)); break; - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: + case MTypes::SzArray: + case MTypes::Array: { - if (klass == mono_array_class_get(mono_get_byte_class(), 1)) + void* ptr = MCore::Array::GetAddress((MArray*)value); + if (klass->GetElementClass() == MCore::TypeCache::Byte) { Variant v; - v.SetBlob(mono_array_addr((MonoArray*)value, byte, 0), (int32)mono_array_length((MonoArray*)value)); + v.SetBlob(ptr, MCore::Array::GetLength((MArray*)value)); return v; } - MString fullname; - GetClassFullname(klass, fullname); + const StringAnsiView fullname = klass->GetFullName(); Variant v; v.SetType(MoveTemp(VariantType(VariantType::Array, fullname))); auto& array = v.AsArray(); - array.Resize((int32)mono_array_length((MonoArray*)value)); + array.Resize(MCore::Array::GetLength((MArray*)value)); const StringAnsiView elementTypename(*fullname, fullname.Length() - 2); - MonoClass* elementClass = mono_class_get_element_class(klass); - uint32_t elementAlign; - const int32 elementSize = mono_class_value_size(elementClass, &elementAlign); - if (mono_class_is_enum(elementClass)) + MClass* elementClass = klass->GetElementClass(); + const int32 elementSize = elementClass->GetInstanceSize(); + if (elementClass->IsEnum()) { // Array of Enums for (int32 i = 0; i < array.Count(); i++) { array[i].SetType(VariantType(VariantType::Enum, elementTypename)); - Platform::MemoryCopy(&array[i].AsUint64, mono_array_addr_with_size((MonoArray*)value, elementSize, i), elementSize); + Platform::MemoryCopy(&array[i].AsUint64, (byte*)ptr + elementSize * i, elementSize); } } - else if (mono_class_is_valuetype(elementClass)) + else if (elementClass->IsValueType()) { // Array of Structures - VariantType elementType = UnboxVariantType(mono_class_get_type(elementClass)); + VariantType elementType = UnboxVariantType(elementClass->GetType()); switch (elementType.Type) { case VariantType::Bool: @@ -509,7 +449,7 @@ Variant MUtils::UnboxVariant(MonoObject* value) { auto& a = array[i]; a.SetType(elementType); - Platform::MemoryCopy(&a.AsData, mono_array_addr_with_size((MonoArray*)value, elementSize, i), elementSize); + Platform::MemoryCopy(&a.AsData,(byte*)ptr + elementSize * i, elementSize); } break; case VariantType::Transform: @@ -525,7 +465,7 @@ Variant MUtils::UnboxVariant(MonoObject* value) { auto& a = array[i]; a.SetType(elementType); - Platform::MemoryCopy(a.AsBlob.Data, mono_array_addr_with_size((MonoArray*)value, elementSize, i), elementSize); + Platform::MemoryCopy(a.AsBlob.Data, (byte*)ptr + elementSize * i, elementSize); } break; case VariantType::Structure: @@ -541,10 +481,10 @@ Variant MUtils::UnboxVariant(MonoObject* value) { auto& a = array[i]; a.SetType(elementType); - void* managed = mono_array_addr_with_size((MonoArray*)value, elementSize, i); - // TODO: optimize structures unboxing to not require MonoObject* but raw managed value data to prevent additional boxing here - MonoObject* boxed = mono_object_new(mono_domain_get(), elementClass); - Platform::MemoryCopy(mono_object_unbox(boxed), managed, elementSize); + void* managed = (byte*)ptr + elementSize * i; + // TODO: optimize structures unboxing to not require MObject* but raw managed value data to prevent additional boxing here + MObject* boxed = MCore::Object::New(elementClass); + Platform::MemoryCopy(MCore::Object::Unbox(boxed), managed, elementSize); type.Struct.Unbox(a.AsBlob.Data, boxed); } break; @@ -561,54 +501,51 @@ Variant MUtils::UnboxVariant(MonoObject* value) { // Array of Objects for (int32 i = 0; i < array.Count(); i++) - array[i] = UnboxVariant(mono_array_get((MonoArray*)value, MonoObject*, i)); + array[i] = UnboxVariant(((MObject**)ptr)[i]); } return v; } - case MONO_TYPE_GENERICINST: + case MTypes::GenericInst: { - if (StringUtils::Compare(mono_class_get_name(klass), "Dictionary`2") == 0 && StringUtils::Compare(mono_class_get_namespace(klass), "System.Collections.Generic") == 0) + if (klass->GetName() == "Dictionary`2" && klass->GetNamespace() == "System.Collections.Generic") { // Dictionary ManagedDictionary managed(value); - MonoArray* managedKeys = managed.GetKeys(); - auto length = managedKeys ? (int32)mono_array_length(managedKeys) : 0; + MArray* managedKeys = managed.GetKeys(); + int32 length = managedKeys ? MCore::Array::GetLength(managedKeys) : 0; Dictionary native; native.EnsureCapacity(length); + MObject** managedKeysPtr = MCore::Array::GetAddress(managedKeys); for (int32 i = 0; i < length; i++) { - MonoObject* keyManaged = mono_array_get(managedKeys, MonoObject*, i); - MonoObject* valueManaged = managed.GetValue(keyManaged); + MObject* keyManaged = managedKeysPtr[i]; + MObject* valueManaged = managed.GetValue(keyManaged); native.Add(UnboxVariant(keyManaged), UnboxVariant(valueManaged)); } Variant v(MoveTemp(native)); - StringAnsi typeName; - GetClassFullname(klass, typeName); - v.Type.SetTypeName(typeName); + v.Type.SetTypeName(klass->GetFullName()); return v; } break; } } - if (mono_class_is_subclass_of(klass, Asset::GetStaticClass()->GetNative(), false) != 0) + if (klass->IsSubClassOf(Asset::GetStaticClass())) return static_cast(ScriptingObject::ToNative(value)); - if (mono_class_is_subclass_of(klass, ScriptingObject::GetStaticClass()->GetNative(), false) != 0) + if (klass->IsSubClassOf(ScriptingObject::GetStaticClass())) return ScriptingObject::ToNative(value); - if (mono_class_is_enum(klass)) + if (klass->IsEnum()) { - MString fullname; - GetClassFullname(klass, fullname); + const StringAnsiView fullname = klass->GetFullName(); Variant v; v.Type = MoveTemp(VariantType(VariantType::Enum, fullname)); // TODO: what about 64-bit enum? use enum size with memcpy - v.AsUint64 = *static_cast(mono_object_unbox(value)); + v.AsUint64 = *static_cast(MCore::Object::Unbox(value)); return v; } - if (mono_class_is_valuetype(klass)) + if (klass->IsValueType()) { - MString fullname; - GetClassFullname(klass, fullname); + const StringAnsiView fullname = klass->GetFullName(); const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(fullname); if (typeHandle) { @@ -627,7 +564,7 @@ Variant MUtils::UnboxVariant(MonoObject* value) return Variant(value); } -MonoObject* MUtils::BoxVariant(const Variant& value) +MObject* MUtils::BoxVariant(const Variant& value) { const auto& stdTypes = *StdTypesContainer::Instance(); switch (value.Type.Type) @@ -636,101 +573,100 @@ MonoObject* MUtils::BoxVariant(const Variant& value) case VariantType::Void: return nullptr; case VariantType::Bool: - return mono_value_box(mono_domain_get(), mono_get_boolean_class(), (void*)&value.AsBool); + return MCore::Object::Box((void*)&value.AsBool, MCore::TypeCache::Boolean); case VariantType::Int16: - return mono_value_box(mono_domain_get(), mono_get_int16_class(), (void*)&value.AsInt16); + return MCore::Object::Box((void*)&value.AsInt16, MCore::TypeCache::Int16); case VariantType::Uint16: - return mono_value_box(mono_domain_get(), mono_get_uint16_class(), (void*)&value.AsUint16); + return MCore::Object::Box((void*)&value.AsUint16, MCore::TypeCache::UInt16); case VariantType::Int: - return mono_value_box(mono_domain_get(), mono_get_int32_class(), (void*)&value.AsInt); + return MCore::Object::Box((void*)&value.AsInt, MCore::TypeCache::Int32); case VariantType::Uint: - return mono_value_box(mono_domain_get(), mono_get_uint32_class(), (void*)&value.AsUint); + return MCore::Object::Box((void*)&value.AsUint, MCore::TypeCache::UInt32); case VariantType::Int64: - return mono_value_box(mono_domain_get(), mono_get_int64_class(), (void*)&value.AsInt64); + return MCore::Object::Box((void*)&value.AsInt64, MCore::TypeCache::Int64); case VariantType::Uint64: - return mono_value_box(mono_domain_get(), mono_get_uint64_class(), (void*)&value.AsUint64); + return MCore::Object::Box((void*)&value.AsUint64, MCore::TypeCache::UInt64); case VariantType::Float: - return mono_value_box(mono_domain_get(), mono_get_single_class(), (void*)&value.AsFloat); + return MCore::Object::Box((void*)&value.AsFloat, MCore::TypeCache::Single); case VariantType::Double: - return mono_value_box(mono_domain_get(), mono_get_double_class(), (void*)&value.AsDouble); + return MCore::Object::Box((void*)&value.AsDouble, MCore::TypeCache::Double); case VariantType::Float2: - return mono_value_box(mono_domain_get(), Float2::TypeInitializer.GetMonoClass(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, Float2::TypeInitializer.GetClass()); case VariantType::Float3: - return mono_value_box(mono_domain_get(), Float3::TypeInitializer.GetMonoClass(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, Float3::TypeInitializer.GetClass()); case VariantType::Float4: - return mono_value_box(mono_domain_get(), Float4::TypeInitializer.GetMonoClass(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, Float4::TypeInitializer.GetClass()); case VariantType::Double2: - return mono_value_box(mono_domain_get(), Double2::TypeInitializer.GetMonoClass(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, Double2::TypeInitializer.GetClass()); case VariantType::Double3: - return mono_value_box(mono_domain_get(), Double3::TypeInitializer.GetMonoClass(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, Double3::TypeInitializer.GetClass()); case VariantType::Double4: - return mono_value_box(mono_domain_get(), Double4::TypeInitializer.GetMonoClass(), value.AsBlob.Data); + return MCore::Object::Box((void*)&value.AsData, Double4::TypeInitializer.GetClass()); case VariantType::Color: - return mono_value_box(mono_domain_get(), stdTypes.ColorClass->GetNative(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, stdTypes.ColorClass); case VariantType::Guid: - return mono_value_box(mono_domain_get(), stdTypes.GuidClass->GetNative(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, stdTypes.GuidClass); case VariantType::String: #if USE_NETCORE - return (MonoObject*)MUtils::ToString((StringView)value); + return (MObject*)MUtils::ToString((StringView)value); #else - return (MonoObject*)MUtils::ToString((StringView)value); + return (MObject*)MUtils::ToString((StringView)value); #endif case VariantType::Quaternion: - return mono_value_box(mono_domain_get(), stdTypes.QuaternionClass->GetNative(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, stdTypes.QuaternionClass); case VariantType::BoundingSphere: - return mono_value_box(mono_domain_get(), stdTypes.BoundingSphereClass->GetNative(), (void*)&value.AsBoundingSphere()); + return MCore::Object::Box((void*)&value.AsBoundingSphere(), stdTypes.BoundingSphereClass); case VariantType::Rectangle: - return mono_value_box(mono_domain_get(), stdTypes.RectangleClass->GetNative(), (void*)&value.AsData); + return MCore::Object::Box((void*)&value.AsData, stdTypes.RectangleClass); case VariantType::Pointer: - return mono_value_box(mono_domain_get(), mono_get_intptr_class(), (void*)&value.AsPointer); + return MCore::Object::Box((void*)&value.AsPointer, MCore::TypeCache::IntPtr); case VariantType::Ray: - return mono_value_box(mono_domain_get(), stdTypes.RayClass->GetNative(), (void*)&value.AsRay()); + return MCore::Object::Box((void*)&value.AsRay(), stdTypes.RayClass); case VariantType::BoundingBox: - return mono_value_box(mono_domain_get(), stdTypes.BoundingBoxClass->GetNative(), (void*)&value.AsBoundingBox()); + return MCore::Object::Box((void*)&value.AsBoundingBox(), stdTypes.BoundingBoxClass); case VariantType::Transform: - return mono_value_box(mono_domain_get(), stdTypes.TransformClass->GetNative(), value.AsBlob.Data); + return MCore::Object::Box(value.AsBlob.Data, stdTypes.TransformClass); case VariantType::Matrix: - return mono_value_box(mono_domain_get(), stdTypes.MatrixClass->GetNative(), value.AsBlob.Data); + return MCore::Object::Box(value.AsBlob.Data, stdTypes.MatrixClass); case VariantType::Blob: - return (MonoObject*)ToArray(Span((const byte*)value.AsBlob.Data, value.AsBlob.Length)); + return (MObject*)ToArray(Span((const byte*)value.AsBlob.Data, value.AsBlob.Length)); case VariantType::Object: return value.AsObject ? value.AsObject->GetOrCreateManagedInstance() : nullptr; case VariantType::Asset: return value.AsAsset ? value.AsAsset->GetOrCreateManagedInstance() : nullptr; case VariantType::Array: { - MonoArray* managed; + MArray* managed; const auto& array = value.AsArray(); if (value.Type.TypeName) { const StringAnsiView elementTypename(value.Type.TypeName, StringUtils::Length(value.Type.TypeName) - 2); const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(elementTypename); - MonoClass* elementClass; + MClass* elementClass; if (typeHandle && typeHandle.GetType().ManagedClass) - elementClass = typeHandle.GetType().ManagedClass->GetNative(); + elementClass = typeHandle.GetType().ManagedClass; else - elementClass = Scripting::FindClassNative(elementTypename); + elementClass = Scripting::FindClass(elementTypename); if (!elementClass) { LOG(Error, "Invalid type to box {0}", value.Type); return nullptr; } - uint32_t elementAlign; - const int32 elementSize = mono_class_value_size(elementClass, &elementAlign); - managed = mono_array_new(mono_domain_get(), elementClass, array.Count()); - if (mono_class_is_enum(elementClass)) + const int32 elementSize = elementClass->GetInstanceSize(); + managed = MCore::Array::New(elementClass, array.Count()); + if (elementClass->IsEnum()) { // Array of Enums for (int32 i = 0; i < array.Count(); i++) { auto data = (uint64)array[i]; - Platform::MemoryCopy(mono_array_addr_with_size(managed, elementSize, i), &data, elementSize); + Platform::MemoryCopy((byte*)MCore::Array::GetAddress(managed) + elementSize * i, &data, elementSize); } } - else if (mono_class_is_valuetype(elementClass)) + else if (elementClass->IsValueType()) { // Array of Structures - const VariantType elementType = UnboxVariantType(mono_class_get_type(elementClass)); + const VariantType elementType = UnboxVariantType(elementClass->GetType()); switch (elementType.Type) { case VariantType::Bool: @@ -761,7 +697,7 @@ MonoObject* MUtils::BoxVariant(const Variant& value) #endif // Optimized boxing of raw data type for (int32 i = 0; i < array.Count(); i++) - Platform::MemoryCopy(mono_array_addr_with_size(managed, elementSize, i), &array[i].AsData, elementSize); + Platform::MemoryCopy((byte*)MCore::Array::GetAddress(managed) + elementSize * i, &array[i].AsData, elementSize); break; case VariantType::Transform: case VariantType::Matrix: @@ -773,7 +709,7 @@ MonoObject* MUtils::BoxVariant(const Variant& value) #endif // Optimized boxing of raw data type for (int32 i = 0; i < array.Count(); i++) - Platform::MemoryCopy(mono_array_addr_with_size(managed, elementSize, i), array[i].AsBlob.Data, elementSize); + Platform::MemoryCopy((byte*)MCore::Array::GetAddress(managed) + elementSize * i, array[i].AsBlob.Data, elementSize); break; case VariantType::Structure: if (typeHandle) @@ -782,9 +718,9 @@ MonoObject* MUtils::BoxVariant(const Variant& value) ASSERT(type.Type == ScriptingTypes::Structure); for (int32 i = 0; i < array.Count(); i++) { - // TODO: optimize structures boxing to not return MonoObject* but use raw managed object to prevent additional boxing here - MonoObject* boxed = type.Struct.Box(array[i].AsBlob.Data); - Platform::MemoryCopy(mono_array_addr_with_size(managed, elementSize, i), mono_object_unbox(boxed), elementSize); + // TODO: optimize structures boxing to not return MObject* but use raw managed object to prevent additional boxing here + MObject* boxed = type.Struct.Box(array[i].AsBlob.Data); + Platform::MemoryCopy((byte*)MCore::Array::GetAddress(managed) + elementSize * i, MCore::Object::Unbox(boxed), elementSize); } break; } @@ -799,22 +735,22 @@ MonoObject* MUtils::BoxVariant(const Variant& value) { // Array of Objects for (int32 i = 0; i < array.Count(); i++) - mono_array_setref(managed, i, BoxVariant(array[i])); + MCore::GC::WriteArrayRef(managed, BoxVariant(array[i]), i); } } else { // object[] - managed = mono_array_new(mono_domain_get(), mono_get_object_class(), array.Count()); + managed = MCore::Array::New(MCore::TypeCache::Object, array.Count()); for (int32 i = 0; i < array.Count(); i++) - mono_array_setref(managed, i, BoxVariant(array[i])); + MCore::GC::WriteArrayRef(managed, BoxVariant(array[i]), i); } - return (MonoObject*)managed; + return (MObject*)managed; } case VariantType::Dictionary: { // Get dictionary key and value types - MonoClass *keyClass, *valueClass; + MClass *keyClass, *valueClass; GetDictionaryKeyValueTypes(value.Type.GetTypeName(), keyClass, valueClass); if (!keyClass || !valueClass) { @@ -823,7 +759,7 @@ MonoObject* MUtils::BoxVariant(const Variant& value) } // Allocate managed dictionary - ManagedDictionary managed = ManagedDictionary::New(mono_class_get_type(keyClass), mono_class_get_type(valueClass)); + ManagedDictionary managed = ManagedDictionary::New(keyClass->GetType(), valueClass->GetType()); if (!managed.Instance) return nullptr; @@ -851,23 +787,23 @@ MonoObject* MUtils::BoxVariant(const Variant& value) } case VariantType::Enum: { - const auto klass = Scripting::FindClassNative(StringAnsiView(value.Type.TypeName)); + const auto klass = Scripting::FindClass(StringAnsiView(value.Type.TypeName)); if (klass) - return mono_value_box(mono_domain_get(), klass, (void*)&value.AsUint64); + return MCore::Object::Box((void*)&value.AsUint64, klass); LOG(Error, "Invalid type to box {0}", value.Type); return nullptr; } case VariantType::ManagedObject: #if USE_NETCORE - return value.AsUint64 ? MUtils::GetGCHandleTarget(value.AsUint64) : nullptr; + return value.AsUint64 ? MCore::GCHandle::GetTarget(value.AsUint64) : nullptr; #else - return value.AsUint ? MUtils::GetGCHandleTarget(value.AsUint) : nullptr; + return value.AsUint ? MCore::GCHandle::GetTarget(value.AsUint) : nullptr; #endif case VariantType::Typename: { - const auto klass = Scripting::FindClassNative((StringAnsiView)value); + const auto klass = Scripting::FindClass((StringAnsiView)value); if (klass) - return (MonoObject*)GetType(klass); + return (MObject*)GetType(klass); LOG(Error, "Invalid type to box {0}", value); return nullptr; } @@ -877,341 +813,279 @@ MonoObject* MUtils::BoxVariant(const Variant& value) } } -void MUtils::GetClassFullname(MonoObject* obj, MString& fullname) +const StringAnsi& MUtils::GetClassFullname(MObject* obj) { - if (obj == nullptr) - return; - MonoClass* monoClass = mono_object_get_class(obj); - GetClassFullname(monoClass, fullname); -} - -void MUtils::GetClassFullname(MonoClass* monoClass, MString& fullname) -{ -#if USE_NETCORE - fullname = CoreCLR::GetClassFullname(monoClass); -#else - static MString plusStr("+"); - static MString dotStr("."); - - // Name - fullname = mono_class_get_name(monoClass); - - // Outer class for nested types - MonoClass* nestingClass = mono_class_get_nesting_type(monoClass); - MonoClass* lastClass = monoClass; - while (nestingClass) + if (obj) { - lastClass = nestingClass; - fullname = mono_class_get_name(nestingClass) + plusStr + fullname; - nestingClass = mono_class_get_nesting_type(nestingClass); + MClass* mClass = MCore::Object::GetClass(obj); + return mClass->GetFullName(); } - - // Namespace - const char* lastClassNamespace = mono_class_get_namespace(lastClass); - if (lastClassNamespace && *lastClassNamespace) - fullname = lastClassNamespace + dotStr + fullname; - - // Generic instance arguments - const MonoType* monoType = mono_class_get_type(monoClass); - if (monoType && monoType->type == MONO_TYPE_GENERICINST) - { - fullname += '['; - MString tmp; - for (unsigned int i = 0; i < monoType->data.generic_class->context.class_inst->type_argc; i++) - { - if (i != 0) - fullname += ','; - MonoType* argType = monoType->data.generic_class->context.class_inst->type_argv[i]; - GetClassFullname(mono_type_get_class(argType), tmp); - fullname += tmp; - } - fullname += ']'; - } -#endif + return StringAnsi::Empty; } -void MUtils::GetClassFullname(MonoReflectionType* type, MString& fullname) +MClass* MUtils::GetClass(MTypeObject* type) { - if (!type) - return; - MonoType* monoType = mono_reflection_type_get_type(type); - MonoClass* monoClass = mono_class_from_mono_type(monoType); - GetClassFullname(monoClass, fullname); -} - -MonoClass* MUtils::GetClass(MonoObject* object) -{ - return mono_object_get_class(object); -} - -MonoClass* MUtils::GetClass(MonoReflectionType* type) -{ - if (!type) + if (type == nullptr) return nullptr; - MonoType* monoType = mono_reflection_type_get_type(type); - return mono_class_from_mono_type(monoType); + MType* mType = INTERNAL_TYPE_OBJECT_GET(type); + return MCore::Type::GetClass(mType); } -MonoClass* MUtils::GetClass(const VariantType& value) +MClass* MUtils::GetClass(const VariantType& value) { - const auto& stdTypes = *StdTypesContainer::Instance(); auto mclass = Scripting::FindClass(StringAnsiView(value.TypeName)); if (mclass) - return mclass->GetNative(); + return mclass; + const auto& stdTypes = *StdTypesContainer::Instance(); switch (value.Type) { case VariantType::Void: - return mono_get_void_class(); + return MCore::TypeCache::Void; case VariantType::Bool: - return mono_get_boolean_class(); + return MCore::TypeCache::Boolean; case VariantType::Int16: - return mono_get_int16_class(); + return MCore::TypeCache::Int16; case VariantType::Uint16: - return mono_get_uint16_class(); + return MCore::TypeCache::UInt16; case VariantType::Int: - return mono_get_int32_class(); + return MCore::TypeCache::Int32; case VariantType::Uint: - return mono_get_uint32_class(); + return MCore::TypeCache::UInt32; case VariantType::Int64: - return mono_get_int64_class(); + return MCore::TypeCache::Int64; case VariantType::Uint64: - return mono_get_uint64_class(); + return MCore::TypeCache::UInt64; case VariantType::Float: - return mono_get_single_class(); + return MCore::TypeCache::Single; case VariantType::Double: - return mono_get_double_class(); + return MCore::TypeCache::Double; case VariantType::Pointer: - return mono_get_intptr_class(); + return MCore::TypeCache::IntPtr; case VariantType::String: - return mono_get_string_class(); + return MCore::TypeCache::String; case VariantType::Object: - return ScriptingObject::GetStaticClass()->GetNative(); + return ScriptingObject::GetStaticClass(); case VariantType::Asset: - return Asset::GetStaticClass()->GetNative(); + return Asset::GetStaticClass(); case VariantType::Blob: - return mono_array_class_get(mono_get_byte_class(), 1); + return MCore::Array::GetClass(MCore::TypeCache::Byte); case VariantType::Float2: - return Double2::TypeInitializer.GetMonoClass(); + return Double2::TypeInitializer.GetClass(); case VariantType::Float3: - return Float3::TypeInitializer.GetMonoClass(); + return Float3::TypeInitializer.GetClass(); case VariantType::Float4: - return Float4::TypeInitializer.GetMonoClass(); + return Float4::TypeInitializer.GetClass(); case VariantType::Double2: - return Double2::TypeInitializer.GetMonoClass(); + return Double2::TypeInitializer.GetClass(); case VariantType::Double3: - return Double3::TypeInitializer.GetMonoClass(); + return Double3::TypeInitializer.GetClass(); case VariantType::Double4: - return Double4::TypeInitializer.GetMonoClass(); + return Double4::TypeInitializer.GetClass(); case VariantType::Color: - return stdTypes.ColorClass->GetNative(); + return stdTypes.ColorClass; case VariantType::Guid: - return stdTypes.GuidClass->GetNative(); + return stdTypes.GuidClass; case VariantType::Typename: - return stdTypes.TypeClass->GetNative(); + return stdTypes.TypeClass; case VariantType::BoundingBox: - return stdTypes.BoundingBoxClass->GetNative(); + return stdTypes.BoundingBoxClass; case VariantType::BoundingSphere: - return stdTypes.BoundingSphereClass->GetNative(); + return stdTypes.BoundingSphereClass; case VariantType::Quaternion: - return stdTypes.QuaternionClass->GetNative(); + return stdTypes.QuaternionClass; case VariantType::Transform: - return stdTypes.TransformClass->GetNative(); + return stdTypes.TransformClass; case VariantType::Rectangle: - return stdTypes.RectangleClass->GetNative(); + return stdTypes.RectangleClass; case VariantType::Ray: - return stdTypes.RayClass->GetNative(); + return stdTypes.RayClass; case VariantType::Matrix: - return stdTypes.MatrixClass->GetNative(); + return stdTypes.MatrixClass; case VariantType::Array: if (value.TypeName) { const StringAnsiView elementTypename(value.TypeName, StringUtils::Length(value.TypeName) - 2); mclass = Scripting::FindClass(elementTypename); if (mclass) - return mono_array_class_get(mclass->GetNative(), 1); + return MCore::Array::GetClass(mclass); } - return mono_array_class_get(mono_get_object_class(), 1); + return MCore::Array::GetClass(MCore::TypeCache::Object); case VariantType::Dictionary: { - MonoClass *keyClass, *valueClass; + MClass *keyClass, *valueClass; GetDictionaryKeyValueTypes(value.GetTypeName(), keyClass, valueClass); if (!keyClass || !valueClass) { LOG(Error, "Invalid type to box {0}", value.ToString()); return nullptr; } - return GetClass(ManagedDictionary::GetClass(mono_class_get_type(keyClass), mono_class_get_type(valueClass))); + return GetClass(ManagedDictionary::GetClass(keyClass->GetType(), valueClass->GetType())); } case VariantType::ManagedObject: - return mono_get_object_class(); + return MCore::TypeCache::Object; default: ; } return nullptr; } -MonoClass* MUtils::GetClass(const Variant& value) +MClass* MUtils::GetClass(const Variant& value) { const auto& stdTypes = *StdTypesContainer::Instance(); switch (value.Type.Type) { case VariantType::Void: - return mono_get_void_class(); + return MCore::TypeCache::Void; case VariantType::Bool: - return mono_get_boolean_class(); + return MCore::TypeCache::Boolean; case VariantType::Int16: - return mono_get_int16_class(); + return MCore::TypeCache::Int16; case VariantType::Uint16: - return mono_get_uint16_class(); + return MCore::TypeCache::UInt16; case VariantType::Int: - return mono_get_int32_class(); + return MCore::TypeCache::Int32; case VariantType::Uint: - return mono_get_uint32_class(); + return MCore::TypeCache::UInt32; case VariantType::Int64: - return mono_get_int64_class(); + return MCore::TypeCache::Int64; case VariantType::Uint64: - return mono_get_uint64_class(); + return MCore::TypeCache::UInt64; case VariantType::Float: - return mono_get_single_class(); + return MCore::TypeCache::Single; case VariantType::Double: - return mono_get_double_class(); + return MCore::TypeCache::Double; case VariantType::Pointer: - return mono_get_intptr_class(); + return MCore::TypeCache::IntPtr; case VariantType::String: - return mono_get_string_class(); + return MCore::TypeCache::String; case VariantType::Blob: - return mono_array_class_get(mono_get_byte_class(), 1); + return MCore::Array::GetClass(MCore::TypeCache::Byte); case VariantType::Float2: - return Float2::TypeInitializer.GetMonoClass(); + return Float2::TypeInitializer.GetClass(); case VariantType::Float3: - return Float3::TypeInitializer.GetMonoClass(); + return Float3::TypeInitializer.GetClass(); case VariantType::Float4: - return Float4::TypeInitializer.GetMonoClass(); + return Float4::TypeInitializer.GetClass(); case VariantType::Double2: - return Double2::TypeInitializer.GetMonoClass(); + return Double2::TypeInitializer.GetClass(); case VariantType::Double3: - return Double3::TypeInitializer.GetMonoClass(); + return Double3::TypeInitializer.GetClass(); case VariantType::Double4: - return Double4::TypeInitializer.GetMonoClass(); + return Double4::TypeInitializer.GetClass(); case VariantType::Color: - return stdTypes.ColorClass->GetNative(); + return stdTypes.ColorClass; case VariantType::Guid: - return stdTypes.GuidClass->GetNative(); + return stdTypes.GuidClass; case VariantType::Typename: - return stdTypes.TypeClass->GetNative(); + return stdTypes.TypeClass; case VariantType::BoundingBox: - return stdTypes.BoundingBoxClass->GetNative(); + return stdTypes.BoundingBoxClass; case VariantType::BoundingSphere: - return stdTypes.BoundingSphereClass->GetNative(); + return stdTypes.BoundingSphereClass; case VariantType::Quaternion: - return stdTypes.QuaternionClass->GetNative(); + return stdTypes.QuaternionClass; case VariantType::Transform: - return stdTypes.TransformClass->GetNative(); + return stdTypes.TransformClass; case VariantType::Rectangle: - return stdTypes.RectangleClass->GetNative(); + return stdTypes.RectangleClass; case VariantType::Ray: - return stdTypes.RayClass->GetNative(); + return stdTypes.RayClass; case VariantType::Matrix: - return stdTypes.MatrixClass->GetNative(); + return stdTypes.MatrixClass; case VariantType::Array: case VariantType::Dictionary: return GetClass(value.Type); case VariantType::Object: - return value.AsObject ? value.AsObject->GetClass()->GetNative() : nullptr; + return value.AsObject ? value.AsObject->GetClass() : nullptr; case VariantType::Asset: - return value.AsAsset ? value.AsAsset->GetClass()->GetNative() : nullptr; + return value.AsAsset ? value.AsAsset->GetClass() : nullptr; case VariantType::Structure: case VariantType::Enum: - return Scripting::FindClassNative(StringAnsiView(value.Type.TypeName)); + return Scripting::FindClass(StringAnsiView(value.Type.TypeName)); case VariantType::ManagedObject: - return GetClass((MonoObject*)value); + return MCore::Object::GetClass((MObject*)value); default: ; } return nullptr; } -MonoReflectionType* MUtils::GetType(MonoObject* object) +MTypeObject* MUtils::GetType(MObject* object) { - MonoClass* klass = GetClass(object); + if (!object) + return nullptr; + MClass* klass = MCore::Object::GetClass(object); return GetType(klass); } -MonoReflectionType* MUtils::GetType(MonoClass* klass) +MTypeObject* MUtils::GetType(MClass* klass) { - MonoType* monoType = mono_class_get_type(klass); - return mono_type_get_object(mono_domain_get(), monoType); + if (!klass) + return nullptr; + MType* type = klass->GetType(); + return INTERNAL_TYPE_GET_OBJECT(type); } -MonoReflectionType* MUtils::GetType(MClass* mclass) -{ - return mclass ? GetType(mclass->GetNative()) : nullptr; -} - -BytesContainer MUtils::LinkArray(MonoArray* arrayObj) +BytesContainer MUtils::LinkArray(MArray* arrayObj) { BytesContainer result; - const int32 length = arrayObj ? (int32)mono_array_length(arrayObj) : 0; + const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0; if (length != 0) { - result.Link((byte*)mono_array_addr_with_size(arrayObj, sizeof(byte), 0), length); + result.Link((byte*)MCore::Array::GetAddress(arrayObj), length); } return result; } -void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed) +void* MUtils::VariantToManagedArgPtr(Variant& value, MType* type, bool& failed) { // Convert Variant into matching managed type and return pointer to data for the method invocation - MonoTypeEnum monoType = (MonoTypeEnum)mono_type_get_type(type.GetNative()); - switch (monoType) + MTypes mType = MCore::Type::GetType(type); + switch (mType) { - case MONO_TYPE_BOOLEAN: + case MTypes::Boolean: if (value.Type.Type != VariantType::Bool) value = (bool)value; return &value.AsBool; - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_I2: + case MTypes::Char: + case MTypes::I1: + case MTypes::I2: if (value.Type.Type != VariantType::Int16) value = (int16)value; return &value.AsInt16; - case MONO_TYPE_I4: + case MTypes::I4: if (value.Type.Type != VariantType::Int) value = (int32)value; return &value.AsInt; - case MONO_TYPE_U1: - case MONO_TYPE_U2: + case MTypes::U1: + case MTypes::U2: if (value.Type.Type != VariantType::Uint16) value = (uint16)value; return &value.AsUint16; - case MONO_TYPE_U4: + case MTypes::U4: if (value.Type.Type != VariantType::Uint) value = (uint32)value; return &value.AsUint; - case MONO_TYPE_I8: + case MTypes::I8: if (value.Type.Type != VariantType::Int64) value = (int64)value; return &value.AsInt64; - case MONO_TYPE_U8: + case MTypes::U8: if (value.Type.Type != VariantType::Uint64) value = (uint64)value; return &value.AsUint64; - case MONO_TYPE_R4: + case MTypes::R4: if (value.Type.Type != VariantType::Float) value = (float)value; return &value.AsFloat; - case MONO_TYPE_R8: + case MTypes::R8: if (value.Type.Type != VariantType::Double) value = (double)value; return &value.AsDouble; - case MONO_TYPE_STRING: + case MTypes::String: return MUtils::ToString((StringView)value); - case MONO_TYPE_VALUETYPE: + case MTypes::ValueType: { -#if !USE_NETCORE - MonoClass* klass = type.GetNative()->data.klass; -#else - MonoClass* klass = mono_type_get_class(type.GetNative()); -#endif - if (mono_class_is_enum(klass)) + MClass* klass = MCore::Type::GetClass(type); + if (klass->IsEnum()) { if (value.Type.Type != VariantType::Enum) { @@ -1222,7 +1096,7 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa } const auto stdTypes = StdTypesContainer::Instance(); #define CASE_IN_BUILD_TYPE(type, access) \ - if (klass == stdTypes->type##Class->GetNative()) \ + if (klass == stdTypes->type##Class) \ { \ if (value.Type.Type != VariantType::type) \ value = Variant((type)value); \ @@ -1236,7 +1110,7 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa CASE_IN_BUILD_TYPE(Transform, AsBlob.Data); #undef CASE_IN_BUILD_TYPE #define CASE_IN_BUILD_TYPE(type, access) \ - if (klass == stdTypes->type##Class->GetNative()) \ + if (klass == stdTypes->type##Class) \ { \ if (value.Type.Type != VariantType::type) \ value = Variant((type)value); \ @@ -1250,7 +1124,7 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa CASE_IN_BUILD_TYPE(Ray, AsRay); #undef CASE_IN_BUILD_TYPE #define CASE_IN_BUILD_TYPE(type, access) \ - if (klass == type::TypeInitializer.GetMonoClass()) \ + if (klass == type::TypeInitializer.GetClass()) \ { \ if (value.Type.Type != VariantType::type) \ value = Variant((type)value); \ @@ -1263,7 +1137,7 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa CASE_IN_BUILD_TYPE(Double3, AsData); CASE_IN_BUILD_TYPE(Double4, AsBlob.Data); #undef CASE_IN_BUILD_TYPE - if (mono_class_is_valuetype(klass)) + if (klass->IsValueType()) { if (value.Type.Type == VariantType::Structure) { @@ -1271,55 +1145,54 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa if (typeHandle && value.AsBlob.Data) { auto& valueType = typeHandle.GetType(); - if (valueType.ManagedClass->GetNative() == mono_type_get_class(type.GetNative())) + if (valueType.ManagedClass == MCore::Type::GetClass(type)) { - return mono_object_unbox(valueType.Struct.Box(value.AsBlob.Data)); + return MCore::Object::Unbox(valueType.Struct.Box(value.AsBlob.Data)); } - LOG(Error, "Cannot marshal argument of type {0} as {1}", String(valueType.Fullname), type.ToString()); + LOG(Error, "Cannot marshal argument of type {0} as {1}", String(valueType.Fullname), MCore::Type::ToString(type)); } } else { - MString typeName; - GetClassFullname(klass, typeName); - const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeName); + const StringAnsiView fullname = klass->GetFullName(); + const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(fullname); if (typeHandle) { auto& valueType = typeHandle.GetType(); - value.SetType(VariantType(VariantType::Structure, typeName)); - return mono_object_unbox(valueType.Struct.Box(value.AsBlob.Data)); + value.SetType(VariantType(VariantType::Structure, fullname)); + return MCore::Object::Unbox(valueType.Struct.Box(value.AsBlob.Data)); } } } } break; - case MONO_TYPE_CLASS: + case MTypes::Class: { if (value.Type.Type == VariantType::Null) return nullptr; - MonoObject* object = BoxVariant(value); - if (object && !mono_class_is_subclass_of(mono_object_get_class(object), type.GetNative()->data.klass, false)) + MObject* object = BoxVariant(value); + if (object && !MCore::Object::GetClass(object)->IsSubClassOf(MCore::Type::GetClass(type))) object = nullptr; return object; } - case MONO_TYPE_OBJECT: + case MTypes::Object: return BoxVariant(value); - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: + case MTypes::SzArray: + case MTypes::Array: { if (value.Type.Type != VariantType::Array) return nullptr; - MonoObject* object = BoxVariant(value); - if (object && !mono_class_is_subclass_of(mono_object_get_class(object), mono_array_class_get(type.GetNative()->data.klass, 1), false)) + MObject* object = BoxVariant(value); + if (object && !MCore::Object::GetClass(object)->IsSubClassOf(MCore::Array::GetClass(MCore::Type::GetClass(type)))) object = nullptr; return object; } - case MONO_TYPE_GENERICINST: + case MTypes::GenericInst: { if (value.Type.Type == VariantType::Null) return nullptr; - MonoObject* object = BoxVariant(value); - if (object && !mono_class_is_subclass_of(mono_object_get_class(object), mono_class_from_mono_type(type.GetNative()), false)) + MObject* object = BoxVariant(value); + if (object && !MCore::Object::GetClass(object)->IsSubClassOf(MCore::Type::GetClass(type))) object = nullptr; return object; } @@ -1330,7 +1203,7 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa return nullptr; } -MonoObject* MUtils::ToManaged(const Version& value) +MObject* MUtils::ToManaged(const Version& value) { #if USE_NETCORE auto scriptingClass = Scripting::GetStaticClass(); @@ -1350,13 +1223,13 @@ MonoObject* MUtils::ToManaged(const Version& value) params[3] = &revision; auto obj = versionToManaged->Invoke(nullptr, params, nullptr); #else - auto obj = mono_object_new(mono_domain_get(), Scripting::FindClassNative("System.Version")); - Platform::MemoryCopy((byte*)obj + sizeof(MonoObject), &value, sizeof(Version)); + auto obj = MCore::Object::New(Scripting::FindClass("System.Version")); + Platform::MemoryCopy(MCore::Object::Unbox(obj), &value, sizeof(Version)); #endif return obj; } -Version MUtils::ToNative(MonoObject* value) +Version MUtils::ToNative(MObject* value) { if (value) #if USE_NETCORE @@ -1374,9 +1247,8 @@ Version MUtils::ToNative(MonoObject* value) versionToNative->Invoke(nullptr, params, nullptr); return ver; } - #else - return *(Version*)((byte*)value + sizeof(MonoObject)); + return *(Version*)MCore::Object::Unbox(value); #endif return Version(); } diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.h b/Source/Engine/Scripting/ManagedCLR/MUtils.h index 9dbb80a00..fa59973ab 100644 --- a/Source/Engine/Scripting/ManagedCLR/MUtils.h +++ b/Source/Engine/Scripting/ManagedCLR/MUtils.h @@ -3,99 +3,78 @@ #pragma once #include "MTypes.h" +#include "MCore.h" #include "Engine/Core/Types/StringView.h" #include "Engine/Core/Types/DataContainer.h" #include "Engine/Core/Types/Variant.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Scripting/ScriptingObject.h" -#if USE_MONO - -#include -#include - -#if USE_NETCORE -#include "Engine/Scripting/DotNet/CoreCLR.h" -#endif +#if USE_CSHARP struct Version; +class CultureInfo; template class BitArray; namespace MUtils { - extern FLAXENGINE_API StringView ToString(MonoString* str); - extern FLAXENGINE_API StringAnsi ToStringAnsi(MonoString* str); - extern FLAXENGINE_API void ToString(MonoString* str, String& result); - extern FLAXENGINE_API void ToString(MonoString* str, StringView& result); - extern FLAXENGINE_API void ToString(MonoString* str, Variant& result); - extern FLAXENGINE_API void ToString(MonoString* str, MString& result); + extern FLAXENGINE_API StringView ToString(MString* str); + extern FLAXENGINE_API StringAnsi ToStringAnsi(MString* str); + extern FLAXENGINE_API void ToString(MString* str, String& result); + extern FLAXENGINE_API void ToString(MString* str, StringView& result); + extern FLAXENGINE_API void ToString(MString* str, Variant& result); + extern FLAXENGINE_API void ToString(MString* str, StringAnsi& result); - extern FLAXENGINE_API MonoString* ToString(const char* str); - extern FLAXENGINE_API MonoString* ToString(const StringAnsi& str); - extern FLAXENGINE_API MonoString* ToString(const String& str); - extern FLAXENGINE_API MonoString* ToString(const String& str, MonoDomain* domain); - extern FLAXENGINE_API MonoString* ToString(const StringAnsiView& str); - extern FLAXENGINE_API MonoString* ToString(const StringView& str); - extern FLAXENGINE_API MonoString* ToString(const StringView& str, MonoDomain* domain); + extern FLAXENGINE_API MString* ToString(const char* str); + extern FLAXENGINE_API MString* ToString(const StringAnsi& str); + extern FLAXENGINE_API MString* ToString(const String& str); + extern FLAXENGINE_API MString* ToString(const String& str, MDomain* domain); + extern FLAXENGINE_API MString* ToString(const StringAnsiView& str); + extern FLAXENGINE_API MString* ToString(const StringView& str); + extern FLAXENGINE_API MString* ToString(const StringView& str, MDomain* domain); - extern FLAXENGINE_API ScriptingTypeHandle UnboxScriptingTypeHandle(MonoReflectionType* value); - extern FLAXENGINE_API MonoReflectionType* BoxScriptingTypeHandle(const ScriptingTypeHandle& value); - extern FLAXENGINE_API VariantType UnboxVariantType(MonoReflectionType* value); - extern FLAXENGINE_API VariantType UnboxVariantType(MonoType* monoType); - extern FLAXENGINE_API MonoReflectionType* BoxVariantType(const VariantType& value); - extern FLAXENGINE_API Variant UnboxVariant(MonoObject* value); - extern FLAXENGINE_API MonoObject* BoxVariant(const Variant& value); + extern FLAXENGINE_API ScriptingTypeHandle UnboxScriptingTypeHandle(MTypeObject* value); + extern FLAXENGINE_API MTypeObject* BoxScriptingTypeHandle(const ScriptingTypeHandle& value); + extern FLAXENGINE_API VariantType UnboxVariantType(MType* type); + extern FLAXENGINE_API MTypeObject* BoxVariantType(const VariantType& value); + extern FLAXENGINE_API Variant UnboxVariant(MObject* value); + extern FLAXENGINE_API MObject* BoxVariant(const Variant& value); } // Converter for data of type T between managed and unmanaged world template struct MConverter { - MonoObject* Box(const T& data, MonoClass* klass); - void Unbox(T& result, MonoObject* data); - void ToManagedArray(MonoArray* result, const Span& data); - template - void ToNativeArray(Array& result, MonoArray* data, int32 length); + MObject* Box(const T& data, const MClass* klass); + void Unbox(T& result, MObject* data); + void ToManagedArray(MArray* result, const Span& data); + void ToNativeArray(Span& result, const MArray* data); }; -#if USE_NETCORE -// Pass-through converter for ScriptingObjects (passed as GCHandles) -template<> -struct MConverter -{ - void Unbox(void*& result, MonoObject* data) - { - CHECK(data); - result = data; - } -}; -#endif - // Converter for POD types (that can use raw memory copy). template struct MConverter, TNot::Type>>>::Value>::Type> { - MonoObject* Box(const T& data, MonoClass* klass) + MObject* Box(const T& data, const MClass* klass) { - return mono_value_box(mono_domain_get(), klass, (void*)&data); + return MCore::Object::Box((void*)&data, klass); } - void Unbox(T& result, MonoObject* data) + void Unbox(T& result, MObject* data) { CHECK(data); - Platform::MemoryCopy(&result, mono_object_unbox(data), sizeof(T)); + Platform::MemoryCopy(&result, MCore::Object::Unbox(data), sizeof(T)); } - void ToManagedArray(MonoArray* result, const Span& data) + void ToManagedArray(MArray* result, const Span& data) { - Platform::MemoryCopy(mono_array_addr(result, T, 0), data.Get(), data.Length() * sizeof(T)); + Platform::MemoryCopy(MCore::Array::GetAddress(result), data.Get(), data.Length() * sizeof(T)); } - template - void ToNativeArray(Array& result, MonoArray* data, int32 length) + void ToNativeArray(Span& result, const MArray* data) { - result.Add(mono_array_addr(data, T, 0), length); + Platform::MemoryCopy(result.Get(), MCore::Array::GetAddress(data), result.Length() * sizeof(T)); } }; @@ -103,38 +82,37 @@ struct MConverter, TNot struct MConverter { - MonoObject* Box(const String& data, MonoClass* klass) + MObject* Box(const String& data, const MClass* klass) { #if USE_NETCORE - MonoString* str = MUtils::ToString(data); - return mono_value_box(nullptr, klass, str); + MString* str = MUtils::ToString(data); + return MCore::Object::Box(str, klass); #else - return (MonoObject*)MUtils::ToString(data); + return (MObject*)MUtils::ToString(data); #endif } - void Unbox(String& result, MonoObject* data) + void Unbox(String& result, MObject* data) { #if USE_NETCORE - MonoString* str = (MonoString*)mono_object_unbox(data); + MString* str = (MString*)MCore::Object::Unbox(data); result = MUtils::ToString(str); #else - result = MUtils::ToString((MonoString*)data); + result = MUtils::ToString((MString*)data); #endif } - void ToManagedArray(MonoArray* result, const Span& data) + void ToManagedArray(MArray* result, const Span& data) { for (int32 i = 0; i < data.Length(); i++) - mono_array_setref(result, i, MUtils::ToString(data[i])); + MCore::GC::WriteArrayRef(result, (MObject*)MUtils::ToString(data[i]), i); } - template - void ToNativeArray(Array& result, MonoArray* data, int32 length) + void ToNativeArray(Span& result, const MArray* data) { - result.Resize(length); - for (int32 i = 0; i < length; i++) - MUtils::ToString(mono_array_get(data, MonoString*, i), result[i]); + MString** dataPtr = MCore::Array::GetAddress(data); + for (int32 i = 0; i < result.Length(); i++) + MUtils::ToString(dataPtr[i], result[i]); } }; @@ -142,28 +120,27 @@ struct MConverter template<> struct MConverter { - MonoObject* Box(const StringAnsi& data, MonoClass* klass) + MObject* Box(const StringAnsi& data, const MClass* klass) { - return (MonoObject*)MUtils::ToString(data); + return (MObject*)MUtils::ToString(data); } - void Unbox(StringAnsi& result, MonoObject* data) + void Unbox(StringAnsi& result, MObject* data) { - result = MUtils::ToStringAnsi((MonoString*)data); + result = MUtils::ToStringAnsi((MString*)data); } - void ToManagedArray(MonoArray* result, const Span& data) + void ToManagedArray(MArray* result, const Span& data) { for (int32 i = 0; i < data.Length(); i++) - mono_array_setref(result, i, MUtils::ToString(data[i])); + MCore::GC::WriteArrayRef(result, (MObject*)MUtils::ToString(data[i]), i); } - template - void ToNativeArray(Array& result, MonoArray* data, int32 length) + void ToNativeArray(Span& result, const MArray* data) { - result.Resize(length); - for (int32 i = 0; i < length; i++) - MUtils::ToString(mono_array_get(data, MonoString*, i), result[i]); + MString** dataPtr = MCore::Array::GetAddress(data); + for (int32 i = 0; i < result.Length(); i++) + MUtils::ToString(dataPtr[i], result[i]); } }; @@ -171,28 +148,27 @@ struct MConverter template<> struct MConverter { - MonoObject* Box(const StringView& data, MonoClass* klass) + MObject* Box(const StringView& data, const MClass* klass) { - return (MonoObject*)MUtils::ToString(data); + return (MObject*)MUtils::ToString(data); } - void Unbox(StringView& result, MonoObject* data) + void Unbox(StringView& result, MObject* data) { - result = MUtils::ToString((MonoString*)data); + result = MUtils::ToString((MString*)data); } - void ToManagedArray(MonoArray* result, const Span& data) + void ToManagedArray(MArray* result, const Span& data) { for (int32 i = 0; i < data.Length(); i++) - mono_array_setref(result, i, MUtils::ToString(data[i])); + MCore::GC::WriteArrayRef(result, (MObject*)MUtils::ToString(data[i]), i); } - template - void ToNativeArray(Array& result, MonoArray* data, int32 length) + void ToNativeArray(Span& result, const MArray* data) { - result.Resize(length); - for (int32 i = 0; i < length; i++) - MUtils::ToString(mono_array_get(data, MonoString*, i), result[i]); + MString** dataPtr = MCore::Array::GetAddress(data); + for (int32 i = 0; i < result.Length(); i++) + MUtils::ToString(dataPtr[i], result[i]); } }; @@ -200,28 +176,27 @@ struct MConverter template<> struct MConverter { - MonoObject* Box(const Variant& data, MonoClass* klass) + MObject* Box(const Variant& data, const MClass* klass) { return MUtils::BoxVariant(data); } - void Unbox(Variant& result, MonoObject* data) + void Unbox(Variant& result, MObject* data) { result = MUtils::UnboxVariant(data); } - void ToManagedArray(MonoArray* result, const Span& data) + void ToManagedArray(MArray* result, const Span& data) { for (int32 i = 0; i < data.Length(); i++) - mono_array_setref(result, i, MUtils::BoxVariant(data[i])); + MCore::GC::WriteArrayRef(result, MUtils::BoxVariant(data[i]), i); } - template - void ToNativeArray(Array& result, MonoArray* data, int32 length) + void ToNativeArray(Span& result, const MArray* data) { - result.Resize(length); - for (int32 i = 0; i < length; i++) - result[i] = MUtils::UnboxVariant(mono_array_get(data, MonoObject*, i)); + MObject** dataPtr = MCore::Array::GetAddress(data); + for (int32 i = 0; i < result.Length(); i++) + result[i] = MUtils::UnboxVariant(dataPtr[i]); } }; @@ -229,31 +204,27 @@ struct MConverter template struct MConverter::Value>::Type> { - MonoObject* Box(T* data, MonoClass* klass) + MObject* Box(T* data, const MClass* klass) { return data ? data->GetOrCreateManagedInstance() : nullptr; } - void Unbox(T*& result, MonoObject* data) + void Unbox(T*& result, MObject* data) { result = (T*)ScriptingObject::ToNative(data); } - void ToManagedArray(MonoArray* result, const Span& data) + void ToManagedArray(MArray* result, const Span& data) { for (int32 i = 0; i < data.Length(); i++) - { - auto obj = data[i]; - mono_array_setref(result, i, obj ? obj->GetOrCreateManagedInstance() : nullptr); - } + MCore::GC::WriteArrayRef(result, data[i] ? data[i]->GetOrCreateManagedInstance() : nullptr, i); } - template - void ToNativeArray(Array& result, MonoArray* data, int32 length) + void ToNativeArray(Span& result, const MArray* data) { - result.Resize(length); - for (int32 i = 0; i < length; i++) - result[i] = (T*)ScriptingObject::ToNative(mono_array_get(data, MonoObject*, i)); + MObject** dataPtr = MCore::Array::GetAddress(data); + for (int32 i = 0; i < result.Length(); i++) + result[i] = (T*)ScriptingObject::ToNative(dataPtr[i]); } }; @@ -261,28 +232,15 @@ struct MConverter::Va template struct MConverter::Value>::Type> { - MonoObject* Box(const T& data, MonoClass* klass) + MObject* Box(const T& data, const MClass* klass) { return data.GetOrCreateManagedInstance(); } - void Unbox(T& result, MonoObject* data) - { - // Not Supported - CRASH; - } - - void ToManagedArray(MonoArray* result, const Span& data) + void ToManagedArray(MArray* result, const Span& data) { for (int32 i = 0; i < data.Length(); i++) - mono_array_setref(result, i, data[i].GetOrCreateManagedInstance()); - } - - template - void ToNativeArray(Array& result, MonoArray* data, int32 length) - { - // Not Supported - CRASH; + MCore::GC::WriteArrayRef(result, data[i].GetOrCreateManagedInstance(), i); } }; @@ -293,28 +251,27 @@ class ScriptingObjectReference; template struct MConverter> { - MonoObject* Box(const ScriptingObjectReference& data, MonoClass* klass) + MObject* Box(const ScriptingObjectReference& data, const MClass* klass) { return data.GetManagedInstance(); } - void Unbox(ScriptingObjectReference& result, MonoObject* data) + void Unbox(ScriptingObjectReference& result, MObject* data) { result = (T*)ScriptingObject::ToNative(data); } - void ToManagedArray(MonoArray* result, const Span>& data) + void ToManagedArray(MArray* result, const Span>& data) { for (int32 i = 0; i < data.Length(); i++) - mono_array_setref(result, i, data[i].GetManagedInstance()); + MCore::GC::WriteArrayRef(result, data[i].GetManagedInstance(), i); } - template - void ToNativeArray(Array, AllocationType>& result, MonoArray* data, int32 length) + void ToNativeArray(Span>& result, const MArray* data) { - result.Resize(length); - for (int32 i = 0; i < length; i++) - result[i] = (T*)ScriptingObject::ToNative(mono_array_get(data, MonoObject*, i)); + MObject** dataPtr = MCore::Array::GetAddress(data); + for (int32 i = 0; i < result.Length(); i++) + result[i] = (T*)ScriptingObject::ToNative(dataPtr[i]); } }; @@ -325,28 +282,27 @@ class AssetReference; template struct MConverter> { - MonoObject* Box(const AssetReference& data, MonoClass* klass) + MObject* Box(const AssetReference& data, const MClass* klass) { return data.GetManagedInstance(); } - void Unbox(AssetReference& result, MonoObject* data) + void Unbox(AssetReference& result, MObject* data) { result = (T*)ScriptingObject::ToNative(data); } - void ToManagedArray(MonoArray* result, const Span>& data) + void ToManagedArray(MArray* result, const Span>& data) { for (int32 i = 0; i < data.Length(); i++) - mono_array_setref(result, i, data[i].GetManagedInstance()); + MCore::GC::WriteArrayRef(result, data[i].GetManagedInstance(), i); } - template - void ToNativeArray(Array, AllocationType>& result, MonoArray* data, int32 length) + void ToNativeArray(Span>& result, const MArray* data) { - result.Resize(length); - for (int32 i = 0; i < length; i++) - result[i] = (T*)ScriptingObject::ToNative(mono_array_get(data, MonoObject*, i)); + MObject** dataPtr = MCore::Array::GetAddress(data); + for (int32 i = 0; i < result.Length(); i++) + result[i] = (T*)ScriptingObject::ToNative(dataPtr[i]); } }; @@ -354,102 +310,66 @@ struct MConverter> template struct MConverter> { - MonoObject* Box(const Array& data, MonoClass* klass) + MObject* Box(const Array& data, const MClass* klass) { if (!klass) return nullptr; - // TODO: use shared empty arrays cache - auto result = mono_array_new(mono_domain_get(), klass, data.Count()); + MArray* result = MCore::Array::New(klass, data.Count()); MConverter converter; converter.ToManagedArray(result, Span(data.Get(), data.Count())); - return (MonoObject*)result; + return (MObject*)result; } - void Unbox(Array& result, MonoObject* data) + void Unbox(Array& result, MObject* data) { - auto length = data ? (int32)mono_array_length((MonoArray*)data) : 0; - result.EnsureCapacity(length); + const int32 length = data ? MCore::Array::GetLength((MArray*)data) : 0; + result.Resize(length); MConverter converter; - converter.ToNativeArray(result, (MonoArray*)data, length); - } - - void ToManagedArray(MonoArray* result, const Span>& data) - { - CRASH; // Not implemented - } - - template - void ToNativeArray(Array, AllocationType>& result, MonoArray* data, int32 length) - { - CRASH; // Not implemented + Span resultSpan(result.Get(), length); + converter.ToNativeArray(resultSpan, (MArray*)data); } }; namespace MUtils { // Outputs the full typename for the type of the specified object. - extern FLAXENGINE_API void GetClassFullname(MonoObject* obj, MString& fullname); - - // Outputs the full typename for the specified type. - extern FLAXENGINE_API void GetClassFullname(MonoClass* monoClass, MString& fullname); - - // Outputs the full typename for the specified type. - extern FLAXENGINE_API void GetClassFullname(MonoReflectionType* type, MString& fullname); - - // Outputs the full typename for the type of the specified object. - inline MString GetClassFullname(MonoObject* obj) - { - MString fullname; - GetClassFullname(obj, fullname); - return fullname; - } - - // Outputs the full typename for the type of the specified object. - inline MString GetClassFullname(MonoClass* monoClass) - { - MString fullname; - GetClassFullname(monoClass, fullname); - return fullname; - } + extern FLAXENGINE_API const StringAnsi& GetClassFullname(MObject* obj); // Returns the class of the provided object. - extern FLAXENGINE_API MonoClass* GetClass(MonoObject* object); + extern FLAXENGINE_API MClass* GetClass(MObject* object); // Returns the class of the provided type. - extern FLAXENGINE_API MonoClass* GetClass(MonoReflectionType* type); + extern FLAXENGINE_API MClass* GetClass(MTypeObject* type); // Returns the class of the provided VariantType value. - extern FLAXENGINE_API MonoClass* GetClass(const VariantType& value); + extern FLAXENGINE_API MClass* GetClass(const VariantType& value); // Returns the class of the provided Variant value. - extern FLAXENGINE_API MonoClass* GetClass(const Variant& value); + extern FLAXENGINE_API MClass* GetClass(const Variant& value); // Returns the type of the provided object. - extern FLAXENGINE_API MonoReflectionType* GetType(MonoObject* object); + extern FLAXENGINE_API MTypeObject* GetType(MObject* object); // Returns the type of the provided class. - extern FLAXENGINE_API MonoReflectionType* GetType(MonoClass* klass); - - // Returns the type of the provided class. - extern FLAXENGINE_API MonoReflectionType* GetType(MClass* mclass); + extern FLAXENGINE_API MTypeObject* GetType(MClass* klass); /// - /// Boxes the native value into the MonoObject. + /// Boxes the native value into the managed object. /// /// The value. /// The value type class. template - MonoObject* Box(const T& value, MonoClass* valueClass) + MObject* Box(const T& value, const MClass* valueClass) { MConverter converter; return converter.Box(value, valueClass); } /// - /// Unboxes MonoObject to the native value of the given type. + /// Unboxes MObject to the native value of the given type. /// template - T Unbox(MonoObject* object) + T Unbox(MObject* object) { MConverter converter; T result; @@ -462,7 +382,7 @@ namespace MUtils /// /// The array object. /// The result data container with linked array data bytes (not copied). - extern FLAXENGINE_API BytesContainer LinkArray(MonoArray* arrayObj); + extern FLAXENGINE_API BytesContainer LinkArray(MArray* arrayObj); /// /// Allocates new managed array of data and copies contents from given native array. @@ -471,12 +391,11 @@ namespace MUtils /// The array values type class. /// The output array. template - MonoArray* ToArray(const Span& data, MonoClass* valueClass) + MArray* ToArray(const Span& data, const MClass* valueClass) { if (!valueClass) return nullptr; - // TODO: use shared empty arrays cache - auto result = mono_array_new(mono_domain_get(), valueClass, data.Length()); + MArray* result = MCore::Array::New(valueClass, data.Length()); MConverter converter; converter.ToManagedArray(result, data); return result; @@ -489,7 +408,7 @@ namespace MUtils /// The array values type class. /// The output array. template - FORCE_INLINE MonoArray* ToArray(const Array& data, MonoClass* valueClass) + FORCE_INLINE MArray* ToArray(const Array& data, const MClass* valueClass) { return MUtils::ToArray(Span(data.Get(), data.Count()), valueClass); } @@ -500,13 +419,14 @@ namespace MUtils /// The managed array object. /// The output array. template - Array ToArray(MonoArray* arrayObj) + Array ToArray(MArray* arrayObj) { Array result; - auto length = arrayObj ? (int32)mono_array_length(arrayObj) : 0; - result.EnsureCapacity(length); + const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0; + result.Resize(length); MConverter converter; - converter.ToNativeArray(result, arrayObj, length); + Span resultSpan(result.Get(), length); + converter.ToNativeArray(resultSpan, arrayObj); return result; } @@ -516,10 +436,10 @@ namespace MUtils /// The managed array object. /// The output array pointer and size. template - Span ToSpan(MonoArray* arrayObj) + Span ToSpan(MArray* arrayObj) { - auto ptr = (T*)(void*)mono_array_addr_with_size(arrayObj, sizeof(T), 0); - auto length = arrayObj ? (int32)mono_array_length(arrayObj) : 0; + T* ptr = (T*)MCore::Array::GetAddress(arrayObj); + const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0; return Span(ptr, length); } @@ -540,16 +460,15 @@ namespace MUtils /// The array object. /// The result data (linked not copied). template - void ToArray(MonoArray* arrayObj, DataContainer& result) + void ToArray(MArray* arrayObj, DataContainer& result) { - auto length = arrayObj ? (int32)mono_array_length(arrayObj) : 0; + const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0; if (length == 0) { result.Release(); return; } - - auto bytesRaw = (T*)(void*)mono_array_addr_with_size(arrayObj, sizeof(T), 0); + T* bytesRaw = (T*)MCore::Array::GetAddress(arrayObj); result.Link(bytesRaw, length); } @@ -558,9 +477,9 @@ namespace MUtils /// /// The input data. /// The output array. - FORCE_INLINE MonoArray* ToArray(const Span& data) + FORCE_INLINE MArray* ToArray(const Span& data) { - return ToArray(data, mono_get_byte_class()); + return ToArray(data, MCore::TypeCache::Byte); } /// @@ -568,9 +487,9 @@ namespace MUtils /// /// The input data. /// The output array. - FORCE_INLINE MonoArray* ToArray(Array& data) + FORCE_INLINE MArray* ToArray(Array& data) { - return ToArray(Span(data.Get(), data.Count()), mono_get_byte_class()); + return ToArray(Span(data.Get(), data.Count()), MCore::TypeCache::Byte); } /// @@ -578,9 +497,9 @@ namespace MUtils /// /// The input data. /// The output array. - FORCE_INLINE MonoArray* ToArray(const Span& data) + FORCE_INLINE MArray* ToArray(const Span& data) { - return ToArray(data, mono_get_string_class()); + return ToArray(data, MCore::TypeCache::String); } /// @@ -588,35 +507,35 @@ namespace MUtils /// /// The input data. /// The output array. - FORCE_INLINE MonoArray* ToArray(const Array& data) + FORCE_INLINE MArray* ToArray(const Array& data) { - return ToArray(Span(data.Get(), data.Count()), mono_get_string_class()); + return ToArray(Span(data.Get(), data.Count()), MCore::TypeCache::String); } #if USE_NETCORE /// - /// Allocates new boolean array and copies data from the given unmanaged data container. - /// The managed runtime is responsible for releasing the returned array data. + /// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data. /// /// The input data. /// The output array. FORCE_INLINE bool* ToBoolArray(const Array& data) { - bool* arr = (bool*)CoreCLR::Allocate(data.Count() * sizeof(bool)); + // System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer + bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true); memcpy(arr, data.Get(), data.Count() * sizeof(bool)); return arr; } /// - /// Allocates new boolean array and copies data from the given unmanaged data container. - /// The managed runtime is responsible for releasing the returned array data. + /// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data. /// /// The input data. /// The output array. template FORCE_INLINE bool* ToBoolArray(const BitArray& data) { - bool* arr = (bool*)CoreCLR::Allocate(data.Count() * sizeof(bool)); + // System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer + bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true); for (int i = 0; i < data.Count(); i++) arr[i] = data[i]; return arr; @@ -634,45 +553,10 @@ namespace MUtils } #endif - FORCE_INLINE MGCHandle NewGCHandle(MonoObject* obj, bool pinned) - { -#if USE_NETCORE - return CoreCLR::NewGCHandle(obj, pinned); -#else - return mono_gchandle_new(obj, pinned); -#endif - } + extern void* VariantToManagedArgPtr(Variant& value, MType* type, bool& failed); - FORCE_INLINE MGCHandle NewGCHandleWeakref(MonoObject* obj, bool track_resurrection) - { -#if USE_NETCORE - return CoreCLR::NewGCHandleWeakref(obj, track_resurrection); -#else - return mono_gchandle_new_weakref(obj, track_resurrection); -#endif - } - - FORCE_INLINE MonoObject* GetGCHandleTarget(const MGCHandle& handle) - { -#if USE_NETCORE - return (MonoObject*)CoreCLR::GetGCHandleTarget(handle); -#else - return mono_gchandle_get_target(handle); -#endif - } - - FORCE_INLINE void FreeGCHandle(const MGCHandle& handle) - { -#if USE_NETCORE - CoreCLR::FreeGCHandle(handle); -#else - mono_gchandle_free(handle); -#endif - } - - extern void* VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed); - extern MonoObject* ToManaged(const Version& value); - extern Version ToNative(MonoObject* value); + extern MObject* ToManaged(const Version& value); + extern Version ToNative(MObject* value); }; #endif diff --git a/Source/Engine/Scripting/Plugins/PluginManager.cpp b/Source/Engine/Scripting/Plugins/PluginManager.cpp index 4d205d6d6..35ca3550d 100644 --- a/Source/Engine/Scripting/Plugins/PluginManager.cpp +++ b/Source/Engine/Scripting/Plugins/PluginManager.cpp @@ -30,7 +30,7 @@ GamePlugin::GamePlugin(const SpawnParams& params) #if USE_EDITOR #include "EditorPlugin.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" EditorPlugin::EditorPlugin(const SpawnParams& params) diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp new file mode 100644 index 000000000..271b69137 --- /dev/null +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -0,0 +1,1827 @@ +// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. + +#include "Engine/Scripting/Types.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" + +#if USE_NETCORE + +#pragma warning(default : 4297) + +#include "Engine/Core/Log.h" +#include "Engine/Core/Types/DateTime.h" +#include "Engine/Core/Types/TimeSpan.h" +#include "Engine/Core/Collections/Dictionary.h" +#include "Engine/Platform/Platform.h" +#include "Engine/Platform/File.h" +#include "Engine/Platform/FileSystem.h" +#include "Engine/Scripting/ManagedCLR/MAssembly.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MDomain.h" +#include "Engine/Scripting/ManagedCLR/MEvent.h" +#include "Engine/Scripting/ManagedCLR/MField.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" +#include "Engine/Scripting/ManagedCLR/MProperty.h" +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/ManagedCLR/MUtils.h" +#include "Engine/Scripting/Scripting.h" +#include "Engine/Engine/Globals.h" +#include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Threading/Threading.h" +#include "Engine/Debug/Exceptions/CLRInnerException.h" +#if DOTNET_HOST_CORECRL +#include +#include +#include +#elif DOTNET_HOST_MONO +#include +#include +#include +typedef char char_t; +#else +#error "Unknown .NET runtime host." +#endif +#if PLATFORM_WINDOWS +#include +#undef SetEnvironmentVariable +#undef LoadLibrary +#undef LoadImage +#endif + +#if defined(_WIN32) +#define CORECLR_DELEGATE_CALLTYPE __stdcall +#define FLAX_CORECLR_STRING String +#define FLAX_CORECLR_TEXT(x) TEXT(x) +#else +#define CORECLR_DELEGATE_CALLTYPE +#define FLAX_CORECLR_STRING StringAnsi +#define FLAX_CORECLR_TEXT(x) x +#endif + +// System.Reflection.TypeAttributes +enum class MTypeAttributes : uint32 +{ + VisibilityMask = 0x00000007, + NotPublic = 0x00000000, + Public = 0x00000001, + NestedPublic = 0x00000002, + NestedPrivate = 0x00000003, + NestedFamily = 0x00000004, + NestedAssembly = 0x00000005, + NestedFamANDAssem = 0x00000006, + NestedFamORAssem = 0x00000007, + LayoutMask = 0x00000018, + AutoLayout = 0x00000000, + SequentialLayout = 0x00000008, + ExplicitLayout = 0x00000010, + ClassSemanticsMask = 0x00000020, + Class = 0x00000000, + Interface = 0x00000020, + Abstract = 0x00000080, + Sealed = 0x00000100, + SpecialName = 0x00000400, + Import = 0x00001000, + Serializable = 0x00002000, + WindowsRuntime = 0x00004000, + StringFormatMask = 0x00030000, + AnsiClass = 0x00000000, + UnicodeClass = 0x00010000, + AutoClass = 0x00020000, + CustomFormatClass = 0x00030000, + CustomFormatMask = 0x00C00000, + BeforeFieldInit = 0x00100000, + RTSpecialName = 0x00000800, + HasSecurity = 0x00040000, + ReservedMask = 0x00040800, +}; + +// System.Reflection.MethodAttributes +enum class MMethodAttributes : uint32 +{ + MemberAccessMask = 0x0007, + PrivateScope = 0x0000, + Private = 0x0001, + FamANDAssem = 0x0002, + Assembly = 0x0003, + Family = 0x0004, + FamORAssem = 0x0005, + Public = 0x0006, + Static = 0x0010, + Final = 0x0020, + Virtual = 0x0040, + HideBySig = 0x0080, + CheckAccessOnOverride = 0x0200, + VtableLayoutMask = 0x0100, + ReuseSlot = 0x0000, + NewSlot = 0x0100, + Abstract = 0x0400, + SpecialName = 0x0800, + PinvokeImpl = 0x2000, + UnmanagedExport = 0x0008, + RTSpecialName = 0x1000, + HasSecurity = 0x4000, + RequireSecObject = 0x8000, + ReservedMask = 0xd000, +}; + +// System.Reflection.FieldAttributes +enum class MFieldAttributes : uint32 +{ + FieldAccessMask = 0x0007, + PrivateScope = 0x0000, + Private = 0x0001, + FamANDAssem = 0x0002, + Assembly = 0x0003, + Family = 0x0004, + FamORAssem = 0x0005, + Public = 0x0006, + Static = 0x0010, + InitOnly = 0x0020, + Literal = 0x0040, + NotSerialized = 0x0080, + SpecialName = 0x0200, + PinvokeImpl = 0x2000, + RTSpecialName = 0x0400, + HasFieldMarshal = 0x1000, + HasDefault = 0x8000, + HasFieldRVA = 0x0100, + ReservedMask = 0x9500, +}; + +DECLARE_ENUM_OPERATORS(MTypeAttributes); +DECLARE_ENUM_OPERATORS(MMethodAttributes); +DECLARE_ENUM_OPERATORS(MFieldAttributes); + +extern MDomain* MRootDomain; +extern MDomain* MActiveDomain; +extern Array> MDomains; + +Dictionary CachedFunctions; +const char_t* NativeInteropTypeName = FLAX_CORECLR_TEXT("FlaxEngine.NativeInterop, FlaxEngine.CSharp"); + +Dictionary classHandles; +Dictionary assemblyHandles; + +/// +/// Returns the function pointer to the managed static method in NativeInterop class. +/// +void* GetStaticMethodPointer(const String& methodName); + +/// +/// Calls the managed static method in NativeInterop class with given parameters. +/// +template +inline RetType CallStaticMethodByName(const String& methodName, Args... args) +{ + typedef RetType (CORECLR_DELEGATE_CALLTYPE* fun)(Args...); + return ((fun)GetStaticMethodPointer(methodName))(args...); +} + +/// +/// Calls the managed static method with given parameters. +/// +template +inline RetType CallStaticMethod(void* methodPtr, Args... args) +{ + typedef RetType (CORECLR_DELEGATE_CALLTYPE* fun)(Args...); + return ((fun)methodPtr)(args...); +} + +void RegisterNativeLibrary(const char* moduleName, const char* modulePath) +{ + static void* RegisterNativeLibraryPtr = GetStaticMethodPointer(TEXT("RegisterNativeLibrary")); + CallStaticMethod(RegisterNativeLibraryPtr, moduleName, modulePath); +} + +bool InitHostfxr(const String& configPath, const String& libraryPath); +void ShutdownHostfxr(); + +MAssembly* GetAssembly(void* assemblyHandle); +MClass* GetClass(void* typeHandle); +MClass* GetOrCreateClass(void* typeHandle); + +bool HasCustomAttribute(const MClass* klass, const MClass* attributeClass); +bool HasCustomAttribute(const MClass* klass); +void* GetCustomAttribute(const MClass* klass, const MClass* attributeClass); + +// Structures used to pass information from runtime, must match with the structures in managed side +struct NativeClassDefinitions +{ + void* typeHandle; + const char* name; + const char* fullname; + const char* namespace_; + MTypeAttributes typeAttributes; +}; + +struct NativeMethodDefinitions +{ + const char* name; + int numParameters; + void* handle; + MMethodAttributes methodAttributes; +}; + +struct NativeFieldDefinitions +{ + const char* name; + void* fieldHandle; + void* fieldType; + MFieldAttributes fieldAttributes; +}; + +struct NativePropertyDefinitions +{ + const char* name; + void* getterHandle; + void* setterHandle; + MMethodAttributes getterAttributes; + MMethodAttributes setterAttributes; +}; + +struct NativeString +{ + int32 length; + Char chars[1]; +}; + +MDomain* MCore::CreateDomain(const StringAnsi& domainName) +{ + return nullptr; +} + +void MCore::UnloadDomain(const StringAnsi& domainName) +{ +} + +bool MCore::LoadEngine() +{ + PROFILE_CPU(); + const ::String csharpLibraryPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll"); + const ::String csharpRuntimeConfigPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.runtimeconfig.json"); + if (!FileSystem::FileExists(csharpLibraryPath)) + LOG(Fatal, "Failed to initialize managed runtime, FlaxEngine.CSharp.dll is missing."); + if (!FileSystem::FileExists(csharpRuntimeConfigPath)) + LOG(Fatal, "Failed to initialize managed runtime, FlaxEngine.CSharp.runtimeconfig.json is missing."); + + // Initialize hostfxr + if (InitHostfxr(csharpRuntimeConfigPath, csharpLibraryPath)) + return true; + + // Prepare managed side + CallStaticMethodByName(TEXT("Init")); +#ifdef MCORE_MAIN_MODULE_NAME + // MCORE_MAIN_MODULE_NAME define is injected by Scripting.Build.cs on platforms that use separate shared library for engine symbols + const StringAnsi flaxLibraryPath(Platform::GetMainDirectory() / TEXT(MACRO_TO_STR(MCORE_MAIN_MODULE_NAME))); +#else + const StringAnsi flaxLibraryPath(Platform::GetExecutableFilePath()); +#endif + RegisterNativeLibrary("FlaxEngine", flaxLibraryPath.Get()); + + MRootDomain = New("Root"); + MDomains.Add(MRootDomain); + + char* buildInfo = CallStaticMethodByName(TEXT("GetRuntimeInformation")); + LOG(Info, ".NET runtime version: {0}", ::String(buildInfo)); + MCore::GC::FreeMemory(buildInfo); + + return false; +} + +void MCore::UnloadEngine() +{ + if (!MRootDomain) + return; + PROFILE_CPU(); + CallStaticMethodByName(TEXT("Exit")); + MDomains.ClearDelete(); + MRootDomain = nullptr; + ShutdownHostfxr(); +} + +MObject* MCore::Object::Box(void* value, const MClass* klass) +{ + static void* BoxValuePtr = GetStaticMethodPointer(TEXT("BoxValue")); + return (MObject*)CallStaticMethod(BoxValuePtr, klass->_handle, value); +} + +void* MCore::Object::Unbox(MObject* obj) +{ + static void* UnboxValuePtr = GetStaticMethodPointer(TEXT("UnboxValue")); + return CallStaticMethod(UnboxValuePtr, obj); +} + +MObject* MCore::Object::New(const MClass* klass) +{ + static void* NewObjectPtr = GetStaticMethodPointer(TEXT("NewObject")); + return (MObject*)CallStaticMethod(NewObjectPtr, klass->_handle); +} + +void MCore::Object::Init(MObject* obj) +{ + static void* ObjectInitPtr = GetStaticMethodPointer(TEXT("ObjectInit")); + CallStaticMethod(ObjectInitPtr, obj); +} + +MClass* MCore::Object::GetClass(MObject* obj) +{ + static void* GetObjectTypePtr = GetStaticMethodPointer(TEXT("GetObjectType")); + void* classHandle = CallStaticMethod(GetObjectTypePtr, obj); + return GetOrCreateClass((void*)classHandle); +} + +MString* MCore::Object::ToString(MObject* obj) +{ + MISSING_CODE("TODO: MCore::Object::ToString"); // TODO: MCore::Object::ToString + return nullptr; +} + +int32 MCore::Object::GetHashCode(MObject* obj) +{ + MISSING_CODE("TODO: MCore::Object::GetHashCode"); // TODO: MCore::Object::GetHashCode + return 0; +} + +MString* MCore::String::GetEmpty(MDomain* domain) +{ + static void* GetStringEmptyPtr = GetStaticMethodPointer(TEXT("GetStringEmpty")); + return (MString*)CallStaticMethod(GetStringEmptyPtr); +} + +MString* MCore::String::New(const char* str, int32 length, MDomain* domain) +{ + static void* NewStringLengthPtr = GetStaticMethodPointer(TEXT("NewStringLength")); + return (MString*)CallStaticMethod(NewStringLengthPtr, str, length); +} + +MString* MCore::String::New(const Char* str, int32 length, MDomain* domain) +{ + static void* NewStringUTF16Ptr = GetStaticMethodPointer(TEXT("NewStringUTF16")); + return (MString*)CallStaticMethod(NewStringUTF16Ptr, str, length); +} + +StringView MCore::String::GetChars(MString* obj) +{ + static void* GetStringPointerPtr = GetStaticMethodPointer(TEXT("GetStringPointer")); + NativeString* str = (NativeString*)CallStaticMethod(GetStringPointerPtr, obj); + return StringView(str->chars, str->length); +} + +MArray* MCore::Array::New(const MClass* elementKlass, int32 length) +{ + static void* NewArrayPtr = GetStaticMethodPointer(TEXT("NewArray")); + return (MArray*)CallStaticMethod(NewArrayPtr, elementKlass->_handle, length); +} + +MClass* MCore::Array::GetClass(MClass* elementKlass) +{ + MISSING_CODE("TODO: MCore::Array::GetClass"); // TODO: MCore::Object::GetClass + return nullptr; +} + +int32 MCore::Array::GetLength(const MArray* obj) +{ + static void* GetArrayLengthPtr = GetStaticMethodPointer(TEXT("GetArrayLength")); + return CallStaticMethod(GetArrayLengthPtr, (void*)obj); +} + +void* MCore::Array::GetAddress(const MArray* obj) +{ + static void* GetArrayPointerPtr = GetStaticMethodPointer(TEXT("GetArrayPointer")); + return CallStaticMethod(GetArrayPointerPtr, (void*)obj); +} + +MGCHandle MCore::GCHandle::New(MObject* obj, bool pinned) +{ + static void* NewGCHandlePtr = GetStaticMethodPointer(TEXT("NewGCHandle")); + return (MGCHandle)CallStaticMethod(NewGCHandlePtr, obj, pinned); +} + +MGCHandle MCore::GCHandle::NewWeak(MObject* obj, bool trackResurrection) +{ + static void* NewGCHandleWeakPtr = GetStaticMethodPointer(TEXT("NewGCHandleWeak")); + return (MGCHandle)CallStaticMethod(NewGCHandleWeakPtr, obj, trackResurrection); +} + +MObject* MCore::GCHandle::GetTarget(const MGCHandle& handle) +{ + return (MObject*)(void*)handle; +} + +void MCore::GCHandle::Free(const MGCHandle& handle) +{ + static void* FreeGCHandlePtr = GetStaticMethodPointer(TEXT("FreeGCHandle")); + CallStaticMethod(FreeGCHandlePtr, (void*)handle); +} + +void MCore::GC::Collect() +{ + PROFILE_CPU(); + // TODO: call System.GC.Collect() +} + +void MCore::GC::Collect(int32 generation) +{ + PROFILE_CPU(); + // TODO: call System.GC.Collect(int32) +} + +void MCore::GC::WaitForPendingFinalizers() +{ + PROFILE_CPU(); + // TODO: call System.GC.WaitForPendingFinalizers() +} + +void MCore::GC::WriteRef(void* ptr, MObject* ref) +{ + *(void**)ptr = ref; +} + +void MCore::GC::WriteValue(void* dst, void* src, int32 count, const MClass* klass) +{ + const int32 size = klass->GetInstanceSize(); + memcpy(dst, src, count * size); +} + +void MCore::GC::WriteArrayRef(MArray* dst, MObject* ref, int32 index) +{ + static void* SetArrayValueReferencePtr = GetStaticMethodPointer(TEXT("SetArrayValueReference")); + CallStaticMethod(SetArrayValueReferencePtr, dst, ref, index); +} + +void* MCore::GC::AllocateMemory(int32 size, bool coTaskMem) +{ + static void* AllocMemoryPtr = GetStaticMethodPointer(TEXT("AllocMemory")); + return CallStaticMethod(AllocMemoryPtr, size, coTaskMem); +} + +void MCore::GC::FreeMemory(void* ptr, bool coTaskMem) +{ + if (!ptr) + return; + static void* FreeMemoryPtr = GetStaticMethodPointer(TEXT("FreeMemory")); + CallStaticMethod(FreeMemoryPtr, ptr, coTaskMem); +} + +void MCore::Thread::Attach() +{ +} + +void MCore::Thread::Exit() +{ +} + +bool MCore::Thread::IsAttached() +{ + return true; +} + +void MCore::Exception::Throw(MObject* exception) +{ + static void* RaiseExceptionPtr = GetStaticMethodPointer(TEXT("RaiseException")); + CallStaticMethod(RaiseExceptionPtr, exception); +} + +MObject* MCore::Exception::GetNullReference() +{ + static void* GetNullReferenceExceptionPtr = GetStaticMethodPointer(TEXT("GetNullReferenceException")); + return (MObject*)CallStaticMethod(GetNullReferenceExceptionPtr); +} + +MObject* MCore::Exception::Get(const char* msg) +{ + return nullptr; // TODO: implement generic exception with custom message +} + +MObject* MCore::Exception::GetArgument(const char* arg, const char* msg) +{ + static void* GetArgumentExceptionPtr = GetStaticMethodPointer(TEXT("GetArgumentException")); + return (MObject*)CallStaticMethod(GetArgumentExceptionPtr); +} + +MObject* MCore::Exception::GetArgumentNull(const char* arg) +{ + static void* GetArgumentNullExceptionPtr = GetStaticMethodPointer(TEXT("GetArgumentNullException")); + return (MObject*)CallStaticMethod(GetArgumentNullExceptionPtr); +} + +MObject* MCore::Exception::GetArgumentOutOfRange(const char* arg) +{ + static void* GetArgumentOutOfRangeExceptionPtr = GetStaticMethodPointer(TEXT("GetArgumentOutOfRangeException")); + return (MObject*)CallStaticMethod(GetArgumentOutOfRangeExceptionPtr); +} + +MObject* MCore::Exception::GetNotSupported(const char* msg) +{ + static void* GetNotSupportedExceptionPtr = GetStaticMethodPointer(TEXT("GetNotSupportedException")); + return (MObject*)CallStaticMethod(GetNotSupportedExceptionPtr); +} + +::String MCore::Type::ToString(MType* type) +{ + MClass* klass = GetOrCreateClass(type); + return ::String(klass->GetFullName()); +} + +MClass* MCore::Type::GetClass(MType* type) +{ + return GetOrCreateClass(type); +} + +int32 MCore::Type::GetSize(MType* type) +{ + return GetOrCreateClass(type)->GetInstanceSize(); +} + +MTypes MCore::Type::GetType(MType* type) +{ + MClass* klass = GetOrCreateClass((void*)type); + if (klass->_types == 0) + { + static void* GetTypeMTypesEnumPtr = GetStaticMethodPointer(TEXT("GetTypeMTypesEnum")); + klass->_types = CallStaticMethod(GetTypeMTypesEnumPtr, klass->_handle); + } + return (MTypes)klass->_types; +} + +bool MCore::Type::IsPointer(MType* type) +{ + MISSING_CODE("TODO: MCore::Type::IsPointer"); // TODO: MCore::Type::IsPointer + return false; +} + +bool MCore::Type::IsReference(MType* type) +{ + MISSING_CODE("TODO: MCore::Type::IsReference"); // TODO: MCore::Type::IsReference + return false; +} + +const MAssembly::ClassesDictionary& MAssembly::GetClasses() const +{ + if (_hasCachedClasses || !IsLoaded()) + return _classes; + PROFILE_CPU(); + const auto startTime = DateTime::NowUTC(); + +#if TRACY_ENABLE + ZoneText(*_name, _name.Length()); +#endif + ScopeLock lock(_locker); + if (_hasCachedClasses) + return _classes; + ASSERT(_classes.IsEmpty()); + + NativeClassDefinitions* managedClasses; + int classCount; + static void* GetManagedClassesPtr = GetStaticMethodPointer(TEXT("GetManagedClasses")); + CallStaticMethod(GetManagedClassesPtr, _handle, &managedClasses, &classCount); + _classes.EnsureCapacity(classCount); + for (int32 i = 0; i < classCount; i++) + { + NativeClassDefinitions& managedClass = managedClasses[i]; + + // Create class object + MClass* klass = New(this, managedClass.typeHandle, managedClass.name, managedClass.fullname, managedClass.namespace_, managedClass.typeAttributes); + _classes.Add(klass->GetFullName(), klass); + + MCore::GC::FreeMemory((void*)managedClasses[i].name); + MCore::GC::FreeMemory((void*)managedClasses[i].fullname); + MCore::GC::FreeMemory((void*)managedClasses[i].namespace_); + } + MCore::GC::FreeMemory(managedClasses); + + const auto endTime = DateTime::NowUTC(); + LOG(Info, "Caching classes for assembly {0} took {1}ms", String(_name), (int32)(endTime - startTime).GetTotalMilliseconds()); + +#if 0 + for (auto i = _classes.Begin(); i.IsNotEnd(); ++i) + LOG(Info, "Class: {0}", String(i->Value->GetFullName())); +#endif + + _hasCachedClasses = true; + return _classes; +} + +bool MAssembly::LoadCorlib() +{ + if (IsLoaded()) + return false; + PROFILE_CPU(); +#if TRACY_ENABLE + const StringAnsiView name("Corlib"); + ZoneText(*name, name.Length()); +#endif + + // Ensure to be unloaded + Unload(); + + // Start + const auto startTime = DateTime::NowUTC(); + OnLoading(); + + // Load + { + const char* name; + const char* fullname; + static void* GetAssemblyByNamePtr = GetStaticMethodPointer(TEXT("GetAssemblyByName")); + _handle = CallStaticMethod(GetAssemblyByNamePtr, "System.Private.CoreLib", &name, &fullname); + _name = name; + _fullname = fullname; + MCore::GC::FreeMemory((void*)name); + MCore::GC::FreeMemory((void*)fullname); + } + if (_handle == nullptr) + { + OnLoadFailed(); + return true; + } + _hasCachedClasses = false; + assemblyHandles.Add(_handle, this); + + // End + OnLoaded(startTime); + return false; +} + +bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePath) +{ + // Load assembly file data + Array data; + File::ReadAllBytes(assemblyPath, data); + + // Open .Net assembly + const StringAnsi assemblyPathAnsi = assemblyPath.ToStringAnsi(); + const char* name; + const char* fullname; + static void* LoadAssemblyImagePtr = GetStaticMethodPointer(TEXT("LoadAssemblyImage")); + _handle = CallStaticMethod(LoadAssemblyImagePtr, (char*)data.Get(), data.Count(), assemblyPathAnsi.Get(), &name, &fullname); + _name = name; + _fullname = fullname; + MCore::GC::FreeMemory((void*)name); + MCore::GC::FreeMemory((void*)fullname); + if (_handle == nullptr) + { + Log::CLRInnerException(TEXT(".NET assembly image is invalid at ") + assemblyPath); + return true; + } + assemblyHandles.Add(_handle, this); + + // Provide new path of hot-reloaded native library path for managed DllImport + if (nativePath.HasChars()) + { + RegisterNativeLibrary(assemblyPathAnsi.Get(), StringAnsi(nativePath).Get()); + } + + _hasCachedClasses = false; + _assemblyPath = assemblyPath; + return false; +} + +bool MAssembly::UnloadImage(bool isReloading) +{ + if (_handle) + { + // TODO: closing assembly on reload only is copy-paste from mono, do we need do this on .NET too? + if (isReloading) + { + LOG(Info, "Unloading managed assembly \'{0}\' (is reloading)", String(_name)); + + static void* CloseAssemblyPtr = GetStaticMethodPointer(TEXT("CloseAssembly")); + CallStaticMethod(CloseAssemblyPtr, _handle); + } + + assemblyHandles.Remove(_handle); + _handle = nullptr; + } + return false; +} + +MClass::MClass(const MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes attributes) + : _handle(handle) + , _name(name) + , _namespace_(namespace_) + , _assembly(parentAssembly) + , _fullname(fullname) + , _hasCachedProperties(false) + , _hasCachedFields(false) + , _hasCachedMethods(false) + , _hasCachedAttributes(false) + , _hasCachedEvents(false) + , _hasCachedInterfaces(false) +{ + ASSERT(handle != nullptr); + switch (attributes & MTypeAttributes::VisibilityMask) + { + case MTypeAttributes::NotPublic: + case MTypeAttributes::NestedPrivate: + _visibility = MVisibility::Private; + break; + case MTypeAttributes::Public: + case MTypeAttributes::NestedPublic: + _visibility = MVisibility::Public; + break; + case MTypeAttributes::NestedFamily: + case MTypeAttributes::NestedAssembly: + _visibility = MVisibility::Internal; + break; + case MTypeAttributes::NestedFamORAssem: + _visibility = MVisibility::ProtectedInternal; + break; + case MTypeAttributes::NestedFamANDAssem: + _visibility = MVisibility::PrivateProtected; + break; + default: + CRASH; + } + + const MTypeAttributes staticClassFlags = MTypeAttributes::Abstract | MTypeAttributes::Sealed; + _isStatic = (attributes & staticClassFlags) == staticClassFlags; + _isSealed = !_isStatic && (attributes & MTypeAttributes::Sealed) == MTypeAttributes::Sealed; + _isAbstract = !_isStatic && (attributes & MTypeAttributes::Abstract) == MTypeAttributes::Abstract; + _isInterface = (attributes & MTypeAttributes::ClassSemanticsMask) == MTypeAttributes::Interface; + + // TODO: pass type info from C# side at once (pack into flags) + + static void* TypeIsValueTypePtr = GetStaticMethodPointer(TEXT("TypeIsValueType")); + _isValueType = CallStaticMethod(TypeIsValueTypePtr, handle); + + static void* TypeIsEnumPtr = GetStaticMethodPointer(TEXT("TypeIsEnum")); + _isEnum = CallStaticMethod(TypeIsEnumPtr, handle); + + classHandles.Add(handle, this); +} + +MClass::~MClass() +{ + _methods.ClearDelete(); + _fields.ClearDelete(); + _properties.ClearDelete(); + _events.ClearDelete(); + + classHandles.Remove(_handle); +} + +StringAnsiView MClass::GetName() const +{ + return _name; +} + +StringAnsiView MClass::GetNamespace() const +{ + return _namespace_; +} + +MType* MClass::GetType() const +{ + return (MType*)_handle; +} + +MClass* MClass::GetBaseClass() const +{ + static void* GetClassParentPtr = GetStaticMethodPointer(TEXT("GetClassParent")); + void* parentHandle = CallStaticMethod(GetClassParentPtr, _handle); + return GetOrCreateClass(parentHandle); +} + +bool MClass::IsSubClassOf(const MClass* klass, bool checkInterfaces) const +{ + static void* TypeIsSubclassOfPtr = GetStaticMethodPointer(TEXT("TypeIsSubclassOf")); + return klass && CallStaticMethod(TypeIsSubclassOfPtr, _handle, klass->_handle, checkInterfaces); +} + +bool MClass::HasInterface(const MClass* klass) const +{ + static void* TypeIsAssignableFrom = GetStaticMethodPointer(TEXT("TypeIsAssignableFrom")); + return klass && CallStaticMethod(TypeIsAssignableFrom, _handle, klass->_handle); +} + +bool MClass::IsInstanceOfType(MObject* object) const +{ + if (object == nullptr) + return false; + MClass* objectClass = MCore::Object::GetClass(object); + return IsSubClassOf(objectClass, false); +} + +uint32 MClass::GetInstanceSize() const +{ + if (_size != 0) + return _size; + uint32 align; + static void* NativeSizeOfPtr = GetStaticMethodPointer(TEXT("NativeSizeOf")); + _size = CallStaticMethod(NativeSizeOfPtr, _handle, &align); + return _size; +} + +MClass* MClass::GetElementClass() const +{ + static void* GetElementClassPtr = GetStaticMethodPointer(TEXT("GetElementClass")); + void* elementType = CallStaticMethod(GetElementClassPtr, _handle); + return GetOrCreateClass(elementType); +} + +MMethod* MClass::GetMethod(const char* name, int32 numParams) const +{ + GetMethods(); + for (int32 i = 0; i < _methods.Count(); i++) + { + if (_methods[i]->GetName() == name && _methods[i]->GetParametersCount() == numParams) + return _methods[i]; + } + return nullptr; +} + +const Array& MClass::GetMethods() const +{ + if (_hasCachedMethods) + return _methods; + + NativeMethodDefinitions* methods; + int methodsCount; + static void* GetClassMethodsPtr = GetStaticMethodPointer(TEXT("GetClassMethods")); + CallStaticMethod(GetClassMethodsPtr, _handle, &methods, &methodsCount); + for (int32 i = 0; i < methodsCount; i++) + { + NativeMethodDefinitions& definition = methods[i]; + MMethod* method = New(const_cast(this), StringAnsi(definition.name), definition.handle, definition.numParameters, definition.methodAttributes); + _methods.Add(method); + + MCore::GC::FreeMemory((void*)definition.name); + } + MCore::GC::FreeMemory(methods); + + _hasCachedMethods = true; + return _methods; +} + +MField* MClass::GetField(const char* name) const +{ + GetFields(); + for (int32 i = 0; i < _fields.Count(); i++) + { + if (_fields[i]->GetName() == name) + return _fields[i]; + } + return nullptr; +} + +const Array& MClass::GetFields() const +{ + if (_hasCachedFields) + return _fields; + + NativeFieldDefinitions* fields; + int numFields; + static void* GetClassFieldsPtr = GetStaticMethodPointer(TEXT("GetClassFields")); + CallStaticMethod(GetClassFieldsPtr, _handle, &fields, &numFields); + for (int32 i = 0; i < numFields; i++) + { + NativeFieldDefinitions& definition = fields[i]; + MField* field = New(const_cast(this), definition.fieldHandle, definition.name, definition.fieldType, definition.fieldAttributes); + _fields.Add(field); + + MCore::GC::FreeMemory((void*)definition.name); + } + MCore::GC::FreeMemory(fields); + + _hasCachedFields = true; + return _fields; +} + +const Array& MClass::GetEvents() const +{ + if (_hasCachedEvents) + return _events; + + // TODO: implement MEvent in .NET + + _hasCachedEvents = true; + return _events; +} + +MProperty* MClass::GetProperty(const char* name) const +{ + GetProperties(); + for (int32 i = 0; i < _properties.Count(); i++) + { + if (_properties[i]->GetName() == name) + return _properties[i]; + } + return nullptr; +} + +const Array& MClass::GetProperties() const +{ + if (_hasCachedProperties) + return _properties; + + NativePropertyDefinitions* foundProperties; + int numProperties; + static void* GetClassPropertiesPtr = GetStaticMethodPointer(TEXT("GetClassProperties")); + CallStaticMethod(GetClassPropertiesPtr, _handle, &foundProperties, &numProperties); + for (int i = 0; i < numProperties; i++) + { + const NativePropertyDefinitions& definition = foundProperties[i]; + MProperty* property = New(const_cast(this), definition.name, definition.getterHandle, definition.setterHandle, definition.getterAttributes, definition.setterAttributes); + _properties.Add(property); + + MCore::GC::FreeMemory((void*)definition.name); + } + MCore::GC::FreeMemory(foundProperties); + + _hasCachedProperties = true; + return _properties; +} + +const Array& MClass::GetInterfaces() const +{ + if (_hasCachedInterfaces) + return _interfaces; + + void** foundInterfaces; + int numInterfaces; + static void* GetClassInterfacesPtr = GetStaticMethodPointer(TEXT("GetClassInterfaces")); + CallStaticMethod(GetClassInterfacesPtr, _handle, &foundInterfaces, &numInterfaces); + for (int32 i = 0; i < numInterfaces; i++) + { + MClass* interfaceClass = GetOrCreateClass(foundInterfaces[i]); + _interfaces.Add(interfaceClass); + } + MCore::GC::FreeMemory(foundInterfaces); + + _hasCachedInterfaces = true; + return _interfaces; +} + +bool MClass::HasAttribute(const MClass* monoClass) const +{ + return HasCustomAttribute(this, monoClass); +} + +bool MClass::HasAttribute() const +{ + return HasCustomAttribute(this); +} + +MObject* MClass::GetAttribute(const MClass* monoClass) const +{ + return (MObject*)GetCustomAttribute(this, monoClass); +} + +const Array& MClass::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + + MObject** attributes; + int numAttributes; + static void* GetClassAttributesPtr = GetStaticMethodPointer(TEXT("GetClassAttributes")); + CallStaticMethod(GetClassAttributesPtr, _handle, &attributes, &numAttributes); + _attributes.Resize(numAttributes); + for (int i = 0; i < numAttributes; i++) + { + _attributes.Add(attributes[i]); + } + MCore::GC::FreeMemory(attributes); + + _hasCachedAttributes = true; + return _attributes; +} + +bool MDomain::SetCurrentDomain(bool force) +{ + MActiveDomain = this; + return true; +} + +void MDomain::Dispatch() const +{ +} + +MEvent::MEvent(MClass* parentClass, void* handle, const char* name) + : _handle(handle) + , _addMethod(nullptr) + , _removeMethod(nullptr) + , _parentClass(parentClass) + , _name(name) + , _hasCachedAttributes(false) + , _hasAddMonoMethod(true) + , _hasRemoveMonoMethod(true) +{ +} + +MMethod* MEvent::GetAddMethod() const +{ + return nullptr; // TODO: implement MEvent in .NET +} + +MMethod* MEvent::GetRemoveMethod() const +{ + return nullptr; // TODO: implement MEvent in .NET +} + +bool MEvent::HasAttribute(MClass* monoClass) const +{ + return false; // TODO: implement MEvent in .NET +} + +bool MEvent::HasAttribute() const +{ + return false; // TODO: implement MEvent in .NET +} + +MObject* MEvent::GetAttribute(MClass* monoClass) const +{ + return nullptr; // TODO: implement MEvent in .NET +} + +const Array& MEvent::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + // TODO: implement MEvent in .NET + return _attributes; +} + +MException::MException(MObject* exception) + : InnerException(nullptr) +{ + ASSERT(exception); + MClass* exceptionClass = MCore::Object::GetClass(exception); + + MProperty* exceptionMsgProp = exceptionClass->GetProperty("Message"); + MMethod* exceptionMsgGetter = exceptionMsgProp->GetGetMethod(); + MString* exceptionMsg = (MString*)exceptionMsgGetter->Invoke(exception, nullptr, nullptr); + Message = MUtils::ToString(exceptionMsg); + + MProperty* exceptionStackProp = exceptionClass->GetProperty("StackTrace"); + MMethod* exceptionStackGetter = exceptionStackProp->GetGetMethod(); + MString* exceptionStackTrace = (MString*)exceptionStackGetter->Invoke(exception, nullptr, nullptr); + StackTrace = MUtils::ToString(exceptionStackTrace); + + MProperty* innerExceptionProp = exceptionClass->GetProperty("InnerException"); + MMethod* innerExceptionGetter = innerExceptionProp->GetGetMethod(); + MObject* innerException = (MObject*)innerExceptionGetter->Invoke(exception, nullptr, nullptr); + if (innerException) + InnerException = New(innerException); +} + +MException::~MException() +{ + if (InnerException) + Delete(InnerException); +} + +MField::MField(MClass* parentClass, void* handle, const char* name, void* type, MFieldAttributes attributes) + : _handle(handle) + , _type(type) + , _parentClass(parentClass) + , _name(name) + , _hasCachedAttributes(false) +{ + switch (attributes & MFieldAttributes::FieldAccessMask) + { + case MFieldAttributes::Private: + _visibility = MVisibility::Private; + break; + case MFieldAttributes::FamANDAssem: + _visibility = MVisibility::PrivateProtected; + break; + case MFieldAttributes::Assembly: + _visibility = MVisibility::Internal; + break; + case MFieldAttributes::Family: + _visibility = MVisibility::Protected; + break; + case MFieldAttributes::FamORAssem: + _visibility = MVisibility::ProtectedInternal; + break; + case MFieldAttributes::Public: + _visibility = MVisibility::Public; + break; + default: + CRASH; + } + _isStatic = (attributes & MFieldAttributes::Static) == MFieldAttributes::Static; +} + +MType* MField::GetType() const +{ + return (MType*)_type; +} + +int32 MField::GetOffset() const +{ + MISSING_CODE("TODO: MField::GetOffset"); // TODO: MField::GetOffset + return 0; +} + +void MField::GetValue(MObject* instance, void* result) const +{ + static void* FieldGetValuePtr = GetStaticMethodPointer(TEXT("FieldGetValue")); + CallStaticMethod(FieldGetValuePtr, instance, _handle, result); +} + +MObject* MField::GetValueBoxed(MObject* instance) const +{ + MISSING_CODE("TODO: MField::GetValueBoxed"); // TODO: MField::GetValueBoxed + return nullptr; +} + +void MField::SetValue(MObject* instance, void* value) const +{ + static void* FieldSetValuePtr = GetStaticMethodPointer(TEXT("FieldSetValue")); + CallStaticMethod(FieldSetValuePtr, instance, _handle, value); +} + +bool MField::HasAttribute(MClass* monoClass) const +{ + // TODO: implement MField attributes in .NET + return false; +} + +bool MField::HasAttribute() const +{ + // TODO: implement MField attributes in .NET + return false; +} + +MObject* MField::GetAttribute(MClass* monoClass) const +{ + // TODO: implement MField attributes in .NET + return nullptr; +} + +const Array& MField::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + // TODO: implement MField attributes in .NET + return _attributes; +} + +MMethod::MMethod(MClass* parentClass, StringAnsi&& name, void* handle, int32 paramsCount, MMethodAttributes attributes) + : _handle(handle) + , _paramsCount(paramsCount) + , _parentClass(parentClass) + , _name(MoveTemp(name)) + , _hasCachedAttributes(false) + , _hasCachedSignature(false) +{ + switch (attributes & MMethodAttributes::MemberAccessMask) + { + case MMethodAttributes::Private: + _visibility = MVisibility::Private; + break; + case MMethodAttributes::FamANDAssem: + _visibility = MVisibility::PrivateProtected; + break; + case MMethodAttributes::Assembly: + _visibility = MVisibility::Internal; + break; + case MMethodAttributes::Family: + _visibility = MVisibility::Protected; + break; + case MMethodAttributes::FamORAssem: + _visibility = MVisibility::ProtectedInternal; + break; + case MMethodAttributes::Public: + _visibility = MVisibility::Public; + break; + default: + CRASH; + } + _isStatic = (attributes & MMethodAttributes::Static) == MMethodAttributes::Static; + +#if COMPILE_WITH_PROFILER + const StringAnsi& className = parentClass->GetFullName(); + ProfilerName.Resize(className.Length() + 2 + _name.Length()); + Platform::MemoryCopy(ProfilerName.Get(), className.Get(), className.Length()); + ProfilerName.Get()[className.Length()] = ':'; + ProfilerName.Get()[className.Length() + 1] = ':'; + Platform::MemoryCopy(ProfilerName.Get() + className.Length() + 2, _name.Get(), _name.Length()); + ProfilerData.name = ProfilerName.Get(); + ProfilerData.function = _name.Get(); + ProfilerData.file = nullptr; + ProfilerData.line = 0; + ProfilerData.color = 0; +#endif +} + +void MMethod::CacheSignature() const +{ + _hasCachedSignature = true; + + static void* GetMethodReturnTypePtr = GetStaticMethodPointer(TEXT("GetMethodReturnType")); + static void* GetMethodParameterTypesPtr = GetStaticMethodPointer(TEXT("GetMethodParameterTypes")); + + _returnType = CallStaticMethod(GetMethodReturnTypePtr, _handle); + + if (_paramsCount == 0) + return; + void** parameterTypeHandles; + CallStaticMethod(GetMethodParameterTypesPtr, _handle, ¶meterTypeHandles); + _parameterTypes.Set(parameterTypeHandles, _paramsCount); + MCore::GC::FreeMemory(parameterTypeHandles); +} + +MObject* MMethod::Invoke(void* instance, void** params, MObject** exception) const +{ + PROFILE_CPU_SRC_LOC(ProfilerData); + static void* InvokeMethodPtr = GetStaticMethodPointer(TEXT("InvokeMethod")); + return (MObject*)CallStaticMethod(InvokeMethodPtr, instance, _handle, params, exception); +} + +MObject* MMethod::InvokeVirtual(MObject* instance, void** params, MObject** exception) const +{ + return Invoke(instance, params, exception); +} + +#if !USE_MONO_AOT + +void* MMethod::GetThunk() +{ + if (!_cachedThunk) + { + static void* GetMethodUnmanagedFunctionPointerPtr = GetStaticMethodPointer(TEXT("GetMethodUnmanagedFunctionPointer")); + _cachedThunk = CallStaticMethod(GetMethodUnmanagedFunctionPointerPtr, _handle); + } + return _cachedThunk; +} + +#endif + +MMethod* MMethod::InflateGeneric() const +{ + // TODO: implement/test this on .NET (eg. C# script that inherits other generic C# script which implements C++ native method) + return const_cast(this); +} + +MType* MMethod::GetReturnType() const +{ + if (!_hasCachedSignature) + CacheSignature(); + return (MType*)_returnType; +} + +int32 MMethod::GetParametersCount() const +{ + return _paramsCount; +} + +MType* MMethod::GetParameterType(int32 paramIdx) const +{ + if (!_hasCachedSignature) + CacheSignature(); + ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < _paramsCount); + return (MType*)_parameterTypes[paramIdx]; +} + +bool MMethod::GetParameterIsOut(int32 paramIdx) const +{ + if (!_hasCachedSignature) + CacheSignature(); + ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < _paramsCount); + // TODO: cache GetParameterIsOut maybe? + static void* GetMethodParameterIsOutPtr = GetStaticMethodPointer(TEXT("GetMethodParameterIsOut")); + return CallStaticMethod(GetMethodParameterIsOutPtr, _handle, paramIdx); +} + +bool MMethod::HasAttribute(MClass* monoClass) const +{ + // TODO: implement MMethod attributes in .NET + return false; +} + +bool MMethod::HasAttribute() const +{ + // TODO: implement MMethod attributes in .NET + return false; +} + +MObject* MMethod::GetAttribute(MClass* monoClass) const +{ + // TODO: implement MMethod attributes in .NET + return nullptr; +} + +const Array& MMethod::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + // TODO: implement MMethod attributes in .NET + return _attributes; +} + +MProperty::MProperty(MClass* parentClass, const char* name, void* getterHandle, void* setterHandle, MMethodAttributes getterAttributes, MMethodAttributes setterAttributes) + : _parentClass(parentClass) + , _name(name) + , _hasCachedAttributes(false) +{ + _hasGetMethod = getterHandle != nullptr; + if (_hasGetMethod) + _getMethod = New(parentClass, StringAnsi("get_" + _name), getterHandle, 1, getterAttributes); + else + _getMethod = nullptr; + _hasSetMethod = setterHandle != nullptr; + if (_hasSetMethod) + _setMethod = New(parentClass, StringAnsi("set_" + _name), setterHandle, 1, setterAttributes); + else + _setMethod = nullptr; +} + +MProperty::~MProperty() +{ + if (_getMethod) + Delete(_getMethod); + if (_setMethod) + Delete(_setMethod); +} + +MMethod* MProperty::GetGetMethod() const +{ + return _getMethod; +} + +MMethod* MProperty::GetSetMethod() const +{ + return _setMethod; +} + +MObject* MProperty::GetValue(MObject* instance, MObject** exception) const +{ + MISSING_CODE("TODO: MProperty::GetValue"); // TODO: MProperty::GetValue + return nullptr; +} + +void MProperty::SetValue(MObject* instance, void* value, MObject** exception) const +{ + MISSING_CODE("TODO: MProperty::SetValue"); // TODO: MProperty::SetValue +} + +bool MProperty::HasAttribute(MClass* monoClass) const +{ + // TODO: implement MProperty attributes in .NET + return false; +} + +bool MProperty::HasAttribute() const +{ + // TODO: implement MProperty attributes in .NET + return false; +} + +MObject* MProperty::GetAttribute(MClass* monoClass) const +{ + // TODO: implement MProperty attributes in .NET + return nullptr; +} + +const Array& MProperty::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + // TODO: implement MProperty attributes in .NET + return _attributes; +} + +MAssembly* GetAssembly(void* assemblyHandle) +{ + MAssembly* assembly; + if (assemblyHandles.TryGet(assemblyHandle, assembly)) + return assembly; + return nullptr; +} + +MClass* GetClass(void* typeHandle) +{ + MClass* klass = nullptr; + classHandles.TryGet(typeHandle, klass); + return nullptr; +} + +MClass* GetOrCreateClass(void* typeHandle) +{ + if (!typeHandle) + return nullptr; + MClass* klass; + if (!classHandles.TryGet(typeHandle, klass)) + { + NativeClassDefinitions classInfo; + void* assemblyHandle; + static void* GetManagedClassFromTypePtr = GetStaticMethodPointer(TEXT("GetManagedClassFromType")); + CallStaticMethod(GetManagedClassFromTypePtr, typeHandle, &classInfo, &assemblyHandle); + MAssembly* assembly = GetAssembly(assemblyHandle); + klass = New(assembly, classInfo.typeHandle, classInfo.name, classInfo.fullname, classInfo.namespace_, classInfo.typeAttributes); + if (assembly != nullptr) + { + const_cast(assembly->GetClasses()).Add(klass->GetFullName(), klass); + } + + if (typeHandle != classInfo.typeHandle) + CallStaticMethod(GetManagedClassFromTypePtr, typeHandle, &classInfo); + + MCore::GC::FreeMemory((void*)classInfo.name); + MCore::GC::FreeMemory((void*)classInfo.fullname); + MCore::GC::FreeMemory((void*)classInfo.namespace_); + } + ASSERT(klass != nullptr); + return klass; +} + +bool HasCustomAttribute(const MClass* klass, const MClass* attributeClass) +{ + return GetCustomAttribute(klass, attributeClass) != nullptr; +} + +bool HasCustomAttribute(const MClass* klass) +{ + return GetCustomAttribute(klass, nullptr) != nullptr; +} + +void* GetCustomAttribute(const MClass* klass, const MClass* attributeClass) +{ + static void* GetCustomAttributePtr = GetStaticMethodPointer(TEXT("GetCustomAttribute")); + return CallStaticMethod(GetCustomAttributePtr, klass->GetNative(), attributeClass ? attributeClass->GetNative() : nullptr); +} + +#if DOTNET_HOST_CORECRL + +hostfxr_initialize_for_runtime_config_fn hostfxr_initialize_for_runtime_config; +hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line; +hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate; +hostfxr_close_fn hostfxr_close; +load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer; +get_function_pointer_fn get_function_pointer; +hostfxr_set_error_writer_fn hostfxr_set_error_writer; +hostfxr_get_dotnet_environment_info_result_fn hostfxr_get_dotnet_environment_info_result; +hostfxr_run_app_fn hostfxr_run_app; + +bool InitHostfxr(const String& configPath, const String& libraryPath) +{ + const FLAX_CORECLR_STRING& library_path = FLAX_CORECLR_STRING(libraryPath); + + // Get path to hostfxr library + get_hostfxr_parameters get_hostfxr_params; + get_hostfxr_params.size = sizeof(hostfxr_initialize_parameters); + get_hostfxr_params.assembly_path = library_path.Get(); + FLAX_CORECLR_STRING dotnetRoot; + // TODO: implement proper lookup for dotnet instalation folder and handle standalone build of FlaxGame +#if PLATFORM_MAC + get_hostfxr_params.dotnet_root = "/usr/local/share/dotnet"; +#else + get_hostfxr_params.dotnet_root = nullptr; +#endif +#if !USE_EDITOR + const String& bundledDotnetPath = Globals::ProjectFolder / TEXT("Dotnet"); + if (FileSystem::DirectoryExists(bundledDotnetPath)) + { + dotnetRoot = FLAX_CORECLR_STRING(bundledDotnetPath); +#if PLATFORM_WINDOWS_FAMILY + dotnetRoot.Replace('/', '\\'); +#endif + get_hostfxr_params.dotnet_root = dotnetRoot.Get(); + } +#endif + char_t hostfxrPath[1024]; + size_t hostfxrPathSize = sizeof(hostfxrPath) / sizeof(char_t); + int rc = get_hostfxr_path(hostfxrPath, &hostfxrPathSize, &get_hostfxr_params); + if (rc != 0) + { + LOG(Error, "Failed to find hostfxr: {0:x} ({1})", (unsigned int)rc, String(get_hostfxr_params.dotnet_root)); + + // Warn user about missing .Net +#if PLATFORM_DESKTOP + Platform::OpenUrl(TEXT("https://dotnet.microsoft.com/en-us/download/dotnet/7.0")); +#endif +#if USE_EDITOR + LOG(Fatal, "Missing .NET 7 SDK installation requried to run Flax Editor."); +#else + LOG(Fatal, "Missing .NET 7 Runtime installation requried to run this application."); +#endif + return true; + } + String path(hostfxrPath); + LOG(Info, "Found hostfxr in {0}", path); + + // Get API from hostfxr library + void* hostfxr = Platform::LoadLibrary(path.Get()); + if (hostfxr == nullptr) + { + LOG(Fatal, "Failed to load hostfxr library ({0})", path); + return true; + } + hostfxr_initialize_for_runtime_config = (hostfxr_initialize_for_runtime_config_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_runtime_config"); + hostfxr_initialize_for_dotnet_command_line = (hostfxr_initialize_for_dotnet_command_line_fn)Platform::GetProcAddress(hostfxr, "hostfxr_initialize_for_dotnet_command_line"); + hostfxr_get_runtime_delegate = (hostfxr_get_runtime_delegate_fn)Platform::GetProcAddress(hostfxr, "hostfxr_get_runtime_delegate"); + hostfxr_close = (hostfxr_close_fn)Platform::GetProcAddress(hostfxr, "hostfxr_close"); + hostfxr_set_error_writer = (hostfxr_set_error_writer_fn)Platform::GetProcAddress(hostfxr, "hostfxr_set_error_writer"); + hostfxr_get_dotnet_environment_info_result = (hostfxr_get_dotnet_environment_info_result_fn)Platform::GetProcAddress(hostfxr, "hostfxr_get_dotnet_environment_info_result"); + hostfxr_run_app = (hostfxr_run_app_fn)Platform::GetProcAddress(hostfxr, "hostfxr_run_app"); + if (!hostfxr_get_runtime_delegate || !hostfxr_run_app) + { + LOG(Fatal, "Failed to setup hostfxr API ({0})", path); + return true; + } + + // Initialize hosting component + const char_t* argv[1] = { library_path.Get() }; + hostfxr_initialize_parameters init_params; + init_params.size = sizeof(hostfxr_initialize_parameters); + init_params.host_path = library_path.Get(); + path = String(StringUtils::GetDirectoryName(path)) / TEXT("/../../../"); + StringUtils::PathRemoveRelativeParts(path); + dotnetRoot = FLAX_CORECLR_STRING(path); + init_params.dotnet_root = dotnetRoot.Get(); + hostfxr_handle handle = nullptr; + rc = hostfxr_initialize_for_dotnet_command_line(ARRAY_COUNT(argv), argv, &init_params, &handle); + if (rc != 0 || handle == nullptr) + { + hostfxr_close(handle); + LOG(Fatal, "Failed to initialize hostfxr: {0:x} ({1})", (unsigned int)rc, String(init_params.dotnet_root)); + return true; + } + + void* pget_function_pointer = nullptr; + rc = hostfxr_get_runtime_delegate(handle, hdt_get_function_pointer, &pget_function_pointer); + if (rc != 0 || pget_function_pointer == nullptr) + { + hostfxr_close(handle); + LOG(Fatal, "Failed to get runtime delegate hdt_get_function_pointer: 0x{0:x}", (unsigned int)rc); + return true; + } + + hostfxr_close(handle); + get_function_pointer = (get_function_pointer_fn)pget_function_pointer; + return false; +} + +void ShutdownHostfxr() +{ +} + +void* GetStaticMethodPointer(const String& methodName) +{ + void* fun; + if (CachedFunctions.TryGet(methodName, fun)) + return fun; + const int rc = get_function_pointer(NativeInteropTypeName, FLAX_CORECLR_STRING(methodName).Get(), UNMANAGEDCALLERSONLY_METHOD, nullptr, nullptr, &fun); + if (rc != 0) + LOG(Fatal, "Failed to get unmanaged function pointer for method {0}: 0x{1:x}", methodName.Get(), (unsigned int)rc); + CachedFunctions.Add(methodName, fun); + return fun; +} + +#elif DOTNET_HOST_MONO + +#ifdef USE_MONO_AOT_MODULE +void* MonoAotModuleHandle = nullptr; +#endif +MonoDomain* MonoDomainHandle = nullptr; + +void OnLogCallback(const char* logDomain, const char* logLevel, const char* message, mono_bool fatal, void* userData) +{ + String currentDomain(logDomain); + String msg(message); + msg.Replace('\n', ' '); + + static const char* monoErrorLevels[] = + { + nullptr, + "error", + "critical", + "warning", + "message", + "info", + "debug" + }; + + uint32 errorLevel = 0; + if (logLevel != nullptr) + { + for (uint32 i = 1; i < 7; i++) + { + if (strcmp(monoErrorLevels[i], logLevel) == 0) + { + errorLevel = i; + break; + } + } + } + + if (currentDomain.IsEmpty()) + { + auto domain = MCore::GetActiveDomain(); + if (domain != nullptr) + { + currentDomain = domain->GetName().Get(); + } + else + { + currentDomain = "null"; + } + } + +#if 0 + // Print C# stack trace (crash may be caused by the managed code) + if (mono_domain_get() && Assemblies::FlaxEngine.Assembly->IsLoaded()) + { + const auto managedStackTrace = DebugLog::GetStackTrace(); + if (managedStackTrace.HasChars()) + { + LOG(Warning, "Managed stack trace:"); + LOG_STR(Warning, managedStackTrace); + } + } +#endif + + if (errorLevel == 0) + { + Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); + } + else if (errorLevel <= 2) + { + Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); + } + else if (errorLevel <= 3) + { + LOG(Warning, "Message: {0} | Domain: {1}", msg, currentDomain); + } + else + { + LOG(Info, "Message: {0} | Domain: {1}", msg, currentDomain); + } +} + +void OnPrintCallback(const char* string, mono_bool isStdout) +{ + LOG_STR(Warning, String(string)); +} + +void OnPrintErrorCallback(const char* string, mono_bool isStdout) +{ + // HACK: ignore this message + if (string && Platform::MemoryCompare(string, "debugger-agent: Unable to listen on ", 36) == 0) + return; + + LOG_STR(Error, String(string)); +} + +bool InitHostfxr(const String& configPath, const String& libraryPath) +{ +#if 1 + // Enable detailed Mono logging + Platform::SetEnvironmentVariable(TEXT("MONO_LOG_LEVEL"), TEXT("debug")); + Platform::SetEnvironmentVariable(TEXT("MONO_LOG_MASK"), TEXT("all")); + //Platform::SetEnvironmentVariable(TEXT("MONO_GC_DEBUG"), TEXT("6:gc-log.txt,check-remset-consistency,nursery-canaries")); +#endif + +#if defined(USE_MONO_AOT_MODE) + // Enable AOT mode (per-platform) + mono_jit_set_aot_mode(USE_MONO_AOT_MODE); +#endif + +#ifdef USE_MONO_AOT_MODULE + // Load AOT module + const DateTime aotModuleLoadStartTime = DateTime::Now(); + LOG(Info, "Loading Mono AOT module..."); + void* libAotModule = Platform::LoadLibrary(TEXT(USE_MONO_AOT_MODULE)); + if (libAotModule == nullptr) + { + LOG(Error, "Failed to laod Mono AOT module (" TEXT(USE_MONO_AOT_MODULE) ")"); + return true; + } + MonoAotModuleHandle = libAotModule; + void* getModulesPtr = Platform::GetProcAddress(libAotModule, "GetMonoModules"); + if (getModulesPtr == nullptr) + { + LOG(Error, "Failed to get Mono AOT modules getter."); + return true; + } + typedef int (*GetMonoModulesFunc)(void** buffer, int bufferSize); + const auto getModules = (GetMonoModulesFunc)getModulesPtr; + const int32 moduelsCount = getModules(nullptr, 0); + void** modules = (void**)Allocator::Allocate(moduelsCount * sizeof(void*)); + getModules(modules, moduelsCount); + for (int32 i = 0; i < moduelsCount; i++) + { + mono_aot_register_module((void**)modules[i]); + } + Allocator::Free(modules); + LOG(Info, "Mono AOT module loaded in {0}ms", (int32)(DateTime::Now() - aotModuleLoadStartTime).GetTotalMilliseconds()); +#endif + + // Setup debugger + { + int32 debuggerLogLevel = 0; + if (CommandLine::Options.MonoLog.IsTrue()) + { + LOG(Info, "Using detailed Mono logging"); + mono_trace_set_level_string("debug"); + debuggerLogLevel = 10; + } + else + { + mono_trace_set_level_string("warning"); + } + +#if MONO_DEBUG_ENABLE && !PLATFORM_SWITCH + StringAnsi debuggerIp = "127.0.0.1"; + uint16 debuggerPort = 41000 + Platform::GetCurrentProcessId() % 1000; + if (CommandLine::Options.DebuggerAddress.HasValue()) + { + const auto& address = CommandLine::Options.DebuggerAddress.GetValue(); + const int32 splitIndex = address.Find(':'); + if (splitIndex == INVALID_INDEX) + { + debuggerIp = address.ToStringAnsi(); + } + else + { + debuggerIp = address.Left(splitIndex).ToStringAnsi(); + StringUtils::Parse(address.Right(address.Length() - splitIndex - 1).Get(), &debuggerPort); + } + } + + char buffer[150]; + sprintf(buffer, "--debugger-agent=transport=dt_socket,address=%s:%d,embedding=1,server=y,suspend=%s,loglevel=%d", debuggerIp.Get(), debuggerPort, CommandLine::Options.WaitForDebugger ? "y,timeout=5000" : "n", debuggerLogLevel); + + const char* options[] = { + "--soft-breakpoints", + //"--optimize=float32", + buffer + }; + mono_jit_parse_options(ARRAY_COUNT(options), (char**)options); + + mono_debug_init(MONO_DEBUG_FORMAT_MONO, 0); + LOG(Info, "Mono debugger server at {0}:{1}", ::String(debuggerIp), debuggerPort); +#endif + } + + // Connect to mono engine callback system + mono_trace_set_log_handler(OnLogCallback, nullptr); + mono_trace_set_print_handler(OnPrintCallback); + mono_trace_set_printerr_handler(OnPrintErrorCallback); + + // Initialize Mono VM + StringAnsi baseDirectory(Globals::ProjectFolder); + const char* appctxKeys[] = + { + "RUNTIME_IDENTIFIER", + "APP_CONTEXT_BASE_DIRECTORY", + }; + const char* appctxValues[] = + { + MACRO_TO_STR(DOTNET_HOST_RUNTIME_IDENTIFIER), + baseDirectory.Get(), + }; + static_assert(ARRAY_COUNT(appctxKeys) == ARRAY_COUNT(appctxValues), "Invalid appctx setup"); + monovm_initialize(ARRAY_COUNT(appctxKeys), appctxKeys, appctxValues); + + // Init managed runtime +#if PLATFORM_ANDROID || PLATFORM_IOS + const char* monoVersion = "mobile"; +#else + const char* monoVersion = ""; // ignored +#endif + MonoDomainHandle = mono_jit_init_version("Flax", monoVersion); + if (!MonoDomainHandle) + { + LOG(Fatal, "Failed to initialize Mono."); + return true; + } + + // Log info + char* buildInfo = mono_get_runtime_build_info(); + LOG(Info, "Mono runtime version: {0}", String(buildInfo)); + mono_free(buildInfo); + + return false; +} + +void ShutdownHostfxr() +{ + mono_jit_cleanup(MonoDomainHandle); + MonoDomainHandle = nullptr; + +#ifdef USE_MONO_AOT_MODULE + Platform::FreeLibrary(MonoAotModuleHandle); +#endif +} + +void* GetStaticMethodPointer(const String& methodName) +{ + MISSING_CODE("TODO: GetStaticMethodPointer for Mono host runtime"); // TODO: impl this + return nullptr; +} + +#endif + +#endif diff --git a/Source/Engine/Scripting/Runtime/Mono.cpp b/Source/Engine/Scripting/Runtime/Mono.cpp new file mode 100644 index 000000000..f34fb4b87 --- /dev/null +++ b/Source/Engine/Scripting/Runtime/Mono.cpp @@ -0,0 +1,3564 @@ +// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. + +#include "Engine/Scripting/Types.h" + +#if USE_MONO + +#include "Engine/Core/Log.h" +#include "Engine/Core/Types/DateTime.h" +#include "Engine/Core/Types/TimeSpan.h" +#include "Engine/Platform/File.h" +#include "Engine/Platform/FileSystem.h" +#include "Engine/Engine/Globals.h" +#include "Engine/Engine/CommandLine.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" +#include "Engine/Scripting/ManagedCLR/MAssembly.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MDomain.h" +#include "Engine/Scripting/ManagedCLR/MEvent.h" +#include "Engine/Scripting/ManagedCLR/MField.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" +#include "Engine/Scripting/ManagedCLR/MProperty.h" +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/ManagedCLR/MUtils.h" +#include "Engine/Scripting/Scripting.h" +#include "Engine/Scripting/BinaryModule.h" +#include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Threading/Threading.h" +#include "Engine/Debug/Exceptions/CLRInnerException.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !USE_MONO_DYNAMIC_LIB +#include +#endif + +#ifdef USE_MONO_AOT_MODULE +void* MonoAotModuleHandle = nullptr; +#endif + +#define GET_CUSTOM_ATTR() (MonoCustomAttrInfo*)(_attrInfo ? _attrInfo : _attrInfo = mono_custom_attrs_from_class(_monoClass)) + +extern MDomain* MRootDomain; +extern MDomain* MActiveDomain; +extern Array> MDomains; + +// Inlined mono private types to access MonoType internals + +typedef struct _MonoGenericClass MonoGenericClass; +typedef struct _MonoGenericContext MonoGenericContext; + +struct _MonoGenericInst +{ + unsigned int id; + unsigned int type_argc : 22; + unsigned int is_open : 1; + MonoType* type_argv[MONO_ZERO_LEN_ARRAY]; +}; + +struct _MonoGenericContext +{ + MonoGenericInst* class_inst; + MonoGenericInst* method_inst; +}; + +struct _MonoGenericClass +{ + MonoClass* container_class; + MonoGenericContext context; + unsigned int is_dynamic : 1; + unsigned int is_tb_open : 1; + unsigned int need_sync : 1; + MonoClass* cached_class; + class MonoImageSet* owner; +}; + +struct _MonoType +{ + union + { + MonoClass* klass; + MonoType* type; + MonoArrayType* array; + MonoMethodSignature* method; + MonoGenericParam* generic_param; + MonoGenericClass* generic_class; + } data; + + unsigned int attrs : 16; + MonoTypeEnum type : 8; + unsigned int has_cmods : 1; + unsigned int byref : 1; + unsigned int pinned : 1; +}; + +namespace +{ + static StringAnsi PlusStr("+"); + static StringAnsi DotStr("."); + + void GetClassFullname(MonoClass* monoClass, StringAnsi& fullname) + { + // Name + fullname = mono_class_get_name(monoClass); + + // Outer class for nested types + MonoClass* nestingClass = mono_class_get_nesting_type(monoClass); + MonoClass* lastClass = monoClass; + while (nestingClass) + { + lastClass = nestingClass; + fullname = mono_class_get_name(nestingClass) + PlusStr + fullname; + nestingClass = mono_class_get_nesting_type(nestingClass); + } + + // Namespace + const char* lastClassNamespace = mono_class_get_namespace(lastClass); + if (lastClassNamespace && *lastClassNamespace) + fullname = lastClassNamespace + DotStr + fullname; + + // Generic instance arguments + MonoType* mType = mono_class_get_type(monoClass); + if (mType && mType->type == MONO_TYPE_GENERICINST) + { + fullname += '['; + StringAnsi tmp; + for (unsigned int i = 0; i < mType->data.generic_class->context.class_inst->type_argc; i++) + { + if (i != 0) + fullname += ','; + MType* argType = mType->data.generic_class->context.class_inst->type_argv[i]; + GetClassFullname(mono_class_from_mono_type(argType), tmp); + fullname += tmp; + } + fullname += ']'; + } + } + + MClass* FindClass(MonoClass* monoClass, bool addIfMissing = true) + { + if (monoClass == nullptr) + return nullptr; + PROFILE_CPU(); + auto& modules = BinaryModule::GetModules(); + for (auto module : modules) + { + auto managedModule = dynamic_cast(module); + if (managedModule && managedModule->Assembly->IsLoaded()) + { + MClass* result = managedModule->Assembly->GetClass(monoClass); + if (result != nullptr) + return result; + } + } + if (addIfMissing) + { + MISSING_CODE("TODO: register new MClass"); // TODO: this might happen when for example querying class to array of game script type and it should add new MClass to handle this + } + return nullptr; + } +} + +MDomain* MCore::CreateDomain(const StringAnsi& domainName) +{ +#if USE_MONO_AOT + LOG(Fatal, "Scripts can run only in single domain mode with AOT mode enabled."); + return nullptr; +#endif + + for (int32 i = 0; i < MDomains.Count(); i++) + { + if (MDomains[i]->GetName() == domainName) + return MDomains[i]; + } + + auto domain = New(domainName); + const auto monoDomain = mono_domain_create_appdomain((char*)domainName.Get(), nullptr); +#if MONO_DEBUG_ENABLE + mono_debug_domain_create(monoDomain); +#endif + ASSERT(monoDomain); + domain->_monoDomain = monoDomain; + MDomains.Add(domain); + return domain; +} + +void MCore::UnloadDomain(const StringAnsi& domainName) +{ + int32 i = 0; + for (; i < MDomains.Count(); i++) + { + if (MDomains[i]->GetName() == domainName) + break; + } + if (i == MDomains.Count()) + return; + + auto domain = MDomains[i]; +#if MONO_DEBUG_ENABLE + //mono_debug_domain_unload(domain->GetNative()); +#endif + //mono_domain_finalize(domain->GetNative(), 2000); + MObject* exception = nullptr; + mono_domain_try_unload(domain->GetNative(), &exception); + if (exception) + { + MException ex(exception); + ex.Log(LogType::Fatal, TEXT("Scripting::Release")); + } + Delete(domain); + MDomains.RemoveAtKeepOrder(i); +} + +#if 0 + +void* MonoMalloc(size_t size) +{ + return malloc(size); +} + +void* MonoRealloc(void* mem, size_t count) +{ + return realloc(mem, count); +} + +void MonoFree(void* mem) +{ + return free(mem); +} + +void* MonoCalloc(size_t count, size_t size) +{ + return calloc(count, size); +} + +#endif + +#if USE_MONO_PROFILER + +#include "Engine/Core/Types/StringBuilder.h" + +struct FlaxMonoProfiler +{ +}; + +FlaxMonoProfiler Profiler; + +struct StackWalkDataResult +{ + StringBuilder Buffer; +}; + +mono_bool OnStackWalk(MonoMethod* method, int32_t native_offset, int32_t il_offset, mono_bool managed, void* data) +{ + auto result = (StackWalkDataResult*)data; + + if (method) + { + auto mName = mono_method_get_name(method); + auto mKlassNameSpace = mono_class_get_namespace(mono_method_get_class(method)); + auto mKlassName = mono_class_get_name(mono_method_get_class(method)); + result->Buffer.Append(mKlassNameSpace); + result->Buffer.Append(TEXT(".")); + result->Buffer.Append(mKlassName); + result->Buffer.Append(TEXT("::")); + result->Buffer.Append(mName); + result->Buffer.Append(TEXT("\n")); + } + else if (!managed) + { + result->Buffer.Append(TEXT("\n")); + } + + return 0; +} + +void OnGCAllocation(MonoProfiler* profiler, MonoObject* obj) +{ + // Get allocation info + auto klass = mono_object_get_class(obj); + //auto name_space = mono_class_get_namespace(klass); + //auto name = mono_class_get_name(klass); + auto size = mono_class_instance_size(klass); + + //LOG(Info, "GC new: {0}.{1} ({2} bytes)", name_space, name, size); + +#if 0 + if (ProfilerCPU::IsProfilingCurrentThread()) + { + static int details = 0; + if (details) + { + StackWalkDataResult stackTrace; + stackTrace.Buffer.SetCapacity(1024); + mono_stack_walk(&OnStackWalk, &stackTrace); + + const auto msg = String::Format(TEXT("GC new: {0}.{1} ({2} bytes). Stack Trace:\n{3}"), String(name_space), String(name), size, stackTrace.Buffer.ToStringView()); + Platform::Log(*msg); + //LOG_STR(Info, msg); + } + } +#endif + +#if COMPILE_WITH_PROFILER + // Register allocation during the current CPU event + auto thread = ProfilerCPU::GetCurrentThread(); + if (thread != nullptr && thread->Buffer.GetCount() != 0) + { + auto& activeEvent = thread->Buffer.Last().Event(); + if (activeEvent.End < ZeroTolerance) + { + activeEvent.ManagedMemoryAllocation += size; + } + } +#endif +} + +void OnGCEvent(MonoProfiler* profiler, MonoProfilerGCEvent event, uint32_t generation, mono_bool is_serial) +{ +#if COMPILE_WITH_PROFILER + // GC + static int32 ActiveEventIndex; + if (event == MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED) + { + ActiveEventIndex = ProfilerCPU::BeginEvent(TEXT("Garbage Collection")); + } + else if (event == MONO_GC_EVENT_POST_START_WORLD_UNLOCKED) + { + ProfilerCPU::EndEvent(ActiveEventIndex); + } +#endif +} + +#endif + +void OnLogCallback(const char* logDomain, const char* logLevel, const char* message, mono_bool fatal, void* userData) +{ + String currentDomain(logDomain); + String msg(message); + msg.Replace('\n', ' '); + + static const char* monoErrorLevels[] = + { + nullptr, + "error", + "critical", + "warning", + "message", + "info", + "debug" + }; + + uint32 errorLevel = 0; + if (logLevel != nullptr) + { + for (uint32 i = 1; i < 7; i++) + { + if (strcmp(monoErrorLevels[i], logLevel) == 0) + { + errorLevel = i; + break; + } + } + } + + if (currentDomain.IsEmpty()) + { + auto domain = MCore::GetActiveDomain(); + if (domain != nullptr) + { + currentDomain = domain->GetName().Get(); + } + else + { + currentDomain = "null"; + } + } + +#if 0 + // Print C# stack trace (crash may be caused by the managed code) + if (mono_domain_get() && Assemblies::FlaxEngine.Assembly->IsLoaded()) + { + const auto managedStackTrace = DebugLog::GetStackTrace(); + if (managedStackTrace.HasChars()) + { + LOG(Warning, "Managed stack trace:"); + LOG_STR(Warning, managedStackTrace); + } + } +#endif + + if (errorLevel == 0) + { + Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); + } + else if (errorLevel <= 2) + { + Log::CLRInnerException(String::Format(TEXT("Message: {0} | Domain: {1}"), msg, currentDomain)).SetLevel(LogType::Error); + } + else if (errorLevel <= 3) + { + LOG(Warning, "Message: {0} | Domain: {1}", msg, currentDomain); + } + else + { + LOG(Info, "Message: {0} | Domain: {1}", msg, currentDomain); + } +} + +void OnPrintCallback(const char* string, mono_bool isStdout) +{ + LOG_STR(Warning, String(string)); +} + +void OnPrintErrorCallback(const char* string, mono_bool isStdout) +{ + // HACK: ignore this message + if (string && Platform::MemoryCompare(string, "debugger-agent: Unable to listen on ", 36) == 0) + return; + + LOG_STR(Error, String(string)); +} + +#if PLATFORM_LINUX && !USE_MONO_DYNAMIC_LIB + +#include + +#define MONO_THIS_LIB_HANDLE ((void*)(intptr)-1) + +static void* ThisLibHandle = nullptr; + +static void* OnMonoLinuxDlOpen(const char* name, int flags, char** err, void* user_data) +{ + void* result = nullptr; + if (name && StringUtils::Compare(name + StringUtils::Length(name) - 17, "libmono-native.so") == 0) + { + result = MONO_THIS_LIB_HANDLE; + } + return result; +} + +static void* OnMonoLinuxDlSym(void* handle, const char* name, char** err, void* user_data) +{ + void* result = nullptr; + if (handle == MONO_THIS_LIB_HANDLE && ThisLibHandle != nullptr) + { + result = dlsym(ThisLibHandle, name); + } + return result; +} + +#endif + +bool MCore::LoadEngine() +{ + PROFILE_CPU(); + ASSERT(Globals::MonoPath.IsANSI()); + + // Debugging Mono GC + //Platform::SetEnvironmentVariable(TEXT("MONO_GC_DEBUG"), TEXT("6:gc-log.txt,check-remset-consistency,nursery-canaries")); + +#if 0 + // Override memory allocation callback + // TODO: use ENABLE_OVERRIDABLE_ALLOCATORS when building Mono to support memory callbacks or use counters for memory profiling + MonoAllocatorVTable alloc; + alloc.version = MONO_ALLOCATOR_VTABLE_VERSION; + alloc.malloc = MonoMalloc; + alloc.realloc = MonoRealloc; + alloc.free = MonoFree; + alloc.calloc = MonoCalloc; + mono_set_allocator_vtable(&alloc); +#endif + +#if USE_MONO_AOT + mono_jit_set_aot_mode(USE_MONO_AOT_MODE); +#endif + +#ifdef USE_MONO_AOT_MODULE + // Load AOT module + const DateTime aotModuleLoadStartTime = DateTime::Now(); + LOG(Info, "Loading Mono AOT module..."); + void* libAotModule = Platform::LoadLibrary(TEXT(USE_MONO_AOT_MODULE)); + if (libAotModule == nullptr) + { + LOG(Error, "Failed to laod Mono AOT module (" TEXT(USE_MONO_AOT_MODULE) ")"); + return true; + } + MonoAotModuleHandle = libAotModule; + void* getModulesPtr = Platform::GetProcAddress(libAotModule, "GetMonoModules"); + if (getModulesPtr == nullptr) + { + LOG(Error, "Failed to get Mono AOT modules getter."); + return true; + } + typedef int (*GetMonoModulesFunc)(void** buffer, int bufferSize); + const auto getModules = (GetMonoModulesFunc)getModulesPtr; + const int32 moduelsCount = getModules(nullptr, 0); + void** modules = (void**)Allocator::Allocate(moduelsCount * sizeof(void*)); + getModules(modules, moduelsCount); + for (int32 i = 0; i < moduelsCount; i++) + { + mono_aot_register_module((void**)modules[i]); + } + Allocator::Free(modules); + LOG(Info, "Mono AOT module loaded in {0}ms", (int32)(DateTime::Now() - aotModuleLoadStartTime).GetTotalMilliseconds()); +#endif + + // Set mono assemblies path + StringAnsi pathLib = (Globals::MonoPath / TEXT("/lib")).ToStringAnsi(); + StringAnsi pathEtc = (Globals::MonoPath / TEXT("/etc")).ToStringAnsi(); + mono_set_dirs(pathLib.Get(), pathEtc.Get()); + + // Setup debugger + { + int32 debuggerLogLevel = 0; + if (CommandLine::Options.MonoLog.IsTrue()) + { + LOG(Info, "Using detailed Mono logging"); + mono_trace_set_level_string("debug"); + debuggerLogLevel = 10; + } + else + { + mono_trace_set_level_string("warning"); + } + +#if MONO_DEBUG_ENABLE && !PLATFORM_SWITCH + StringAnsi debuggerIp = "127.0.0.1"; + uint16 debuggerPort = 41000 + Platform::GetCurrentProcessId() % 1000; + if (CommandLine::Options.DebuggerAddress.HasValue()) + { + const auto& address = CommandLine::Options.DebuggerAddress.GetValue(); + const int32 splitIndex = address.Find(':'); + if (splitIndex == INVALID_INDEX) + { + debuggerIp = address.ToStringAnsi(); + } + else + { + debuggerIp = address.Left(splitIndex).ToStringAnsi(); + StringUtils::Parse(address.Right(address.Length() - splitIndex - 1).Get(), &debuggerPort); + } + } + + char buffer[150]; + sprintf(buffer, "--debugger-agent=transport=dt_socket,address=%s:%d,embedding=1,server=y,suspend=%s,loglevel=%d", debuggerIp.Get(), debuggerPort, CommandLine::Options.WaitForDebugger ? "y,timeout=5000" : "n", debuggerLogLevel); + + const char* options[] = { + "--soft-breakpoints", + //"--optimize=float32", + buffer + }; + mono_jit_parse_options(ARRAY_COUNT(options), (char**)options); + + mono_debug_init(MONO_DEBUG_FORMAT_MONO, 0); + LOG(Info, "Mono debugger server at {0}:{1}", ::String(debuggerIp), debuggerPort); +#endif + + // Connects to mono engine callback system + mono_trace_set_log_handler(OnLogCallback, nullptr); + mono_trace_set_print_handler(OnPrintCallback); + mono_trace_set_printerr_handler(OnPrintErrorCallback); + } + +#if USE_MONO_PROFILER + // Setup profiler options + bool useExternalProfiler = false; + { + ::String monoEnvOptions; + if (!Platform::GetEnvironmentVariable(TEXT("MONO_ENV_OPTIONS"), monoEnvOptions)) + { + const StringView prefix(TEXT("--profile=")); + if (monoEnvOptions.StartsWith(prefix)) + { + monoEnvOptions = monoEnvOptions.Substring(prefix.Length()); + LOG(Info, "Loading Mono profiler with options \'{0}\'", monoEnvOptions); + StringAnsi monoEnvOptionsAnsi(monoEnvOptions); + mono_profiler_load(monoEnvOptionsAnsi.Get()); + useExternalProfiler = true; + } + } + } +#endif + +#if PLATFORM_ANDROID + // Disable any AOT code on Android + mono_jit_set_aot_mode(MONO_AOT_MODE_NONE); + + // Hint to use default system assemblies location + const StringAnsi assembliesPath = (Globals::MonoPath / TEXT("/lib/mono/2.1")).ToStringAnsi(); + mono_set_assemblies_path(*assembliesPath); +#elif PLATFORM_LINUX + // Adjust GC threads suspending mode on Linux + Platform::SetEnvironmentVariable(TEXT("MONO_THREADS_SUSPEND"), TEXT("preemptive")); + +#if !USE_MONO_DYNAMIC_LIB + // Hook for missing library (when using static linking) + ThisLibHandle = dlopen(nullptr, RTLD_LAZY); + mono_dl_fallback_register(OnMonoLinuxDlOpen, OnMonoLinuxDlSym, nullptr, nullptr); +#endif +#elif PLATFORM_MAC + // Adjust GC threads suspending mode on Mac + Platform::SetEnvironmentVariable(TEXT("MONO_THREADS_SUSPEND"), TEXT("preemptive")); +#endif + const char* configPath = nullptr; +#if PLATFORM_SWITCH + StringAnsi configPathBuf = (Globals::MonoPath / TEXT("/etc/mono/config")).ToStringAnsi(); + configPath = *configPathBuf; + const StringAnsi assembliesPath = (Globals::MonoPath / TEXT("/lib/mono/4.5")).ToStringAnsi(); + mono_set_assemblies_path(*assembliesPath); +#endif + mono_config_parse(configPath); + +#if USE_MONO_PROFILER + // Init profiler + if (!useExternalProfiler) + { + const MonoProfilerHandle profilerHandle = mono_profiler_create((MonoProfiler*)&Profiler); + mono_profiler_set_gc_allocation_callback(profilerHandle, &OnGCAllocation); + mono_profiler_set_gc_event_callback(profilerHandle, &OnGCEvent); + mono_profiler_enable_allocations(); + } +#endif + + // Init managed runtime +#if PLATFORM_ANDROID + const char* monoVersion = "mobile"; +#else + const char* monoVersion = "v4.0.30319"; +#endif + auto monoRootDomain = mono_jit_init_version("Flax", monoVersion); + ASSERT(monoRootDomain); + MRootDomain = New("Root"); + MRootDomain->_monoDomain = monoRootDomain; + MDomains.Add(MRootDomain); + + auto exePath = Platform::GetExecutableFilePath(); + auto configDir = StringUtils::GetDirectoryName(exePath).ToStringAnsi(); + auto configFilename = StringUtils::GetFileName(exePath).ToStringAnsi() + ".config"; +#if PLATFORM_UWP + // Change the app root to Mono sub directory to prevent loading .Net Core assemblies from the AppX root folder + configDir += "\\Mono"; +#elif PLATFORM_SWITCH + // Make config file path absolute + configFilename = exePath.ToStringAnsi() + ".config"; +#endif + mono_domain_set_config(monoRootDomain, configDir.Get(), configFilename.Get()); + mono_thread_set_main(mono_thread_current()); + + // Info + char* buildInfo = mono_get_runtime_build_info(); + LOG(Info, "Mono runtime version: {0}", ::String(buildInfo)); + mono_free(buildInfo); + + return false; +} + +#if PLATFORM_WINDOWS && USE_EDITOR +long MonoHackSehExceptionHandler(class EXCEPTION_POINTERS* ep) +{ + LOG(Error, "Mono crashed on exit"); + return 1; +} +#endif + +void MCore::UnloadEngine() +{ + // Only root domain should be alive at this point + for (auto domain : MDomains) + { + if (domain != MRootDomain) + Delete(domain); + } + MDomains.Clear(); + + if (MRootDomain) + { +#if PLATFORM_WINDOWS && USE_EDITOR + // TODO: reduce issues with hot-reloading C# DLLs because sometimes it crashes on exit + __try +#endif + { + mono_jit_cleanup(MRootDomain->GetNative()); + } +#if PLATFORM_WINDOWS && USE_EDITOR + __except (MonoHackSehExceptionHandler(nullptr)) + { + } +#endif + Delete(MRootDomain); + MRootDomain = nullptr; + } + +#ifdef USE_MONO_AOT_MODULE + Platform::FreeLibrary(MonoAotModuleHandle); +#endif + +#if PLATFORM_LINUX && !USE_MONO_DYNAMIC_LIB + if (ThisLibHandle) + { + dlclose(ThisLibHandle); + ThisLibHandle = nullptr; + } +#endif +} + +MObject* MCore::Object::Box(void* value, const MClass* klass) +{ + return mono_value_box(mono_domain_get(), klass->GetNative(), value); +} + +void* MCore::Object::Unbox(MObject* obj) +{ + return (byte*)obj + sizeof(MonoObject); + //return mono_object_unbox(obj); +} + +MObject* MCore::Object::New(const MClass* klass) +{ + return mono_object_new(mono_domain_get(), klass->GetNative()); +} + +void MCore::Object::Init(MObject* obj) +{ + mono_runtime_object_init(obj); +} + +MClass* MCore::Object::GetClass(MObject* obj) +{ + MonoClass* mclass = mono_object_get_class(obj); + return FindClass(mclass); +} + +MString* MCore::Object::ToString(MObject* obj) +{ + return mono_object_to_string(obj, nullptr); +} + +int32 MCore::Object::GetHashCode(MObject* obj) +{ + return mono_object_hash(obj); +} + +MString* MCore::String::GetEmpty(MDomain* domain) +{ + MonoDomain* mdomain = domain ? domain->GetNative() : mono_domain_get(); + return mono_string_empty(mdomain); +} + +MString* MCore::String::New(const char* str, int32 length, MDomain* domain) +{ + MonoDomain* mdomain = domain ? domain->GetNative() : mono_domain_get(); + return mono_string_new_len(mdomain, str, length); +} + +MString* MCore::String::New(const Char* str, int32 length, MDomain* domain) +{ + MonoDomain* mdomain = domain ? domain->GetNative() : mono_domain_get(); + return mono_string_new_utf16(mdomain, str, length); +} + +StringView MCore::String::GetChars(MString* obj) +{ + return StringView(mono_string_chars(obj), (int32)mono_string_length(obj)); +} + +MArray* MCore::Array::New(const MClass* elementKlass, int32 length) +{ + // TODO: use shared empty arrays cache + return mono_array_new(mono_domain_get(), elementKlass->GetNative(), length); +} + +MClass* MCore::Array::GetClass(MClass* elementKlass) +{ + MonoClass* monoClass = mono_array_class_get(elementKlass->GetNative(), 1); + return FindClass(monoClass); +} + +int32 MCore::Array::GetLength(const MArray* obj) +{ + return (int32)mono_array_length((MonoArray*)obj); +} + +void* MCore::Array::GetAddress(const MArray* obj) +{ + return mono_array_addr_with_size((MonoArray*)obj, 0, 0); +} + +MGCHandle MCore::GCHandle::New(MObject* obj, bool pinned) +{ + return mono_gchandle_new(obj, pinned); +} + +MGCHandle MCore::GCHandle::NewWeak(MObject* obj, bool trackResurrection) +{ + return mono_gchandle_new_weakref(obj, trackResurrection); +} + +MObject* MCore::GCHandle::GetTarget(const MGCHandle& handle) +{ + return mono_gchandle_get_target(handle); +} + +void MCore::GCHandle::Free(const MGCHandle& handle) +{ + mono_gchandle_free(handle); +} + +void MCore::GC::Collect() +{ + PROFILE_CPU(); + mono_gc_collect(mono_gc_max_generation()); +} + +void MCore::GC::Collect(int32 generation) +{ + PROFILE_CPU(); + mono_gc_collect(generation); +} + +void MCore::GC::WaitForPendingFinalizers() +{ + PROFILE_CPU(); + if (mono_gc_pending_finalizers()) + { + mono_gc_finalize_notify(); + do + { + Platform::Sleep(1); + } while (mono_gc_pending_finalizers()); + } +} + +void MCore::GC::WriteRef(void* ptr, MObject* ref) +{ + mono_gc_wbarrier_generic_store(ptr, ref); +} + +void MCore::GC::WriteValue(void* dst, void* src, int32 count, const MClass* klass) +{ + mono_gc_wbarrier_value_copy(dst, src, count, klass->GetNative()); +} + +void MCore::GC::WriteArrayRef(MArray* dst, MObject* ref, int32 index) +{ + void* ptr = mono_array_addr_with_size(dst, 0, 0); + mono_gc_wbarrier_set_arrayref(dst, (byte*)ptr + index * sizeof(void*), ref); +} + +void MCore::Thread::Attach() +{ + if (!IsInMainThread() && !mono_domain_get()) + { + const auto domain = GetActiveDomain(); + ASSERT(domain); + mono_thread_attach(domain->GetNative()); + } +} + +void MCore::Thread::Exit() +{ + if (!IsInMainThread() && mono_domain_get()) + { + LOG(Info, "Thread 0x{0:x} exits the managed runtime", Platform::GetCurrentThreadID()); + // TODO: use mono_thread_detach but modify mono to call mono_thread_info_detach there so the thread goes into STATE_DETACHED + mono_thread_exit(); + } +} + +bool MCore::Thread::IsAttached() +{ + return mono_domain_get() && mono_thread_current(); +} + +void MCore::Exception::Throw(MObject* exception) +{ + mono_raise_exception((MonoException*)exception); +} + +MObject* MCore::Exception::GetNullReference() +{ + return (MonoObject*)mono_get_exception_null_reference(); +} + +MObject* MCore::Exception::Get(const char* msg) +{ + return (MonoObject*)mono_exception_from_name_msg(mono_get_corlib(), "System", "Exception", msg); +} + +MObject* MCore::Exception::GetArgument(const char* arg, const char* msg) +{ + return (MonoObject*)mono_get_exception_argument(arg, msg); +} + +MObject* MCore::Exception::GetArgumentNull(const char* arg) +{ + return (MonoObject*)mono_get_exception_argument_null(arg); +} + +MObject* MCore::Exception::GetArgumentOutOfRange(const char* arg) +{ + return (MonoObject*)mono_get_exception_argument_out_of_range(arg); +} + +MObject* MCore::Exception::GetNotSupported(const char* msg) +{ + return (MonoObject*)mono_get_exception_not_supported(msg); +} + +::String MCore::Type::ToString(MType* type) +{ + return ::String(mono_type_get_name(type)); +} + +MClass* MCore::Type::GetClass(MType* type) +{ + MonoClass* mclass = mono_class_from_mono_type(type); + return FindClass(mclass); +} + +int32 MCore::Type::GetSize(MType* type) +{ + int32 valueAlignment; + return mono_type_stack_size(type, &valueAlignment); +} + +MTypes MCore::Type::GetType(MType* type) +{ + return (MTypes)type->type; +} + +bool MCore::Type::IsPointer(MType* type) +{ + return mono_type_is_pointer(type) != 0; +} + +bool MCore::Type::IsReference(MType* type) +{ + return mono_type_is_reference(type) != 0; +} + +MTypeObject* MCore::Type::GetObject(MType* type) +{ + return mono_type_get_object(mono_domain_get(), type); +} + +MType* MCore::Type::Get(MTypeObject* type) +{ + return mono_reflection_type_get_type(type); +} + +MClass* MAssembly::GetClass(MonoClass* monoClass) const +{ + if (monoClass == nullptr || !IsLoaded() || mono_class_get_image(monoClass) != _monoImage) + return nullptr; + + // Find class by native pointer + const auto& classes = GetClasses(); + const auto typeToken = mono_class_get_type_token(monoClass); + for (auto i = classes.Begin(); i.IsNotEnd(); ++i) + { + MonoClass* e = i->Value->GetNative(); + if (e == monoClass || mono_class_get_type_token(e) == typeToken) + { + return i->Value; + } + } + +#if 0 + { + LOG(Warning, "Failed to find class {0}.{1} in assembly {2}. Classes:", String(mono_class_get_namespace(monoClass)), String(mono_class_get_name(monoClass)), ToString()); + for (auto i = classes.Begin(); i.IsNotEnd(); ++i) + { + LOG(Warning, " - {0}", String(i->Key)); + } + } +#endif + return nullptr; +} + +MonoReflectionAssembly* MAssembly::GetNative() const +{ + if (!_monoAssembly) + return nullptr; + return mono_assembly_get_object(mono_domain_get(), _monoAssembly); +} + +const MAssembly::ClassesDictionary& MAssembly::GetClasses() const +{ + if (_hasCachedClasses || !IsLoaded()) + return _classes; + PROFILE_CPU(); + const auto startTime = DateTime::NowUTC(); + +#if TRACY_ENABLE + const StringAnsiView monoImageName(mono_image_get_name(_monoImage)); + ZoneText(*monoImageName, monoImageName.Length()); +#endif + ScopeLock lock(_locker); + if (_hasCachedClasses) + return _classes; + ASSERT(_classes.IsEmpty()); + const int32 numRows = mono_image_get_table_rows(_monoImage, MONO_TABLE_TYPEDEF); + _classes.EnsureCapacity(numRows * 4); + for (int32 i = 1; i < numRows; i++) // Skip class + { + MonoClass* klass = mono_class_get(_monoImage, (i + 1) | MONO_TOKEN_TYPE_DEF); + + // Build the typename + StringAnsi fullname; + GetClassFullname(klass, fullname); + + // Create class object + auto mclass = New(this, klass, fullname); + _classes.Add(fullname, mclass); + } + + const auto endTime = DateTime::NowUTC(); + LOG(Info, "Caching classes for assembly {0} took {1}ms", String(_name), (int32)(endTime - startTime).GetTotalMilliseconds()); + +#if 0 + for (auto i = _classes.Begin(); i.IsNotEnd(); ++i) + LOG(Info, "Class: {0}", String(i->Value->GetFullName())); +#endif + + _hasCachedClasses = true; + return _classes; +} + +bool MAssembly::Load(MonoImage* monoImage) +{ + if (IsLoaded()) + return false; + PROFILE_CPU(); +#if TRACY_ENABLE + const StringAnsiView monoImageName(mono_image_get_name(monoImage)); + ZoneText(*monoImageName, monoImageName.Length()); +#endif + + // Ensure to be unloaded + Unload(); + + // Start + const auto startTime = DateTime::NowUTC(); + OnLoading(); + + // Load + _monoAssembly = mono_image_get_assembly(monoImage); + if (_monoAssembly == nullptr) + { + OnLoadFailed(); + return true; + } + _monoImage = monoImage; + _hasCachedClasses = false; + + // End + OnLoaded(startTime); + return false; +} + +bool MAssembly::LoadCorlib() +{ + return Load(mono_get_corlib()); +} + +bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePath) +{ + // Load assembly file data + Array data; + File::ReadAllBytes(assemblyPath, data); + + // Init Mono image + MonoImageOpenStatus status; + const auto name = assemblyPath.ToStringAnsi(); + const auto assemblyImage = mono_image_open_from_data_with_name(reinterpret_cast(data.Get()), data.Count(), true, &status, false, name.Get()); + if (status != MONO_IMAGE_OK || assemblyImage == nullptr) + { + Log::CLRInnerException(TEXT("Mono assembly image is invalid at ") + assemblyPath); + return true; + } + + // Setup assembly + const auto assembly = mono_assembly_load_from_full(assemblyImage, name.Substring(0, name.Length() - 3).Get(), &status, false); + mono_image_close(assemblyImage); + if (status != MONO_IMAGE_OK || assembly == nullptr) + { + Log::CLRInnerException(TEXT("Mono assembly image is corrupted at ") + assemblyPath); + return true; + } + +#if MONO_DEBUG_ENABLE + // Try to load debug symbols (use portable PDB format) + const auto pdbPath = String(StringUtils::GetPathWithoutExtension(assemblyPath)) + TEXT(".pdb"); + if (FileSystem::FileExists(pdbPath)) + { + // Load .pdb file + File::ReadAllBytes(pdbPath, _debugData); + + // Attach debugging symbols to image + if (_debugData.HasItems()) + { + mono_debug_open_image_from_memory(assemblyImage, _debugData.Get(), _debugData.Count()); + } + } + + // TODO: load pdbs for custom third-party libs referenced by game assemblies for debugging +#if 0 + // Hack to load debug information for Newtonsoft.Json (enable it to debug C# code of json lib) + if (assemblyPath.EndsWith(TEXT("FlaxEngine.CSharp.dll"))) + { + static Array NewtonsoftJsonDebugData; + File::ReadAllBytes(String(StringUtils::GetDirectoryName(assemblyPath)) / TEXT("Newtonsoft.Json.pdb"), NewtonsoftJsonDebugData); + if (NewtonsoftJsonDebugData.HasItems()) + { + StringAnsi tmp(String(StringUtils::GetDirectoryName(assemblyPath)) / TEXT("Newtonsoft.Json.dll")); + MonoAssembly* a = mono_assembly_open(tmp.Get(), &status); + if (a) + { + mono_debug_open_image_from_memory(mono_assembly_get_image(a), NewtonsoftJsonDebugData.Get(), NewtonsoftJsonDebugData.Count()); + } + } + } +#endif +#endif + + _monoAssembly = assembly; + _monoImage = assemblyImage; + _hasCachedClasses = false; + _assemblyPath = assemblyPath; + return false; +} + +bool MAssembly::UnloadImage(bool isReloading) +{ + if (_monoImage) + { + if (isReloading) + { + LOG(Info, "Unloading managed assembly \'{0}\' (is reloading)", String(_name)); + + mono_assembly_close(_monoAssembly); + } + else + { + // NOTE: do not try to close all the opened images + // that will cause the domain unload to crash because + // the images have already been closed (double free) + } + + _monoAssembly = nullptr; + _monoImage = nullptr; + } + return false; +} + +MClass::MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const StringAnsi& fullname) + : _assembly(parentAssembly) + , _fullname(fullname) + , _hasCachedProperties(false) + , _hasCachedFields(false) + , _hasCachedMethods(false) + , _hasCachedAttributes(false) + , _hasCachedEvents(false) + , _hasCachedInterfaces(false) +{ + _monoClass = monoClass; + ASSERT(monoClass); + + const uint32_t flags = mono_class_get_flags(monoClass); + + switch (flags & MONO_TYPE_ATTR_VISIBILITY_MASK) + { + case MONO_TYPE_ATTR_NOT_PUBLIC: + case MONO_TYPE_ATTR_NESTED_PRIVATE: + _visibility = MVisibility::Private; + break; + case MONO_TYPE_ATTR_PUBLIC: + case MONO_TYPE_ATTR_NESTED_PUBLIC: + _visibility = MVisibility::Public; + break; + case MONO_TYPE_ATTR_NESTED_FAMILY: + case MONO_TYPE_ATTR_NESTED_ASSEMBLY: + _visibility = MVisibility::Internal; + break; + case MONO_TYPE_ATTR_NESTED_FAM_OR_ASSEM: + _visibility = MVisibility::ProtectedInternal; + break; + case MONO_TYPE_ATTR_NESTED_FAM_AND_ASSEM: + _visibility = MVisibility::PrivateProtected; + break; + default: + CRASH; + } + + const uint32_t staticClassFlags = MONO_TYPE_ATTR_ABSTRACT | MONO_TYPE_ATTR_SEALED; + _isStatic = (flags & staticClassFlags) == staticClassFlags; + _isSealed = !_isStatic && (flags & MONO_TYPE_ATTR_SEALED) == MONO_TYPE_ATTR_SEALED; + _isAbstract = !_isStatic && (flags & MONO_TYPE_ATTR_ABSTRACT) == MONO_TYPE_ATTR_ABSTRACT; + _isInterface = (flags & MONO_TYPE_ATTR_CLASS_SEMANTIC_MASK) == MONO_TYPE_ATTR_INTERFACE; + _isValueType = mono_class_is_valuetype(monoClass); + _isEnum = mono_class_is_enum(monoClass); +} + +MClass::~MClass() +{ + if (_attrInfo) + mono_custom_attrs_free((MonoCustomAttrInfo*)_attrInfo); + _fields.ClearDelete(); + _properties.ClearDelete(); + _methods.ClearDelete(); + _attributes.ClearDelete(); + _events.ClearDelete(); +} + +StringAnsiView MClass::GetName() const +{ + return StringAnsiView(mono_class_get_name(_monoClass)); +} + +StringAnsiView MClass::GetNamespace() const +{ + return StringAnsiView(mono_class_get_namespace(_monoClass)); +} + +MType* MClass::GetType() const +{ + return mono_class_get_type(_monoClass); +} + +MClass* MClass::GetBaseClass() const +{ + MonoClass* monoBase = mono_class_get_parent(_monoClass); + if (monoBase == nullptr) + return nullptr; + return FindClass(monoBase); +} + +bool MClass::IsSubClassOf(const MClass* klass, bool checkInterfaces) const +{ + return klass && mono_class_is_subclass_of(_monoClass, klass->GetNative(), checkInterfaces) != 0; +} + +bool MClass::HasInterface(const MClass* klass) const +{ + return klass && mono_class_is_assignable_from(klass->GetNative(), _monoClass) != 0; +} + +bool MClass::IsInstanceOfType(MObject* object) const +{ + if (object == nullptr) + return false; + MonoClass* monoClass = mono_object_get_class(object); + return mono_class_is_subclass_of(monoClass, _monoClass, false) != 0; +} + +uint32 MClass::GetInstanceSize() const +{ + uint32 align = 0; + if (IsValueType()) + return mono_class_value_size(_monoClass, &align); + return mono_class_instance_size(_monoClass); +} + +MClass* MClass::GetElementClass() const +{ + MonoClass* monoClass = mono_class_get_element_class(_monoClass); + return FindClass(monoClass); +} + +MMethod* MClass::GetMethod(const char* name, int32 numParams) const +{ + // Lookup for cached method + for (int32 i = 0; i < _methods.Count(); i++) + { + if (_methods[i]->GetName() == name && _methods[i]->GetParametersCount() == numParams) + return _methods[i]; + } + + // Find Mono method + MonoMethod* monoMethod = mono_class_get_method_from_name(_monoClass, name, numParams); + if (monoMethod == nullptr) + return nullptr; + + // Create method + auto method = New(monoMethod, name, (MClass*)this); + _methods.Add(method); + return method; +} + +const Array& MClass::GetMethods() const +{ + if (_hasCachedMethods) + return _methods; + + void* iter = nullptr; + MonoMethod* curClassMethod; + while ((curClassMethod = mono_class_get_methods(_monoClass, &iter))) + { + // Check if has not been added + bool isMissing = true; + for (int32 i = 0; i < _methods.Count(); i++) + { + if (_methods[i]->GetNative() == curClassMethod) + { + isMissing = false; + break; + } + } + + if (isMissing) + { + // Create method + auto method = New(curClassMethod, (MClass*)this); + _methods.Add(method); + } + } + + _hasCachedMethods = true; + return _methods; +} + +MField* MClass::GetField(const char* name) const +{ + // Lookup for cached field + for (int32 i = 0; i < _fields.Count(); i++) + { + if (_fields[i]->GetName() == name) + return _fields[i]; + } + + // Find mono field + MonoClassField* field = mono_class_get_field_from_name(_monoClass, name); + if (field == nullptr) + return nullptr; + + // Create field + auto mfield = New(field, name, (MClass*)this); + _fields.Add(mfield); + return mfield; +} + +const Array& MClass::GetFields() const +{ + if (_hasCachedFields) + return _fields; + + void* iter = nullptr; + MonoClassField* curClassField; + while ((curClassField = mono_class_get_fields(_monoClass, &iter))) + { + const char* fieldName = mono_field_get_name(curClassField); + GetField(fieldName); + } + + _hasCachedFields = true; + return _fields; +} + +const Array& MClass::GetEvents() const +{ + if (_hasCachedEvents) + return _events; + + void* iter = nullptr; + MonoEvent* curEvent; + while ((curEvent = mono_class_get_events(_monoClass, &iter))) + { + const char* name = mono_event_get_name(curEvent); + bool missing = true; + for (int32 i = 0; i < _events.Count(); i++) + { + if (_events[i]->GetName() == name) + { + missing = false; + break; + } + } + if (missing) + { + auto result = New(curEvent, name, (MClass*)this); + _events.Add(result); + } + } + + _hasCachedEvents = true; + return _events; +} + +MProperty* MClass::GetProperty(const char* name) const +{ + // Lookup for cached property + for (int32 i = 0; i < _properties.Count(); i++) + { + if (_properties[i]->GetName() == name) + return _properties[i]; + } + + // Find mono property + MonoProperty* monoProperty = mono_class_get_property_from_name(_monoClass, name); + if (monoProperty == nullptr) + return nullptr; + + // Create method + auto mproperty = New(monoProperty, name, (MClass*)this); + _properties.Add(mproperty); + + return mproperty; +} + +class PhysicsColliderActorInternal +{ +public: + void CollisionEnter_ManagedWrapper(const int32& arg0) + { + MMethod* mmethod = nullptr; + CHECK(mmethod); + PROFILE_CPU_NAMED("FlaxEngine.PhysicsColliderActor::OnCollisionEnter"); + MonoObject* exception = nullptr; + void* params[1]; + MonoObject* instance; + mono_runtime_invoke(mmethod->GetNative(), instance, params, &exception); + mmethod->Invoke(instance, params, &exception); + } +}; + +const Array& MClass::GetProperties() const +{ + if (_hasCachedProperties) + return _properties; + + void* iter = nullptr; + MonoProperty* curClassProperty; + while ((curClassProperty = mono_class_get_properties(_monoClass, &iter))) + { + const char* propertyName = mono_property_get_name(curClassProperty); + GetProperty(propertyName); + } + + _hasCachedProperties = true; + return _properties; +} + +const Array& MClass::GetInterfaces() const +{ + if (_hasCachedInterfaces) + return _interfaces; + + void* iter = nullptr; + MonoClass* curInterface; + while ((curInterface = mono_class_get_interfaces(_monoClass, &iter))) + { + _interfaces.Add(FindClass(curInterface)); + } + + _hasCachedInterfaces = true; + return _interfaces; +} + +bool MClass::HasAttribute(const MClass* monoClass) const +{ + MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); + return attrInfo != nullptr && mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; +} + +bool MClass::HasAttribute() const +{ + MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); + return attrInfo && attrInfo->num_attrs > 0; +} + +MObject* MClass::GetAttribute(const MClass* monoClass) const +{ + MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); + return attrInfo ? mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()) : nullptr; +} + +const Array& MClass::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR(); + if (attrInfo == nullptr) + return _attributes; + + MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); + const uint32 length = (uint32)mono_array_length(monoAttributesArray); + _attributes.Resize(length); + for (uint32 i = 0; i < length; i++) + _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); + mono_custom_attrs_free(attrInfo); + return _attributes; +} + +bool MDomain::SetCurrentDomain(bool force) +{ + if (mono_domain_set(_monoDomain, force) == 0) + return false; + MActiveDomain = this; + return true; +} + +void MDomain::Dispatch() const +{ + if (!IsInMainThread()) + { + mono_thread_attach(_monoDomain); + } +} + +MEvent::MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass) + : _monoEvent(monoEvent) + , _addMethod(nullptr) + , _removeMethod(nullptr) + , _parentClass(parentClass) + , _name(name) + , _hasCachedAttributes(false) + , _hasAddMonoMethod(true) + , _hasRemoveMonoMethod(true) +{ +#if BUILD_DEBUG + // Validate input name + ASSERT(StringUtils::Compare(name, mono_event_get_name(monoEvent)) == 0); +#endif +} + +MMethod* MEvent::GetAddMethod() const +{ + if (!_hasAddMonoMethod) + return nullptr; + if (_addMethod == nullptr) + { + MonoMethod* addMonoMethod = mono_event_get_add_method(_monoEvent); + if (addMonoMethod != nullptr) + { + _hasAddMonoMethod = true; + return _addMethod = New(addMonoMethod, (MClass*)_parentClass); + } + } + return _addMethod; +} + +MMethod* MEvent::GetRemoveMethod() const +{ + if (!_hasRemoveMonoMethod) + return nullptr; + if (_removeMethod == nullptr) + { + MonoMethod* removeMonoMethod = mono_event_get_remove_method(_monoEvent); + if (removeMonoMethod) + { + _hasRemoveMonoMethod = true; + return _removeMethod = New(removeMonoMethod, (MClass*)_parentClass); + } + } + return _removeMethod; +} + +bool MEvent::HasAttribute(MClass* monoClass) const +{ + MonoClass* parentClass = mono_event_get_parent(_monoEvent); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); + if (attrInfo == nullptr) + return false; + + const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; + mono_custom_attrs_free(attrInfo); + return hasAttr; +} + +bool MEvent::HasAttribute() const +{ + MonoClass* parentClass = mono_event_get_parent(_monoEvent); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); + if (attrInfo == nullptr) + return false; + + if (attrInfo->num_attrs > 0) + { + mono_custom_attrs_free(attrInfo); + return true; + } + mono_custom_attrs_free(attrInfo); + return false; +} + +MObject* MEvent::GetAttribute(MClass* monoClass) const +{ + MonoClass* parentClass = mono_event_get_parent(_monoEvent); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); + if (attrInfo == nullptr) + return nullptr; + + MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); + mono_custom_attrs_free(attrInfo); + return foundAttr; +} + +const Array& MEvent::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + MonoClass* parentClass = mono_event_get_parent(_monoEvent); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent); + if (attrInfo == nullptr) + return _attributes; + + MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); + const uint32 length = (uint32)mono_array_length(monoAttributesArray); + _attributes.Resize(length); + for (uint32 i = 0; i < length; i++) + _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); + mono_custom_attrs_free(attrInfo); + return _attributes; +} + +MException::MException(MObject* exception) + : InnerException(nullptr) +{ + ASSERT(exception); + + MonoClass* exceptionClass = mono_object_get_class(exception); + MonoProperty* exceptionMsgProp = mono_class_get_property_from_name(exceptionClass, "Message"); + MonoMethod* exceptionMsgGetter = mono_property_get_get_method(exceptionMsgProp); + MonoString* exceptionMsg = (MonoString*)mono_runtime_invoke(exceptionMsgGetter, exception, nullptr, nullptr); + Message = MUtils::ToString(exceptionMsg); + + MonoProperty* exceptionStackProp = mono_class_get_property_from_name(exceptionClass, "StackTrace"); + MonoMethod* exceptionStackGetter = mono_property_get_get_method(exceptionStackProp); + MonoString* exceptionStackTrace = (MonoString*)mono_runtime_invoke(exceptionStackGetter, exception, nullptr, nullptr); + StackTrace = MUtils::ToString(exceptionStackTrace); + + MonoProperty* innerExceptionProp = mono_class_get_property_from_name(exceptionClass, "InnerException"); + MonoMethod* innerExceptionGetter = mono_property_get_get_method(innerExceptionProp); + MonoObject* innerException = (MonoObject*)mono_runtime_invoke(innerExceptionGetter, exception, nullptr, nullptr); + if (innerException) + InnerException = New(innerException); +} + +MException::~MException() +{ + if (InnerException) + Delete(InnerException); +} + +MField::MField(MonoClassField* monoField, const char* name, MClass* parentClass) + : _monoField(monoField) + , _monoType(mono_field_get_type(monoField)) + , _parentClass(parentClass) + , _name(name) + , _hasCachedAttributes(false) +{ +#if BUILD_DEBUG + // Validate input name + ASSERT(StringUtils::Compare(name, mono_field_get_name(monoField)) == 0); +#endif + + const uint32_t flags = mono_field_get_flags(monoField); + switch (flags & MONO_FIELD_ATTR_FIELD_ACCESS_MASK) + { + case MONO_FIELD_ATTR_PRIVATE: + _visibility = MVisibility::Private; + break; + case MONO_FIELD_ATTR_FAM_AND_ASSEM: + _visibility = MVisibility::PrivateProtected; + break; + case MONO_FIELD_ATTR_ASSEMBLY: + _visibility = MVisibility::Internal; + break; + case MONO_FIELD_ATTR_FAMILY: + _visibility = MVisibility::Protected; + break; + case MONO_FIELD_ATTR_FAM_OR_ASSEM: + _visibility = MVisibility::ProtectedInternal; + break; + case MONO_FIELD_ATTR_PUBLIC: + _visibility = MVisibility::Public; + break; + default: + CRASH; + } + _isStatic = (flags & MONO_FIELD_ATTR_STATIC) != 0; +} + +MType* MField::GetType() const +{ + return _monoType; +} + +int32 MField::GetOffset() const +{ + return (int32)(mono_field_get_offset(_monoField) - sizeof(MonoObject)); +} + +void MField::GetValue(MObject* instance, void* result) const +{ + mono_field_get_value(instance, _monoField, result); +} + +MObject* MField::GetValueBoxed(MObject* instance) const +{ + return mono_field_get_value_object(mono_domain_get(), _monoField, instance); +} + +void MField::SetValue(MObject* instance, void* value) const +{ + mono_field_set_value(instance, _monoField, value); +} + +bool MField::HasAttribute(MClass* monoClass) const +{ + MonoClass* parentClass = mono_field_get_parent(_monoField); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); + if (attrInfo == nullptr) + return false; + + const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; + mono_custom_attrs_free(attrInfo); + return hasAttr; +} + +bool MField::HasAttribute() const +{ + MonoClass* parentClass = mono_field_get_parent(_monoField); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); + if (attrInfo == nullptr) + return false; + + if (attrInfo->num_attrs > 0) + { + mono_custom_attrs_free(attrInfo); + return true; + } + mono_custom_attrs_free(attrInfo); + return false; +} + +MObject* MField::GetAttribute(MClass* monoClass) const +{ + MonoClass* parentClass = mono_field_get_parent(_monoField); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); + if (attrInfo == nullptr) + return nullptr; + + MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); + mono_custom_attrs_free(attrInfo); + return foundAttr; +} + +const Array& MField::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + MonoClass* parentClass = mono_field_get_parent(_monoField); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField); + if (attrInfo == nullptr) + return _attributes; + + MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); + const uint32 length = (uint32)mono_array_length(monoAttributesArray); + _attributes.Resize(length); + for (uint32 i = 0; i < length; i++) + _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); + mono_custom_attrs_free(attrInfo); + return _attributes; +} + +MMethod::MMethod(MonoMethod* monoMethod, MClass* parentClass) + : MMethod(monoMethod, mono_method_get_name(monoMethod), parentClass) +{ +} + +MMethod::MMethod(MonoMethod* monoMethod, const char* name, MClass* parentClass) + : _monoMethod(monoMethod) + , _parentClass(parentClass) + , _name(name) + , _hasCachedAttributes(false) +{ +#if BUILD_DEBUG + // Validate input name + ASSERT(StringUtils::Compare(name, mono_method_get_name(monoMethod)) == 0); +#endif + + const uint32_t flags = mono_method_get_flags(monoMethod, nullptr); + _isStatic = (flags & MONO_METHOD_ATTR_STATIC) != 0; + switch (flags & MONO_METHOD_ATTR_ACCESS_MASK) + { + case MONO_METHOD_ATTR_PRIVATE: + _visibility = MVisibility::Private; + break; + case MONO_METHOD_ATTR_FAM_AND_ASSEM: + _visibility = MVisibility::PrivateProtected; + break; + case MONO_METHOD_ATTR_ASSEM: + _visibility = MVisibility::Internal; + break; + case MONO_METHOD_ATTR_FAMILY: + _visibility = MVisibility::Protected; + break; + case MONO_METHOD_ATTR_FAM_OR_ASSEM: + _visibility = MVisibility::ProtectedInternal; + break; + case MONO_METHOD_ATTR_PUBLIC: + _visibility = MVisibility::Public; + break; + default: + CRASH; + } + +#if COMPILE_WITH_PROFILER + const StringAnsi& className = parentClass->GetFullName(); + ProfilerName.Resize(className.Length() + 2 + _name.Length()); + Platform::MemoryCopy(ProfilerName.Get(), className.Get(), className.Length()); + ProfilerName.Get()[className.Length()] = ':'; + ProfilerName.Get()[className.Length() + 1] = ':'; + Platform::MemoryCopy(ProfilerName.Get() + className.Length() + 2, _name.Get(), _name.Length()); + ProfilerData.name = ProfilerName.Get(); + ProfilerData.function = _name.Get(); + ProfilerData.file = nullptr; + ProfilerData.line = 0; + ProfilerData.color = 0; +#endif +} + +MObject* MMethod::Invoke(void* instance, void** params, MObject** exception) const +{ + PROFILE_CPU_SRC_LOC(ProfilerData); + return mono_runtime_invoke(_monoMethod, instance, params, exception); +} + +MObject* MMethod::InvokeVirtual(MObject* instance, void** params, MObject** exception) const +{ + PROFILE_CPU_SRC_LOC(ProfilerData); + MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, _monoMethod); + return mono_runtime_invoke(virtualMethod, instance, params, exception); +} + +#if !USE_MONO_AOT + +void* MMethod::GetThunk() +{ + if (!_cachedThunk) + _cachedThunk = mono_method_get_unmanaged_thunk(_monoMethod); + return _cachedThunk; +} + +#endif + +MMethod* MMethod::InflateGeneric() const +{ + MonoMethod* inflatedMethod = mono_class_inflate_generic_method(_monoMethod, nullptr); + // TODO: don't leak created method + return New(inflatedMethod, _parentClass); +} + +MType* MMethod::GetReturnType() const +{ + MonoMethodSignature* sig = mono_method_signature(_monoMethod); + return mono_signature_get_return_type(sig); +} + +int32 MMethod::GetParametersCount() const +{ + MonoMethodSignature* sig = mono_method_signature(_monoMethod); + return (int32)mono_signature_get_param_count(sig); +} + +MType* MMethod::GetParameterType(int32 paramIdx) const +{ + MonoMethodSignature* sig = mono_method_signature(_monoMethod); + ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig)); + void* it = nullptr; + mono_signature_get_params(sig, &it); + return ((MonoType**)it)[paramIdx]; +} + +bool MMethod::GetParameterIsOut(int32 paramIdx) const +{ + MonoMethodSignature* sig = mono_method_signature(_monoMethod); + ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig)); + return mono_signature_param_is_out(sig, paramIdx) != 0; +} + +bool MMethod::HasAttribute(MClass* monoClass) const +{ + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); + if (attrInfo == nullptr) + return false; + + const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; + mono_custom_attrs_free(attrInfo); + return hasAttr; +} + +bool MMethod::HasAttribute() const +{ + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); + if (attrInfo == nullptr) + return false; + + if (attrInfo->num_attrs > 0) + { + mono_custom_attrs_free(attrInfo); + return true; + } + mono_custom_attrs_free(attrInfo); + return false; +} + +MObject* MMethod::GetAttribute(MClass* monoClass) const +{ + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); + if (attrInfo == nullptr) + return nullptr; + + MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); + mono_custom_attrs_free(attrInfo); + return foundAttr; +} + +const Array& MMethod::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod); + if (attrInfo == nullptr) + return _attributes; + + MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); + const uint32 length = (uint32)mono_array_length(monoAttributesArray); + _attributes.Resize(length); + for (uint32 i = 0; i < length; i++) + _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); + mono_custom_attrs_free(attrInfo); + return _attributes; +} + +MProperty::MProperty(MonoProperty* monoProperty, const char* name, MClass* parentClass) + : _monoProperty(monoProperty) + , _getMethod(nullptr) + , _setMethod(nullptr) + , _parentClass(parentClass) + , _name(name) + , _hasCachedAttributes(false) + , _hasSetMethod(true) + , _hasGetMethod(true) +{ +#if BUILD_DEBUG + // Validate input name + ASSERT(StringUtils::Compare(name, mono_property_get_name(monoProperty)) == 0); +#endif + + GetGetMethod(); + GetSetMethod(); +} + +MProperty::~MProperty() +{ + if (_getMethod) + Delete(_getMethod); + if (_setMethod) + Delete(_setMethod); +} + +MMethod* MProperty::GetGetMethod() const +{ + if (!_hasGetMethod) + return nullptr; + if (_getMethod == nullptr) + { + MonoMethod* method = mono_property_get_get_method(_monoProperty); + if (method != nullptr) + { + _hasGetMethod = true; + return _getMethod = New(method, (MClass*)_parentClass); + } + } + return _getMethod; +} + +MMethod* MProperty::GetSetMethod() const +{ + if (!_hasSetMethod) + return nullptr; + if (_setMethod == nullptr) + { + MonoMethod* method = mono_property_get_set_method(_monoProperty); + if (method != nullptr) + { + _hasSetMethod = true; + return _setMethod = New(method, (MClass*)_parentClass); + } + } + return _setMethod; +} + +MObject* MProperty::GetValue(MObject* instance, MObject** exception) const +{ + return mono_property_get_value(_monoProperty, instance, nullptr, exception); +} + +void MProperty::SetValue(MObject* instance, void* value, MObject** exception) const +{ + void* params[1]; + params[0] = value; + mono_property_set_value(_monoProperty, instance, params, exception); +} + +bool MProperty::HasAttribute(MClass* monoClass) const +{ + MonoClass* parentClass = mono_property_get_parent(_monoProperty); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); + if (attrInfo == nullptr) + return false; + + const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0; + mono_custom_attrs_free(attrInfo); + return hasAttr; +} + +bool MProperty::HasAttribute() const +{ + MonoClass* parentClass = mono_property_get_parent(_monoProperty); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); + if (attrInfo == nullptr) + return false; + + if (attrInfo->num_attrs > 0) + { + mono_custom_attrs_free(attrInfo); + return true; + } + mono_custom_attrs_free(attrInfo); + return false; +} + +MObject* MProperty::GetAttribute(MClass* monoClass) const +{ + MonoClass* parentClass = mono_property_get_parent(_monoProperty); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); + if (attrInfo == nullptr) + return nullptr; + + MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()); + mono_custom_attrs_free(attrInfo); + return foundAttr; +} + +const Array& MProperty::GetAttributes() const +{ + if (_hasCachedAttributes) + return _attributes; + _hasCachedAttributes = true; + + MonoClass* parentClass = mono_property_get_parent(_monoProperty); + MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty); + if (attrInfo == nullptr) + return _attributes; + + MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo); + const uint32 length = (uint32)mono_array_length(monoAttributesArray); + _attributes.Resize(length); + for (uint32 i = 0; i < length; i++) + _attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i); + mono_custom_attrs_free(attrInfo); + return _attributes; +} + +#endif + +#if USE_MONO && PLATFORM_WIN32 && !USE_MONO_DYNAMIC_LIB + +// Export Mono functions +#pragma comment(linker, "/export:mono_add_internal_call") +#pragma comment(linker, "/export:mono_array_addr_with_size") +#pragma comment(linker, "/export:mono_array_calc_byte_len") +#pragma comment(linker, "/export:mono_array_class_get") +#pragma comment(linker, "/export:mono_array_clone") +#pragma comment(linker, "/export:mono_array_clone_checked") +#pragma comment(linker, "/export:mono_array_clone_in_domain") +#pragma comment(linker, "/export:mono_array_element_size") +#pragma comment(linker, "/export:mono_array_full_copy") +#pragma comment(linker, "/export:mono_array_handle_length") +#pragma comment(linker, "/export:mono_array_handle_memcpy_refs") +#pragma comment(linker, "/export:mono_array_handle_pin_with_size") +#pragma comment(linker, "/export:mono_array_length") +#pragma comment(linker, "/export:mono_array_new") +#pragma comment(linker, "/export:mono_array_new_1") +#pragma comment(linker, "/export:mono_array_new_2") +#pragma comment(linker, "/export:mono_array_new_3") +#pragma comment(linker, "/export:mono_array_new_4") +#pragma comment(linker, "/export:mono_array_new_checked") +#pragma comment(linker, "/export:mono_array_new_full") +#pragma comment(linker, "/export:mono_array_new_full_checked") +#pragma comment(linker, "/export:mono_array_new_full_handle") +#pragma comment(linker, "/export:mono_array_new_handle") +#pragma comment(linker, "/export:mono_array_new_specific") +#pragma comment(linker, "/export:mono_array_new_specific_checked") +#pragma comment(linker, "/export:mono_array_new_specific_handle") +#pragma comment(linker, "/export:mono_array_new_va") +#pragma comment(linker, "/export:mono_array_to_byte_byvalarray") +#pragma comment(linker, "/export:mono_array_to_lparray") +#pragma comment(linker, "/export:mono_array_to_savearray") +#pragma comment(linker, "/export:mono_assembly_addref") +#pragma comment(linker, "/export:mono_assembly_binding_applies_to_image") +#pragma comment(linker, "/export:mono_assembly_candidate_predicate_sn_same_name") +#pragma comment(linker, "/export:mono_assembly_cleanup_domain_bindings") +#pragma comment(linker, "/export:mono_assembly_close") +#pragma comment(linker, "/export:mono_assembly_close_except_image_pools") +#pragma comment(linker, "/export:mono_assembly_close_finish") +#pragma comment(linker, "/export:mono_assembly_fill_assembly_name") +#pragma comment(linker, "/export:mono_assembly_fill_assembly_name_full") +#pragma comment(linker, "/export:mono_assembly_foreach") +#pragma comment(linker, "/export:mono_assembly_get_assemblyref") +#pragma comment(linker, "/export:mono_assembly_get_assemblyref_checked") +#pragma comment(linker, "/export:mono_assembly_get_image") +#pragma comment(linker, "/export:mono_assembly_get_image_internal") +#pragma comment(linker, "/export:mono_assembly_get_main") +#pragma comment(linker, "/export:mono_assembly_get_name") +#pragma comment(linker, "/export:mono_assembly_get_name_internal") +#pragma comment(linker, "/export:mono_assembly_get_object") +#pragma comment(linker, "/export:mono_assembly_get_object_handle") +#pragma comment(linker, "/export:mono_assembly_getrootdir") +#pragma comment(linker, "/export:mono_assembly_has_reference_assembly_attribute") +#pragma comment(linker, "/export:mono_assembly_has_skip_verification") +#pragma comment(linker, "/export:mono_assembly_init_weak_fields") +#pragma comment(linker, "/export:mono_assembly_invoke_load_hook") +#pragma comment(linker, "/export:mono_assembly_invoke_search_hook") +#pragma comment(linker, "/export:mono_assembly_invoke_unload_hook") +#pragma comment(linker, "/export:mono_assembly_is_problematic_version") +#pragma comment(linker, "/export:mono_assembly_is_weak_field") +#pragma comment(linker, "/export:mono_assembly_load") +#pragma comment(linker, "/export:mono_assembly_load_corlib") +#pragma comment(linker, "/export:mono_assembly_load_friends") +#pragma comment(linker, "/export:mono_assembly_load_from") +#pragma comment(linker, "/export:mono_assembly_load_from_assemblies_path") +#pragma comment(linker, "/export:mono_assembly_load_from_full") +#pragma comment(linker, "/export:mono_assembly_load_from_predicate") +#pragma comment(linker, "/export:mono_assembly_load_full") +#pragma comment(linker, "/export:mono_assembly_load_full_nosearch") +#pragma comment(linker, "/export:mono_assembly_load_module") +#pragma comment(linker, "/export:mono_assembly_load_module_checked") +#pragma comment(linker, "/export:mono_assembly_load_reference") +#pragma comment(linker, "/export:mono_assembly_load_references") +#pragma comment(linker, "/export:mono_assembly_load_with_partial_name") +#pragma comment(linker, "/export:mono_assembly_load_with_partial_name_internal") +#pragma comment(linker, "/export:mono_assembly_loaded") +#pragma comment(linker, "/export:mono_assembly_loaded_full") +#pragma comment(linker, "/export:mono_assembly_metadata_foreach_custom_attr") +#pragma comment(linker, "/export:mono_assembly_name_free") +#pragma comment(linker, "/export:mono_assembly_name_free_internal") +#pragma comment(linker, "/export:mono_assembly_name_get_culture") +#pragma comment(linker, "/export:mono_assembly_name_get_name") +#pragma comment(linker, "/export:mono_assembly_name_get_pubkeytoken") +#pragma comment(linker, "/export:mono_assembly_name_get_version") +#pragma comment(linker, "/export:mono_assembly_name_new") +#pragma comment(linker, "/export:mono_assembly_name_parse") +#pragma comment(linker, "/export:mono_assembly_name_parse_full") +#pragma comment(linker, "/export:mono_assembly_names_equal") +#pragma comment(linker, "/export:mono_assembly_names_equal_flags") +#pragma comment(linker, "/export:mono_assembly_open") +#pragma comment(linker, "/export:mono_assembly_open_a_lot") +#pragma comment(linker, "/export:mono_assembly_open_from_bundle") +#pragma comment(linker, "/export:mono_assembly_open_full") +#pragma comment(linker, "/export:mono_assembly_open_predicate") +#pragma comment(linker, "/export:mono_assembly_release_gc_roots") +#pragma comment(linker, "/export:mono_assembly_set_main") +#pragma comment(linker, "/export:mono_assembly_setrootdir") +#pragma comment(linker, "/export:mono_class_alloc") +#pragma comment(linker, "/export:mono_class_alloc0") +#pragma comment(linker, "/export:mono_class_array_element_size") +#pragma comment(linker, "/export:mono_class_bind_generic_parameters") +#pragma comment(linker, "/export:mono_class_can_access_class") +#pragma comment(linker, "/export:mono_class_check_context_used") +#pragma comment(linker, "/export:mono_class_check_vtable_constraints") +#pragma comment(linker, "/export:mono_class_compute_bitmap") +#pragma comment(linker, "/export:mono_class_compute_gc_descriptor") +#pragma comment(linker, "/export:mono_class_contextbound_bit_offset") +#pragma comment(linker, "/export:mono_class_create_array") +#pragma comment(linker, "/export:mono_class_create_array_fill_type") +#pragma comment(linker, "/export:mono_class_create_bounded_array") +#pragma comment(linker, "/export:mono_class_create_fnptr") +#pragma comment(linker, "/export:mono_class_create_from_typedef") +#pragma comment(linker, "/export:mono_class_create_generic_inst") +#pragma comment(linker, "/export:mono_class_create_generic_parameter") +#pragma comment(linker, "/export:mono_class_create_ptr") +#pragma comment(linker, "/export:mono_class_data_size") +#pragma comment(linker, "/export:mono_class_describe_statics") +#pragma comment(linker, "/export:mono_class_enum_basetype") +#pragma comment(linker, "/export:mono_class_enum_basetype_internal") +#pragma comment(linker, "/export:mono_class_field_get_special_static_type") +#pragma comment(linker, "/export:mono_class_field_is_special_static") +#pragma comment(linker, "/export:mono_class_fill_runtime_generic_context") +#pragma comment(linker, "/export:mono_class_find_enum_basetype") +#pragma comment(linker, "/export:mono_class_free_ref_info") +#pragma comment(linker, "/export:mono_class_from_generic_parameter") +#pragma comment(linker, "/export:mono_class_from_mono_type") +#pragma comment(linker, "/export:mono_class_from_mono_type_handle") +#pragma comment(linker, "/export:mono_class_from_name") +#pragma comment(linker, "/export:mono_class_from_name_case") +#pragma comment(linker, "/export:mono_class_from_name_case_checked") +#pragma comment(linker, "/export:mono_class_from_name_checked") +#pragma comment(linker, "/export:mono_class_from_typeref") +#pragma comment(linker, "/export:mono_class_from_typeref_checked") +#pragma comment(linker, "/export:mono_class_full_name") +#pragma comment(linker, "/export:mono_class_generic_sharing_enabled") +#pragma comment(linker, "/export:mono_class_get") +#pragma comment(linker, "/export:mono_class_get_and_inflate_typespec_checked") +#pragma comment(linker, "/export:mono_class_get_appdomain_unloaded_exception_class") +#pragma comment(linker, "/export:mono_class_get_byref_type") +#pragma comment(linker, "/export:mono_class_get_cached_class_info") +#pragma comment(linker, "/export:mono_class_get_cctor") +#pragma comment(linker, "/export:mono_class_get_checked") +#pragma comment(linker, "/export:mono_class_get_com_object_class") +#pragma comment(linker, "/export:mono_class_get_context") +#pragma comment(linker, "/export:mono_class_get_declsec_flags") +#pragma comment(linker, "/export:mono_class_get_default_finalize_method") +#pragma comment(linker, "/export:mono_class_get_dim_conflicts") +#pragma comment(linker, "/export:mono_class_get_element_class") +#pragma comment(linker, "/export:mono_class_get_event_info") +#pragma comment(linker, "/export:mono_class_get_event_token") +#pragma comment(linker, "/export:mono_class_get_events") +#pragma comment(linker, "/export:mono_class_get_exception_data") +#pragma comment(linker, "/export:mono_class_get_exception_for_failure") +#pragma comment(linker, "/export:mono_class_get_field") +#pragma comment(linker, "/export:mono_class_get_field_count") +#pragma comment(linker, "/export:mono_class_get_field_def_values") +#pragma comment(linker, "/export:mono_class_get_field_default_value") +#pragma comment(linker, "/export:mono_class_get_field_from_name") +#pragma comment(linker, "/export:mono_class_get_field_from_name_full") +#pragma comment(linker, "/export:mono_class_get_field_token") +#pragma comment(linker, "/export:mono_class_get_fields") +#pragma comment(linker, "/export:mono_class_get_fields_internal") +#pragma comment(linker, "/export:mono_class_get_fields_lazy") +#pragma comment(linker, "/export:mono_class_get_finalizer") +#pragma comment(linker, "/export:mono_class_get_first_field_idx") +#pragma comment(linker, "/export:mono_class_get_first_method_idx") +#pragma comment(linker, "/export:mono_class_get_flags") +#pragma comment(linker, "/export:mono_class_get_full") +#pragma comment(linker, "/export:mono_class_get_generic_class") +#pragma comment(linker, "/export:mono_class_get_generic_container") +#pragma comment(linker, "/export:mono_class_get_generic_type_definition") +#pragma comment(linker, "/export:mono_class_get_idispatch_class") +#pragma comment(linker, "/export:mono_class_get_image") +#pragma comment(linker, "/export:mono_class_get_implemented_interfaces") +#pragma comment(linker, "/export:mono_class_get_inflated_method") +#pragma comment(linker, "/export:mono_class_get_interfaces") +#pragma comment(linker, "/export:mono_class_get_interop_proxy_class") +#pragma comment(linker, "/export:mono_class_get_iunknown_class") +#pragma comment(linker, "/export:mono_class_get_marshal_info") +#pragma comment(linker, "/export:mono_class_get_method_by_index") +#pragma comment(linker, "/export:mono_class_get_method_count") +#pragma comment(linker, "/export:mono_class_get_method_from_name") +#pragma comment(linker, "/export:mono_class_get_method_from_name_checked") +#pragma comment(linker, "/export:mono_class_get_method_from_name_flags") +#pragma comment(linker, "/export:mono_class_get_method_generic") +#pragma comment(linker, "/export:mono_class_get_methods") +#pragma comment(linker, "/export:mono_class_get_methods_by_name") +#pragma comment(linker, "/export:mono_class_get_name") +#pragma comment(linker, "/export:mono_class_get_namespace") +#pragma comment(linker, "/export:mono_class_get_nested_classes_property") +#pragma comment(linker, "/export:mono_class_get_nested_types") +#pragma comment(linker, "/export:mono_class_get_nesting_type") +#pragma comment(linker, "/export:mono_class_get_nullable_param") +#pragma comment(linker, "/export:mono_class_get_object_finalize_slot") +#pragma comment(linker, "/export:mono_class_get_overrides_full") +#pragma comment(linker, "/export:mono_class_get_parent") +#pragma comment(linker, "/export:mono_class_get_properties") +#pragma comment(linker, "/export:mono_class_get_property_default_value") +#pragma comment(linker, "/export:mono_class_get_property_from_name") +#pragma comment(linker, "/export:mono_class_get_property_info") +#pragma comment(linker, "/export:mono_class_get_property_token") +#pragma comment(linker, "/export:mono_class_get_rank") +#pragma comment(linker, "/export:mono_class_get_ref_info") +#pragma comment(linker, "/export:mono_class_get_ref_info_handle") +#pragma comment(linker, "/export:mono_class_get_ref_info_raw") +#pragma comment(linker, "/export:mono_class_get_type") +#pragma comment(linker, "/export:mono_class_get_type_token") +#pragma comment(linker, "/export:mono_class_get_valuetype_class") +#pragma comment(linker, "/export:mono_class_get_variant_class") +#pragma comment(linker, "/export:mono_class_get_virtual_method") +#pragma comment(linker, "/export:mono_class_get_vtable_entry") +#pragma comment(linker, "/export:mono_class_get_vtable_size") +#pragma comment(linker, "/export:mono_class_get_weak_bitmap") +#pragma comment(linker, "/export:mono_class_gtd_get_canonical_inst") +#pragma comment(linker, "/export:mono_class_has_dim_conflicts") +#pragma comment(linker, "/export:mono_class_has_failure") +#pragma comment(linker, "/export:mono_class_has_finalizer") +#pragma comment(linker, "/export:mono_class_has_ref_info") +#pragma comment(linker, "/export:mono_class_has_special_static_fields") +#pragma comment(linker, "/export:mono_class_has_variant_generic_params") +#pragma comment(linker, "/export:mono_class_implements_interface") +#pragma comment(linker, "/export:mono_class_inflate_generic_class_checked") +#pragma comment(linker, "/export:mono_class_inflate_generic_method") +#pragma comment(linker, "/export:mono_class_inflate_generic_method_checked") +#pragma comment(linker, "/export:mono_class_inflate_generic_method_full_checked") +#pragma comment(linker, "/export:mono_class_inflate_generic_type") +#pragma comment(linker, "/export:mono_class_inflate_generic_type_checked") +#pragma comment(linker, "/export:mono_class_inflate_generic_type_with_mempool") +#pragma comment(linker, "/export:mono_class_init") +#pragma comment(linker, "/export:mono_class_init_checked") +#pragma comment(linker, "/export:mono_class_init_sizes") +#pragma comment(linker, "/export:mono_class_instance_size") +#pragma comment(linker, "/export:mono_class_interface_offset") +#pragma comment(linker, "/export:mono_class_interface_offset_with_variance") +#pragma comment(linker, "/export:mono_class_is_assignable_from") +#pragma comment(linker, "/export:mono_class_is_assignable_from_checked") +#pragma comment(linker, "/export:mono_class_is_assignable_from_internal") +#pragma comment(linker, "/export:mono_class_is_assignable_from_slow") +#pragma comment(linker, "/export:mono_class_is_delegate") +#pragma comment(linker, "/export:mono_class_is_enum") +#pragma comment(linker, "/export:mono_class_is_from_assembly") +#pragma comment(linker, "/export:mono_class_is_magic_float") +#pragma comment(linker, "/export:mono_class_is_magic_int") +#pragma comment(linker, "/export:mono_class_is_nullable") +#pragma comment(linker, "/export:mono_class_is_open_constructed_type") +#pragma comment(linker, "/export:mono_class_is_reflection_method_or_constructor") +#pragma comment(linker, "/export:mono_class_is_subclass_of") +#pragma comment(linker, "/export:mono_class_is_valid_enum") +#pragma comment(linker, "/export:mono_class_is_valuetype") +#pragma comment(linker, "/export:mono_class_is_variant_compatible") +#pragma comment(linker, "/export:mono_class_layout_fields") +#pragma comment(linker, "/export:mono_class_load_from_name") +#pragma comment(linker, "/export:mono_class_min_align") +#pragma comment(linker, "/export:mono_class_name_from_token") +#pragma comment(linker, "/export:mono_class_native_size") +#pragma comment(linker, "/export:mono_class_needs_cctor_run") +#pragma comment(linker, "/export:mono_class_num_events") +#pragma comment(linker, "/export:mono_class_num_fields") +#pragma comment(linker, "/export:mono_class_num_methods") +#pragma comment(linker, "/export:mono_class_num_properties") +#pragma comment(linker, "/export:mono_class_publish_gc_descriptor") +#pragma comment(linker, "/export:mono_class_rgctx_get_array_size") +#pragma comment(linker, "/export:mono_class_set_declsec_flags") +#pragma comment(linker, "/export:mono_class_set_dim_conflicts") +#pragma comment(linker, "/export:mono_class_set_event_info") +#pragma comment(linker, "/export:mono_class_set_exception_data") +#pragma comment(linker, "/export:mono_class_set_failure") +#pragma comment(linker, "/export:mono_class_set_field_count") +#pragma comment(linker, "/export:mono_class_set_field_def_values") +#pragma comment(linker, "/export:mono_class_set_first_field_idx") +#pragma comment(linker, "/export:mono_class_set_first_method_idx") +#pragma comment(linker, "/export:mono_class_set_flags") +#pragma comment(linker, "/export:mono_class_set_generic_container") +#pragma comment(linker, "/export:mono_class_set_is_com_object") +#pragma comment(linker, "/export:mono_class_set_marshal_info") +#pragma comment(linker, "/export:mono_class_set_method_count") +#pragma comment(linker, "/export:mono_class_set_nested_classes_property") +#pragma comment(linker, "/export:mono_class_set_nonblittable") +#pragma comment(linker, "/export:mono_class_set_property_info") +#pragma comment(linker, "/export:mono_class_set_ref_info") +#pragma comment(linker, "/export:mono_class_set_ref_info_handle") +#pragma comment(linker, "/export:mono_class_set_type_load_failure") +#pragma comment(linker, "/export:mono_class_set_type_load_failure_causedby_class") +#pragma comment(linker, "/export:mono_class_set_weak_bitmap") +#pragma comment(linker, "/export:mono_class_setup_basic_field_info") +#pragma comment(linker, "/export:mono_class_setup_events") +#pragma comment(linker, "/export:mono_class_setup_fields") +#pragma comment(linker, "/export:mono_class_setup_has_finalizer") +#pragma comment(linker, "/export:mono_class_setup_interface_id") +#pragma comment(linker, "/export:mono_class_setup_interface_offsets") +#pragma comment(linker, "/export:mono_class_setup_interfaces") +#pragma comment(linker, "/export:mono_class_setup_methods") +#pragma comment(linker, "/export:mono_class_setup_mono_type") +#pragma comment(linker, "/export:mono_class_setup_nested_types") +#pragma comment(linker, "/export:mono_class_setup_parent") +#pragma comment(linker, "/export:mono_class_setup_properties") +#pragma comment(linker, "/export:mono_class_setup_runtime_info") +#pragma comment(linker, "/export:mono_class_setup_supertypes") +#pragma comment(linker, "/export:mono_class_setup_vtable") +#pragma comment(linker, "/export:mono_class_setup_vtable_general") +#pragma comment(linker, "/export:mono_class_static_field_address") +#pragma comment(linker, "/export:mono_class_try_get_com_object_class") +#pragma comment(linker, "/export:mono_class_try_get_generic_class") +#pragma comment(linker, "/export:mono_class_try_get_generic_container") +#pragma comment(linker, "/export:mono_class_try_get_safehandle_class") +#pragma comment(linker, "/export:mono_class_try_get_vtable") +#pragma comment(linker, "/export:mono_class_try_load_from_name") +#pragma comment(linker, "/export:mono_class_value_size") +#pragma comment(linker, "/export:mono_class_vtable") +#pragma comment(linker, "/export:mono_class_vtable_checked") +#pragma comment(linker, "/export:mono_custom_attrs_construct") +#pragma comment(linker, "/export:mono_custom_attrs_free") +#pragma comment(linker, "/export:mono_custom_attrs_from_assembly") +#pragma comment(linker, "/export:mono_custom_attrs_from_assembly_checked") +#pragma comment(linker, "/export:mono_custom_attrs_from_builders") +#pragma comment(linker, "/export:mono_custom_attrs_from_class") +#pragma comment(linker, "/export:mono_custom_attrs_from_class_checked") +#pragma comment(linker, "/export:mono_custom_attrs_from_event") +#pragma comment(linker, "/export:mono_custom_attrs_from_event_checked") +#pragma comment(linker, "/export:mono_custom_attrs_from_field") +#pragma comment(linker, "/export:mono_custom_attrs_from_field_checked") +#pragma comment(linker, "/export:mono_custom_attrs_from_index") +#pragma comment(linker, "/export:mono_custom_attrs_from_index_checked") +#pragma comment(linker, "/export:mono_custom_attrs_from_method") +#pragma comment(linker, "/export:mono_custom_attrs_from_method_checked") +#pragma comment(linker, "/export:mono_custom_attrs_from_param") +#pragma comment(linker, "/export:mono_custom_attrs_from_param_checked") +#pragma comment(linker, "/export:mono_custom_attrs_from_property") +#pragma comment(linker, "/export:mono_custom_attrs_from_property_checked") +#pragma comment(linker, "/export:mono_custom_attrs_get_attr") +#pragma comment(linker, "/export:mono_custom_attrs_get_attr_checked") +#pragma comment(linker, "/export:mono_custom_attrs_has_attr") +#pragma comment(linker, "/export:mono_debug_add_aot_method") +#pragma comment(linker, "/export:mono_debug_add_delegate_trampoline") +#pragma comment(linker, "/export:mono_debug_add_method") +#pragma comment(linker, "/export:mono_debug_cleanup") +#pragma comment(linker, "/export:mono_debug_close_image") +#pragma comment(linker, "/export:mono_debug_close_method") +#pragma comment(linker, "/export:mono_debug_close_mono_symbol_file") +#pragma comment(linker, "/export:mono_debug_count") +#pragma comment(linker, "/export:mono_debug_domain_create") +#pragma comment(linker, "/export:mono_debug_domain_unload") +#pragma comment(linker, "/export:mono_debug_enabled") +#pragma comment(linker, "/export:mono_debug_find_method") +#pragma comment(linker, "/export:mono_debug_free_locals") +#pragma comment(linker, "/export:mono_debug_free_method") +#pragma comment(linker, "/export:mono_debug_free_method_async_debug_info") +#pragma comment(linker, "/export:mono_debug_free_method_jit_info") +#pragma comment(linker, "/export:mono_debug_free_source_location") +#pragma comment(linker, "/export:mono_debug_get_handle") +#pragma comment(linker, "/export:mono_debug_get_seq_points") +#pragma comment(linker, "/export:mono_debug_il_offset_from_address") +#pragma comment(linker, "/export:mono_debug_image_has_debug_info") +#pragma comment(linker, "/export:mono_debug_init") +#pragma comment(linker, "/export:mono_debug_init_method") +#pragma comment(linker, "/export:mono_debug_lookup_locals") +#pragma comment(linker, "/export:mono_debug_lookup_method") +#pragma comment(linker, "/export:mono_debug_lookup_method_addresses") +#pragma comment(linker, "/export:mono_debug_lookup_method_async_debug_info") +#pragma comment(linker, "/export:mono_debug_lookup_source_location") +#pragma comment(linker, "/export:mono_debug_lookup_source_location_by_il") +#pragma comment(linker, "/export:mono_debug_method_lookup_location") +#pragma comment(linker, "/export:mono_debug_open_block") +#pragma comment(linker, "/export:mono_debug_open_method") +#pragma comment(linker, "/export:mono_debug_open_mono_symbols") +#pragma comment(linker, "/export:mono_debug_personality") +#pragma comment(linker, "/export:mono_debug_print_stack_frame") +#pragma comment(linker, "/export:mono_debug_print_vars") +#pragma comment(linker, "/export:mono_debug_record_line_number") +#pragma comment(linker, "/export:mono_debug_remove_method") +#pragma comment(linker, "/export:mono_debug_serialize_debug_info") +#pragma comment(linker, "/export:mono_debug_symfile_free_location") +#pragma comment(linker, "/export:mono_debug_symfile_get_seq_points") +#pragma comment(linker, "/export:mono_debug_symfile_is_loaded") +#pragma comment(linker, "/export:mono_debug_symfile_lookup_locals") +#pragma comment(linker, "/export:mono_debug_symfile_lookup_location") +#pragma comment(linker, "/export:mono_debug_symfile_lookup_method") +#pragma comment(linker, "/export:mono_domain_alloc") +#pragma comment(linker, "/export:mono_domain_alloc0") +#pragma comment(linker, "/export:mono_domain_alloc0_lock_free") +#pragma comment(linker, "/export:mono_domain_assembly_open") +#pragma comment(linker, "/export:mono_domain_assembly_open_internal") +#pragma comment(linker, "/export:mono_domain_assembly_postload_search") +#pragma comment(linker, "/export:mono_domain_code_commit") +#pragma comment(linker, "/export:mono_domain_code_foreach") +#pragma comment(linker, "/export:mono_domain_code_reserve") +#pragma comment(linker, "/export:mono_domain_code_reserve_align") +#pragma comment(linker, "/export:mono_domain_create") +#pragma comment(linker, "/export:mono_domain_create_appdomain") +#pragma comment(linker, "/export:mono_domain_finalize") +#pragma comment(linker, "/export:mono_domain_foreach") +#pragma comment(linker, "/export:mono_domain_free") +#pragma comment(linker, "/export:mono_domain_from_appdomain") +#pragma comment(linker, "/export:mono_domain_get") +#pragma comment(linker, "/export:mono_domain_get_assemblies") +#pragma comment(linker, "/export:mono_domain_get_by_id") +#pragma comment(linker, "/export:mono_domain_get_friendly_name") +#pragma comment(linker, "/export:mono_domain_get_id") +#pragma comment(linker, "/export:mono_domain_has_type_resolve") +#pragma comment(linker, "/export:mono_domain_is_unloading") +#pragma comment(linker, "/export:mono_domain_lock") +#pragma comment(linker, "/export:mono_domain_owns_vtable_slot") +#pragma comment(linker, "/export:mono_domain_parse_assembly_bindings") +#pragma comment(linker, "/export:mono_domain_set") +#pragma comment(linker, "/export:mono_domain_set_config") +#pragma comment(linker, "/export:mono_domain_set_config_checked") +#pragma comment(linker, "/export:mono_domain_set_internal") +#pragma comment(linker, "/export:mono_domain_set_internal_with_options") +#pragma comment(linker, "/export:mono_domain_set_options_from_config") +#pragma comment(linker, "/export:mono_domain_try_type_resolve") +#pragma comment(linker, "/export:mono_domain_try_type_resolve_name") +#pragma comment(linker, "/export:mono_domain_try_type_resolve_typebuilder") +#pragma comment(linker, "/export:mono_domain_try_unload") +#pragma comment(linker, "/export:mono_domain_unload") +#pragma comment(linker, "/export:mono_domain_unlock") +#pragma comment(linker, "/export:mono_domain_unset") +#pragma comment(linker, "/export:mono_exception_from_name") +#pragma comment(linker, "/export:mono_exception_from_name_domain") +#pragma comment(linker, "/export:mono_exception_from_name_msg") +#pragma comment(linker, "/export:mono_exception_from_name_two_strings") +#pragma comment(linker, "/export:mono_exception_from_name_two_strings_checked") +#pragma comment(linker, "/export:mono_exception_from_token") +#pragma comment(linker, "/export:mono_exception_from_token_two_strings") +#pragma comment(linker, "/export:mono_exception_from_token_two_strings_checked") +#pragma comment(linker, "/export:mono_exception_get_managed_backtrace") +#pragma comment(linker, "/export:mono_exception_handle_get_native_backtrace") +#pragma comment(linker, "/export:mono_exception_new_argument") +#pragma comment(linker, "/export:mono_exception_new_argument_null") +#pragma comment(linker, "/export:mono_exception_new_by_name_msg") +#pragma comment(linker, "/export:mono_exception_new_invalid_operation") +#pragma comment(linker, "/export:mono_exception_new_serialization") +#pragma comment(linker, "/export:mono_exception_new_thread_abort") +#pragma comment(linker, "/export:mono_exception_new_thread_interrupted") +#pragma comment(linker, "/export:mono_exception_walk_trace") +#pragma comment(linker, "/export:mono_field_from_token") +#pragma comment(linker, "/export:mono_field_from_token_checked") +#pragma comment(linker, "/export:mono_field_full_name") +#pragma comment(linker, "/export:mono_field_get_data") +#pragma comment(linker, "/export:mono_field_get_flags") +#pragma comment(linker, "/export:mono_field_get_name") +#pragma comment(linker, "/export:mono_field_get_object") +#pragma comment(linker, "/export:mono_field_get_object_checked") +#pragma comment(linker, "/export:mono_field_get_object_handle") +#pragma comment(linker, "/export:mono_field_get_offset") +#pragma comment(linker, "/export:mono_field_get_parent") +#pragma comment(linker, "/export:mono_field_get_type") +#pragma comment(linker, "/export:mono_field_get_type_checked") +#pragma comment(linker, "/export:mono_field_get_value") +#pragma comment(linker, "/export:mono_field_get_value_internal") +#pragma comment(linker, "/export:mono_field_get_value_object") +#pragma comment(linker, "/export:mono_field_get_value_object_checked") +#pragma comment(linker, "/export:mono_field_resolve_type") +#pragma comment(linker, "/export:mono_field_set_value") +#pragma comment(linker, "/export:mono_field_static_get_value") +#pragma comment(linker, "/export:mono_field_static_get_value_checked") +#pragma comment(linker, "/export:mono_field_static_get_value_for_thread") +#pragma comment(linker, "/export:mono_field_static_set_value") +#pragma comment(linker, "/export:mono_free") +#pragma comment(linker, "/export:mono_free_address_info") +#pragma comment(linker, "/export:mono_free_altstack") +#pragma comment(linker, "/export:mono_free_bstr") +#pragma comment(linker, "/export:mono_free_loop_info") +#pragma comment(linker, "/export:mono_free_lparray") +#pragma comment(linker, "/export:mono_free_method") +#pragma comment(linker, "/export:mono_free_verify_list") +#pragma comment(linker, "/export:mono_gc_add_memory_pressure") +#pragma comment(linker, "/export:mono_gc_alloc_array") +#pragma comment(linker, "/export:mono_gc_alloc_fixed") +#pragma comment(linker, "/export:mono_gc_alloc_fixed_no_descriptor") +#pragma comment(linker, "/export:mono_gc_alloc_handle_array") +#pragma comment(linker, "/export:mono_gc_alloc_handle_mature") +#pragma comment(linker, "/export:mono_gc_alloc_handle_obj") +#pragma comment(linker, "/export:mono_gc_alloc_handle_pinned_obj") +#pragma comment(linker, "/export:mono_gc_alloc_handle_string") +#pragma comment(linker, "/export:mono_gc_alloc_handle_vector") +#pragma comment(linker, "/export:mono_gc_alloc_mature") +#pragma comment(linker, "/export:mono_gc_alloc_obj") +#pragma comment(linker, "/export:mono_gc_alloc_pinned_obj") +#pragma comment(linker, "/export:mono_gc_alloc_string") +#pragma comment(linker, "/export:mono_gc_alloc_vector") +#pragma comment(linker, "/export:mono_gc_base_cleanup") +#pragma comment(linker, "/export:mono_gc_base_init") +#pragma comment(linker, "/export:mono_gc_bzero_aligned") +#pragma comment(linker, "/export:mono_gc_bzero_atomic") +#pragma comment(linker, "/export:mono_gc_card_table_nursery_check") +#pragma comment(linker, "/export:mono_gc_cleanup") +#pragma comment(linker, "/export:mono_gc_clear_assembly") +#pragma comment(linker, "/export:mono_gc_clear_domain") +#pragma comment(linker, "/export:mono_gc_collect") +#pragma comment(linker, "/export:mono_gc_collection_count") +#pragma comment(linker, "/export:mono_gc_conservatively_scan_area") +#pragma comment(linker, "/export:mono_gc_debug_set") +#pragma comment(linker, "/export:mono_gc_deregister_root") +#pragma comment(linker, "/export:mono_gc_dllmain") +#pragma comment(linker, "/export:mono_gc_ephemeron_array_add") +#pragma comment(linker, "/export:mono_gc_finalize_assembly") +#pragma comment(linker, "/export:mono_gc_finalize_domain") +#pragma comment(linker, "/export:mono_gc_finalize_notify") +#pragma comment(linker, "/export:mono_gc_free_fixed") +#pragma comment(linker, "/export:mono_gc_get_aligned_size_for_allocator") +#pragma comment(linker, "/export:mono_gc_get_bitmap_for_descr") +#pragma comment(linker, "/export:mono_gc_get_card_table") +#pragma comment(linker, "/export:mono_gc_get_description") +#pragma comment(linker, "/export:mono_gc_get_gc_callbacks") +#pragma comment(linker, "/export:mono_gc_get_gc_name") +#pragma comment(linker, "/export:mono_gc_get_generation") +#pragma comment(linker, "/export:mono_gc_get_heap_size") +#pragma comment(linker, "/export:mono_gc_get_logfile") +#pragma comment(linker, "/export:mono_gc_get_los_limit") +#pragma comment(linker, "/export:mono_gc_get_managed_allocator") +#pragma comment(linker, "/export:mono_gc_get_managed_allocator_by_type") +#pragma comment(linker, "/export:mono_gc_get_managed_allocator_types") +#pragma comment(linker, "/export:mono_gc_get_managed_array_allocator") +#pragma comment(linker, "/export:mono_gc_get_nursery") +#pragma comment(linker, "/export:mono_gc_get_range_copy_func") +#pragma comment(linker, "/export:mono_gc_get_restart_signal") +#pragma comment(linker, "/export:mono_gc_get_specific_write_barrier") +#pragma comment(linker, "/export:mono_gc_get_suspend_signal") +#pragma comment(linker, "/export:mono_gc_get_target_card_table") +#pragma comment(linker, "/export:mono_gc_get_used_size") +#pragma comment(linker, "/export:mono_gc_get_vtable") +#pragma comment(linker, "/export:mono_gc_get_vtable_bits") +#pragma comment(linker, "/export:mono_gc_get_write_barrier") +#pragma comment(linker, "/export:mono_gc_init") +#pragma comment(linker, "/export:mono_gc_invoke_finalizers") +#pragma comment(linker, "/export:mono_gc_invoke_with_gc_lock") +#pragma comment(linker, "/export:mono_gc_is_critical_method") +#pragma comment(linker, "/export:mono_gc_is_disabled") +#pragma comment(linker, "/export:mono_gc_is_finalizer_internal_thread") +#pragma comment(linker, "/export:mono_gc_is_finalizer_thread") +#pragma comment(linker, "/export:mono_gc_is_gc_thread") +#pragma comment(linker, "/export:mono_gc_is_moving") +#pragma comment(linker, "/export:mono_gc_is_null") +#pragma comment(linker, "/export:mono_gc_make_descr_for_array") +#pragma comment(linker, "/export:mono_gc_make_descr_for_object") +#pragma comment(linker, "/export:mono_gc_make_descr_for_string") +#pragma comment(linker, "/export:mono_gc_make_descr_from_bitmap") +#pragma comment(linker, "/export:mono_gc_make_root_descr_all_refs") +#pragma comment(linker, "/export:mono_gc_make_root_descr_user") +#pragma comment(linker, "/export:mono_gc_make_vector_descr") +#pragma comment(linker, "/export:mono_gc_max_generation") +#pragma comment(linker, "/export:mono_gc_memmove_aligned") +#pragma comment(linker, "/export:mono_gc_memmove_atomic") +#pragma comment(linker, "/export:mono_gc_params_set") +#pragma comment(linker, "/export:mono_gc_parse_environment_string_extract_number") +#pragma comment(linker, "/export:mono_gc_pending_finalizers") +#pragma comment(linker, "/export:mono_gc_precise_stack_mark_enabled") +#pragma comment(linker, "/export:mono_gc_reference_queue_add") +#pragma comment(linker, "/export:mono_gc_reference_queue_foreach_remove") +#pragma comment(linker, "/export:mono_gc_reference_queue_foreach_remove2") +#pragma comment(linker, "/export:mono_gc_reference_queue_free") +#pragma comment(linker, "/export:mono_gc_reference_queue_new") +#pragma comment(linker, "/export:mono_gc_register_altstack") +#pragma comment(linker, "/export:mono_gc_register_bridge_callbacks") +#pragma comment(linker, "/export:mono_gc_register_finalizer_callbacks") +#pragma comment(linker, "/export:mono_gc_register_for_finalization") +#pragma comment(linker, "/export:mono_gc_register_obj_with_weak_fields") +#pragma comment(linker, "/export:mono_gc_register_object_with_weak_fields") +#pragma comment(linker, "/export:mono_gc_register_root") +#pragma comment(linker, "/export:mono_gc_register_root_wbarrier") +#pragma comment(linker, "/export:mono_gc_run_finalize") +#pragma comment(linker, "/export:mono_gc_scan_for_specific_ref") +#pragma comment(linker, "/export:mono_gc_scan_object") +#pragma comment(linker, "/export:mono_gc_set_desktop_mode") +#pragma comment(linker, "/export:mono_gc_set_gc_callbacks") +#pragma comment(linker, "/export:mono_gc_set_stack_end") +#pragma comment(linker, "/export:mono_gc_set_string_length") +#pragma comment(linker, "/export:mono_gc_skip_thread_changed") +#pragma comment(linker, "/export:mono_gc_skip_thread_changing") +#pragma comment(linker, "/export:mono_gc_stats") +#pragma comment(linker, "/export:mono_gc_suspend_finalizers") +#pragma comment(linker, "/export:mono_gc_thread_attach") +#pragma comment(linker, "/export:mono_gc_thread_detach_with_lock") +#pragma comment(linker, "/export:mono_gc_thread_in_critical_region") +#pragma comment(linker, "/export:mono_gc_toggleref_add") +#pragma comment(linker, "/export:mono_gc_toggleref_register_callback") +#pragma comment(linker, "/export:mono_gc_user_markers_supported") +#pragma comment(linker, "/export:mono_gc_wait_for_bridge_processing") +#pragma comment(linker, "/export:mono_gc_walk_heap") +#pragma comment(linker, "/export:mono_gc_wbarrier_arrayref_copy") +#pragma comment(linker, "/export:mono_gc_wbarrier_generic_nostore") +#pragma comment(linker, "/export:mono_gc_wbarrier_generic_store") +#pragma comment(linker, "/export:mono_gc_wbarrier_generic_store_atomic") +#pragma comment(linker, "/export:mono_gc_wbarrier_object_copy") +#pragma comment(linker, "/export:mono_gc_wbarrier_object_copy_handle") +#pragma comment(linker, "/export:mono_gc_wbarrier_range_copy") +#pragma comment(linker, "/export:mono_gc_wbarrier_set_arrayref") +#pragma comment(linker, "/export:mono_gc_wbarrier_set_field") +#pragma comment(linker, "/export:mono_gc_wbarrier_value_copy") +#pragma comment(linker, "/export:mono_gchandle_free") +#pragma comment(linker, "/export:mono_gchandle_free_domain") +#pragma comment(linker, "/export:mono_gchandle_from_handle") +#pragma comment(linker, "/export:mono_gchandle_get_target") +#pragma comment(linker, "/export:mono_gchandle_get_target_handle") +#pragma comment(linker, "/export:mono_gchandle_is_in_domain") +#pragma comment(linker, "/export:mono_gchandle_new") +#pragma comment(linker, "/export:mono_gchandle_new_weakref") +#pragma comment(linker, "/export:mono_gchandle_set_target") +#pragma comment(linker, "/export:mono_gchandle_set_target_handle") +#pragma comment(linker, "/export:mono_get_addr_from_ftnptr") +#pragma comment(linker, "/export:mono_get_address_info") +#pragma comment(linker, "/export:mono_get_anonymous_container_for_image") +#pragma comment(linker, "/export:mono_get_aot_cache_config") +#pragma comment(linker, "/export:mono_get_array_class") +#pragma comment(linker, "/export:mono_get_assembly_object") +#pragma comment(linker, "/export:mono_get_boolean_class") +#pragma comment(linker, "/export:mono_get_byte_class") +#pragma comment(linker, "/export:mono_get_cached_unwind_info") +#pragma comment(linker, "/export:mono_get_call_filter") +#pragma comment(linker, "/export:mono_get_char_class") +#pragma comment(linker, "/export:mono_get_config_dir") +#pragma comment(linker, "/export:mono_get_constant_value_from_blob") +#pragma comment(linker, "/export:mono_get_context_capture_method") +#pragma comment(linker, "/export:mono_get_corlib") +#pragma comment(linker, "/export:mono_get_dbnull_object") +#pragma comment(linker, "/export:mono_get_delegate_begin_invoke") +#pragma comment(linker, "/export:mono_get_delegate_begin_invoke_checked") +#pragma comment(linker, "/export:mono_get_delegate_end_invoke") +#pragma comment(linker, "/export:mono_get_delegate_end_invoke_checked") +#pragma comment(linker, "/export:mono_get_delegate_invoke") +#pragma comment(linker, "/export:mono_get_delegate_invoke_checked") +#pragma comment(linker, "/export:mono_get_delegate_virtual_invoke_impl") +#pragma comment(linker, "/export:mono_get_delegate_virtual_invoke_impl_name") +#pragma comment(linker, "/export:mono_get_double_class") +#pragma comment(linker, "/export:mono_get_eh_callbacks") +#pragma comment(linker, "/export:mono_get_enum_class") +#pragma comment(linker, "/export:mono_get_exception_appdomain_unloaded") +#pragma comment(linker, "/export:mono_get_exception_argument") +#pragma comment(linker, "/export:mono_get_exception_argument_null") +#pragma comment(linker, "/export:mono_get_exception_argument_out_of_range") +#pragma comment(linker, "/export:mono_get_exception_arithmetic") +#pragma comment(linker, "/export:mono_get_exception_array_type_mismatch") +#pragma comment(linker, "/export:mono_get_exception_bad_image_format") +#pragma comment(linker, "/export:mono_get_exception_bad_image_format2") +#pragma comment(linker, "/export:mono_get_exception_cannot_unload_appdomain") +#pragma comment(linker, "/export:mono_get_exception_class") +#pragma comment(linker, "/export:mono_get_exception_divide_by_zero") +#pragma comment(linker, "/export:mono_get_exception_execution_engine") +#pragma comment(linker, "/export:mono_get_exception_field_access") +#pragma comment(linker, "/export:mono_get_exception_field_access_msg") +#pragma comment(linker, "/export:mono_get_exception_file_not_found") +#pragma comment(linker, "/export:mono_get_exception_file_not_found2") +#pragma comment(linker, "/export:mono_get_exception_index_out_of_range") +#pragma comment(linker, "/export:mono_get_exception_invalid_cast") +#pragma comment(linker, "/export:mono_get_exception_invalid_operation") +#pragma comment(linker, "/export:mono_get_exception_io") +#pragma comment(linker, "/export:mono_get_exception_method_access") +#pragma comment(linker, "/export:mono_get_exception_method_access_msg") +#pragma comment(linker, "/export:mono_get_exception_missing_field") +#pragma comment(linker, "/export:mono_get_exception_missing_method") +#pragma comment(linker, "/export:mono_get_exception_not_implemented") +#pragma comment(linker, "/export:mono_get_exception_not_supported") +#pragma comment(linker, "/export:mono_get_exception_null_reference") +#pragma comment(linker, "/export:mono_get_exception_out_of_memory") +#pragma comment(linker, "/export:mono_get_exception_out_of_memory_handle") +#pragma comment(linker, "/export:mono_get_exception_overflow") +#pragma comment(linker, "/export:mono_get_exception_reflection_type_load") +#pragma comment(linker, "/export:mono_get_exception_reflection_type_load_checked") +#pragma comment(linker, "/export:mono_get_exception_runtime_wrapped") +#pragma comment(linker, "/export:mono_get_exception_runtime_wrapped_handle") +#pragma comment(linker, "/export:mono_get_exception_security") +#pragma comment(linker, "/export:mono_get_exception_serialization") +#pragma comment(linker, "/export:mono_get_exception_stack_overflow") +#pragma comment(linker, "/export:mono_get_exception_synchronization_lock") +#pragma comment(linker, "/export:mono_get_exception_thread_abort") +#pragma comment(linker, "/export:mono_get_exception_thread_interrupted") +#pragma comment(linker, "/export:mono_get_exception_thread_state") +#pragma comment(linker, "/export:mono_get_exception_type_initialization") +#pragma comment(linker, "/export:mono_get_exception_type_initialization_handle") +#pragma comment(linker, "/export:mono_get_exception_type_load") +#pragma comment(linker, "/export:mono_get_generic_trampoline_name") +#pragma comment(linker, "/export:mono_get_generic_trampoline_simple_name") +#pragma comment(linker, "/export:mono_get_hazardous_pointer") +#pragma comment(linker, "/export:mono_get_image_for_generic_param") +#pragma comment(linker, "/export:mono_get_inflated_method") +#pragma comment(linker, "/export:mono_get_int16_class") +#pragma comment(linker, "/export:mono_get_int32_class") +#pragma comment(linker, "/export:mono_get_int64_class") +#pragma comment(linker, "/export:mono_get_intptr_class") +#pragma comment(linker, "/export:mono_get_jit_icall_info") +#pragma comment(linker, "/export:mono_get_lmf") +#pragma comment(linker, "/export:mono_get_local_interfaces") +#pragma comment(linker, "/export:mono_get_machine_config") +#pragma comment(linker, "/export:mono_get_method") +#pragma comment(linker, "/export:mono_get_method_checked") +#pragma comment(linker, "/export:mono_get_method_constrained") +#pragma comment(linker, "/export:mono_get_method_constrained_checked") +#pragma comment(linker, "/export:mono_get_method_constrained_with_method") +#pragma comment(linker, "/export:mono_get_method_from_ip") +#pragma comment(linker, "/export:mono_get_method_full") +#pragma comment(linker, "/export:mono_get_method_object") +#pragma comment(linker, "/export:mono_get_module_file_name") +#pragma comment(linker, "/export:mono_get_native_calli_wrapper") +#pragma comment(linker, "/export:mono_get_object_class") +#pragma comment(linker, "/export:mono_get_object_from_blob") +#pragma comment(linker, "/export:mono_get_optimizations_for_method") +#pragma comment(linker, "/export:mono_get_restore_context") +#pragma comment(linker, "/export:mono_get_rethrow_exception") +#pragma comment(linker, "/export:mono_get_rgctx_fetch_trampoline_name") +#pragma comment(linker, "/export:mono_get_root_domain") +#pragma comment(linker, "/export:mono_get_runtime_build_info") +#pragma comment(linker, "/export:mono_get_runtime_callbacks") +#pragma comment(linker, "/export:mono_get_runtime_info") +#pragma comment(linker, "/export:mono_get_sbyte_class") +#pragma comment(linker, "/export:mono_get_seq_points") +#pragma comment(linker, "/export:mono_get_shared_generic_inst") +#pragma comment(linker, "/export:mono_get_single_class") +#pragma comment(linker, "/export:mono_get_special_static_data") +#pragma comment(linker, "/export:mono_get_special_static_data_for_thread") +#pragma comment(linker, "/export:mono_get_string_class") +#pragma comment(linker, "/export:mono_get_thread_class") +#pragma comment(linker, "/export:mono_get_throw_corlib_exception") +#pragma comment(linker, "/export:mono_get_throw_exception") +#pragma comment(linker, "/export:mono_get_throw_exception_addr") +#pragma comment(linker, "/export:mono_get_trampoline_code") +#pragma comment(linker, "/export:mono_get_trampoline_func") +#pragma comment(linker, "/export:mono_get_uint16_class") +#pragma comment(linker, "/export:mono_get_uint32_class") +#pragma comment(linker, "/export:mono_get_uint64_class") +#pragma comment(linker, "/export:mono_get_uintptr_class") +#pragma comment(linker, "/export:mono_get_void_class") +#pragma comment(linker, "/export:mono_image_add_to_name_cache") +#pragma comment(linker, "/export:mono_image_addref") +#pragma comment(linker, "/export:mono_image_alloc") +#pragma comment(linker, "/export:mono_image_alloc0") +#pragma comment(linker, "/export:mono_image_append_class_to_reflection_info_set") +#pragma comment(linker, "/export:mono_image_build_metadata") +#pragma comment(linker, "/export:mono_image_check_for_module_cctor") +#pragma comment(linker, "/export:mono_image_close") +#pragma comment(linker, "/export:mono_image_close_except_pools") +#pragma comment(linker, "/export:mono_image_close_finish") +#pragma comment(linker, "/export:mono_image_create_pefile") +#pragma comment(linker, "/export:mono_image_create_token") +#pragma comment(linker, "/export:mono_image_ensure_section") +#pragma comment(linker, "/export:mono_image_ensure_section_idx") +#pragma comment(linker, "/export:mono_image_fixup_vtable") +#pragma comment(linker, "/export:mono_image_g_malloc0") +#pragma comment(linker, "/export:mono_image_get_assembly") +#pragma comment(linker, "/export:mono_image_get_entry_point") +#pragma comment(linker, "/export:mono_image_get_filename") +#pragma comment(linker, "/export:mono_image_get_guid") +#pragma comment(linker, "/export:mono_image_get_methodref_token") +#pragma comment(linker, "/export:mono_image_get_name") +#pragma comment(linker, "/export:mono_image_get_public_key") +#pragma comment(linker, "/export:mono_image_get_resource") +#pragma comment(linker, "/export:mono_image_get_strong_name") +#pragma comment(linker, "/export:mono_image_get_table_info") +#pragma comment(linker, "/export:mono_image_get_table_rows") +#pragma comment(linker, "/export:mono_image_has_authenticode_entry") +#pragma comment(linker, "/export:mono_image_init") +#pragma comment(linker, "/export:mono_image_init_name_cache") +#pragma comment(linker, "/export:mono_image_insert_string") +#pragma comment(linker, "/export:mono_image_is_dynamic") +#pragma comment(linker, "/export:mono_image_load_cli_data") +#pragma comment(linker, "/export:mono_image_load_cli_header") +#pragma comment(linker, "/export:mono_image_load_file_for_image") +#pragma comment(linker, "/export:mono_image_load_file_for_image_checked") +#pragma comment(linker, "/export:mono_image_load_metadata") +#pragma comment(linker, "/export:mono_image_load_module") +#pragma comment(linker, "/export:mono_image_load_module_checked") +#pragma comment(linker, "/export:mono_image_load_names") +#pragma comment(linker, "/export:mono_image_load_pe_data") +#pragma comment(linker, "/export:mono_image_loaded") +#pragma comment(linker, "/export:mono_image_loaded_by_guid") +#pragma comment(linker, "/export:mono_image_loaded_by_guid_full") +#pragma comment(linker, "/export:mono_image_loaded_full") +#pragma comment(linker, "/export:mono_image_loaded_internal") +#pragma comment(linker, "/export:mono_image_lock") +#pragma comment(linker, "/export:mono_image_lookup_resource") +#pragma comment(linker, "/export:mono_image_open") +#pragma comment(linker, "/export:mono_image_open_a_lot") +#pragma comment(linker, "/export:mono_image_open_from_data") +#pragma comment(linker, "/export:mono_image_open_from_data_full") +#pragma comment(linker, "/export:mono_image_open_from_data_internal") +#pragma comment(linker, "/export:mono_image_open_from_data_with_name") +#pragma comment(linker, "/export:mono_image_open_from_module_handle") +#pragma comment(linker, "/export:mono_image_open_full") +#pragma comment(linker, "/export:mono_image_open_metadata_only") +#pragma comment(linker, "/export:mono_image_open_raw") +#pragma comment(linker, "/export:mono_image_property_insert") +#pragma comment(linker, "/export:mono_image_property_lookup") +#pragma comment(linker, "/export:mono_image_property_remove") +#pragma comment(linker, "/export:mono_image_rva_map") +#pragma comment(linker, "/export:mono_image_set_alloc") +#pragma comment(linker, "/export:mono_image_set_alloc0") +#pragma comment(linker, "/export:mono_image_set_description") +#pragma comment(linker, "/export:mono_image_set_lock") +#pragma comment(linker, "/export:mono_image_set_strdup") +#pragma comment(linker, "/export:mono_image_set_unlock") +#pragma comment(linker, "/export:mono_image_strdup") +#pragma comment(linker, "/export:mono_image_strdup_printf") +#pragma comment(linker, "/export:mono_image_strdup_vprintf") +#pragma comment(linker, "/export:mono_image_strerror") +#pragma comment(linker, "/export:mono_image_strong_name_position") +#pragma comment(linker, "/export:mono_image_unlock") +#pragma comment(linker, "/export:mono_metadata_blob_heap") +#pragma comment(linker, "/export:mono_metadata_blob_heap_checked") +#pragma comment(linker, "/export:mono_metadata_clean_for_image") +#pragma comment(linker, "/export:mono_metadata_cleanup") +#pragma comment(linker, "/export:mono_metadata_compute_size") +#pragma comment(linker, "/export:mono_metadata_compute_table_bases") +#pragma comment(linker, "/export:mono_metadata_create_anon_gparam") +#pragma comment(linker, "/export:mono_metadata_cross_helpers_run") +#pragma comment(linker, "/export:mono_metadata_custom_attrs_from_index") +#pragma comment(linker, "/export:mono_metadata_declsec_from_index") +#pragma comment(linker, "/export:mono_metadata_decode_blob_size") +#pragma comment(linker, "/export:mono_metadata_decode_row") +#pragma comment(linker, "/export:mono_metadata_decode_row_checked") +#pragma comment(linker, "/export:mono_metadata_decode_row_col") +#pragma comment(linker, "/export:mono_metadata_decode_signed_value") +#pragma comment(linker, "/export:mono_metadata_decode_table_row") +#pragma comment(linker, "/export:mono_metadata_decode_table_row_col") +#pragma comment(linker, "/export:mono_metadata_decode_value") +#pragma comment(linker, "/export:mono_metadata_encode_value") +#pragma comment(linker, "/export:mono_metadata_events_from_typedef") +#pragma comment(linker, "/export:mono_metadata_field_info") +#pragma comment(linker, "/export:mono_metadata_field_info_with_mempool") +#pragma comment(linker, "/export:mono_metadata_free_array") +#pragma comment(linker, "/export:mono_metadata_free_inflated_signature") +#pragma comment(linker, "/export:mono_metadata_free_marshal_spec") +#pragma comment(linker, "/export:mono_metadata_free_method_signature") +#pragma comment(linker, "/export:mono_metadata_free_mh") +#pragma comment(linker, "/export:mono_metadata_free_type") +#pragma comment(linker, "/export:mono_metadata_generic_class_is_valuetype") +#pragma comment(linker, "/export:mono_metadata_generic_context_equal") +#pragma comment(linker, "/export:mono_metadata_generic_context_hash") +#pragma comment(linker, "/export:mono_metadata_generic_inst_equal") +#pragma comment(linker, "/export:mono_metadata_generic_inst_hash") +#pragma comment(linker, "/export:mono_metadata_generic_param_equal") +#pragma comment(linker, "/export:mono_metadata_generic_param_hash") +#pragma comment(linker, "/export:mono_metadata_get_canonical_generic_inst") +#pragma comment(linker, "/export:mono_metadata_get_constant_index") +#pragma comment(linker, "/export:mono_metadata_get_corresponding_event_from_generic_type_definition") +#pragma comment(linker, "/export:mono_metadata_get_corresponding_field_from_generic_type_definition") +#pragma comment(linker, "/export:mono_metadata_get_corresponding_property_from_generic_type_definition") +#pragma comment(linker, "/export:mono_metadata_get_generic_inst") +#pragma comment(linker, "/export:mono_metadata_get_generic_param_row") +#pragma comment(linker, "/export:mono_metadata_get_image_set_for_class") +#pragma comment(linker, "/export:mono_metadata_get_image_set_for_method") +#pragma comment(linker, "/export:mono_metadata_get_inflated_signature") +#pragma comment(linker, "/export:mono_metadata_get_marshal_info") +#pragma comment(linker, "/export:mono_metadata_get_param_attrs") +#pragma comment(linker, "/export:mono_metadata_get_shared_type") +#pragma comment(linker, "/export:mono_metadata_guid_heap") +#pragma comment(linker, "/export:mono_metadata_has_generic_params") +#pragma comment(linker, "/export:mono_metadata_implmap_from_method") +#pragma comment(linker, "/export:mono_metadata_inflate_generic_inst") +#pragma comment(linker, "/export:mono_metadata_init") +#pragma comment(linker, "/export:mono_metadata_interfaces_from_typedef") +#pragma comment(linker, "/export:mono_metadata_interfaces_from_typedef_full") +#pragma comment(linker, "/export:mono_metadata_load_generic_param_constraints_checked") +#pragma comment(linker, "/export:mono_metadata_load_generic_params") +#pragma comment(linker, "/export:mono_metadata_localscope_from_methoddef") +#pragma comment(linker, "/export:mono_metadata_locate") +#pragma comment(linker, "/export:mono_metadata_locate_token") +#pragma comment(linker, "/export:mono_metadata_lookup_generic_class") +#pragma comment(linker, "/export:mono_metadata_method_has_param_attrs") +#pragma comment(linker, "/export:mono_metadata_methods_from_event") +#pragma comment(linker, "/export:mono_metadata_methods_from_property") +#pragma comment(linker, "/export:mono_metadata_nested_in_typedef") +#pragma comment(linker, "/export:mono_metadata_nesting_typedef") +#pragma comment(linker, "/export:mono_metadata_packing_from_typedef") +#pragma comment(linker, "/export:mono_metadata_parse_array") +#pragma comment(linker, "/export:mono_metadata_parse_custom_mod") +#pragma comment(linker, "/export:mono_metadata_parse_field_type") +#pragma comment(linker, "/export:mono_metadata_parse_generic_inst") +#pragma comment(linker, "/export:mono_metadata_parse_marshal_spec") +#pragma comment(linker, "/export:mono_metadata_parse_marshal_spec_full") +#pragma comment(linker, "/export:mono_metadata_parse_method_signature") +#pragma comment(linker, "/export:mono_metadata_parse_method_signature_full") +#pragma comment(linker, "/export:mono_metadata_parse_mh") +#pragma comment(linker, "/export:mono_metadata_parse_mh_full") +#pragma comment(linker, "/export:mono_metadata_parse_param") +#pragma comment(linker, "/export:mono_metadata_parse_signature") +#pragma comment(linker, "/export:mono_metadata_parse_signature_checked") +#pragma comment(linker, "/export:mono_metadata_parse_type") +#pragma comment(linker, "/export:mono_metadata_parse_type_checked") +#pragma comment(linker, "/export:mono_metadata_parse_typedef_or_ref") +#pragma comment(linker, "/export:mono_metadata_properties_from_typedef") +#pragma comment(linker, "/export:mono_metadata_read_constant_value") +#pragma comment(linker, "/export:mono_metadata_signature_alloc") +#pragma comment(linker, "/export:mono_metadata_signature_deep_dup") +#pragma comment(linker, "/export:mono_metadata_signature_dup") +#pragma comment(linker, "/export:mono_metadata_signature_dup_add_this") +#pragma comment(linker, "/export:mono_metadata_signature_dup_full") +#pragma comment(linker, "/export:mono_metadata_signature_dup_mempool") +#pragma comment(linker, "/export:mono_metadata_signature_equal") +#pragma comment(linker, "/export:mono_metadata_signature_size") +#pragma comment(linker, "/export:mono_metadata_str_hash") +#pragma comment(linker, "/export:mono_metadata_string_heap") +#pragma comment(linker, "/export:mono_metadata_string_heap_checked") +#pragma comment(linker, "/export:mono_metadata_token_from_dor") +#pragma comment(linker, "/export:mono_metadata_translate_token_index") +#pragma comment(linker, "/export:mono_metadata_type_dup") +#pragma comment(linker, "/export:mono_metadata_type_dup_with_cmods") +#pragma comment(linker, "/export:mono_metadata_type_equal") +#pragma comment(linker, "/export:mono_metadata_type_equal_full") +#pragma comment(linker, "/export:mono_metadata_type_hash") +#pragma comment(linker, "/export:mono_metadata_typedef_from_field") +#pragma comment(linker, "/export:mono_metadata_typedef_from_method") +#pragma comment(linker, "/export:mono_metadata_user_string") +#pragma comment(linker, "/export:mono_method_add_generic_virtual_invocation") +#pragma comment(linker, "/export:mono_method_alloc_generic_virtual_trampoline") +#pragma comment(linker, "/export:mono_method_body_get_object") +#pragma comment(linker, "/export:mono_method_body_get_object_handle") +#pragma comment(linker, "/export:mono_method_builder_ilgen_init") +#pragma comment(linker, "/export:mono_method_call_message_new") +#pragma comment(linker, "/export:mono_method_can_access_field") +#pragma comment(linker, "/export:mono_method_can_access_field_full") +#pragma comment(linker, "/export:mono_method_can_access_method") +#pragma comment(linker, "/export:mono_method_can_access_method_full") +#pragma comment(linker, "/export:mono_method_check_context_used") +#pragma comment(linker, "/export:mono_method_clear_object") +#pragma comment(linker, "/export:mono_method_construct_object_context") +#pragma comment(linker, "/export:mono_method_desc_free") +#pragma comment(linker, "/export:mono_method_desc_from_method") +#pragma comment(linker, "/export:mono_method_desc_full_match") +#pragma comment(linker, "/export:mono_method_desc_is_full") +#pragma comment(linker, "/export:mono_method_desc_match") +#pragma comment(linker, "/export:mono_method_desc_new") +#pragma comment(linker, "/export:mono_method_desc_search_in_class") +#pragma comment(linker, "/export:mono_method_desc_search_in_image") +#pragma comment(linker, "/export:mono_method_fill_runtime_generic_context") +#pragma comment(linker, "/export:mono_method_from_method_def_or_ref") +#pragma comment(linker, "/export:mono_method_full_name") +#pragma comment(linker, "/export:mono_method_get_base_method") +#pragma comment(linker, "/export:mono_method_get_class") +#pragma comment(linker, "/export:mono_method_get_context") +#pragma comment(linker, "/export:mono_method_get_context_general") +#pragma comment(linker, "/export:mono_method_get_declaring_generic_method") +#pragma comment(linker, "/export:mono_method_get_flags") +#pragma comment(linker, "/export:mono_method_get_full_name") +#pragma comment(linker, "/export:mono_method_get_generic_container") +#pragma comment(linker, "/export:mono_method_get_header") +#pragma comment(linker, "/export:mono_method_get_header_checked") +#pragma comment(linker, "/export:mono_method_get_header_internal") +#pragma comment(linker, "/export:mono_method_get_header_summary") +#pragma comment(linker, "/export:mono_method_get_imt_slot") +#pragma comment(linker, "/export:mono_method_get_index") +#pragma comment(linker, "/export:mono_method_get_last_managed") +#pragma comment(linker, "/export:mono_method_get_marshal_info") +#pragma comment(linker, "/export:mono_method_get_name") +#pragma comment(linker, "/export:mono_method_get_name_full") +#pragma comment(linker, "/export:mono_method_get_object") +#pragma comment(linker, "/export:mono_method_get_object_checked") +#pragma comment(linker, "/export:mono_method_get_object_handle") +#pragma comment(linker, "/export:mono_method_get_param_names") +#pragma comment(linker, "/export:mono_method_get_param_token") +#pragma comment(linker, "/export:mono_method_get_reflection_name") +#pragma comment(linker, "/export:mono_method_get_signature") +#pragma comment(linker, "/export:mono_method_get_signature_checked") +#pragma comment(linker, "/export:mono_method_get_signature_full") +#pragma comment(linker, "/export:mono_method_get_token") +#pragma comment(linker, "/export:mono_method_get_unmanaged_thunk") +#pragma comment(linker, "/export:mono_method_get_vtable_index") +#pragma comment(linker, "/export:mono_method_get_vtable_slot") +#pragma comment(linker, "/export:mono_method_get_wrapper_cache") +#pragma comment(linker, "/export:mono_method_get_wrapper_data") +#pragma comment(linker, "/export:mono_method_has_marshal_info") +#pragma comment(linker, "/export:mono_method_has_no_body") +#pragma comment(linker, "/export:mono_method_header_get_clauses") +#pragma comment(linker, "/export:mono_method_header_get_code") +#pragma comment(linker, "/export:mono_method_header_get_locals") +#pragma comment(linker, "/export:mono_method_header_get_num_clauses") +#pragma comment(linker, "/export:mono_method_is_from_assembly") +#pragma comment(linker, "/export:mono_method_is_generic_impl") +#pragma comment(linker, "/export:mono_method_is_generic_sharable") +#pragma comment(linker, "/export:mono_method_is_generic_sharable_full") +#pragma comment(linker, "/export:mono_method_lookup_or_register_info") +#pragma comment(linker, "/export:mono_method_needs_static_rgctx_invoke") +#pragma comment(linker, "/export:mono_method_print_code") +#pragma comment(linker, "/export:mono_method_return_message_restore") +#pragma comment(linker, "/export:mono_method_same_domain") +#pragma comment(linker, "/export:mono_method_search_in_array_class") +#pragma comment(linker, "/export:mono_method_set_generic_container") +#pragma comment(linker, "/export:mono_method_signature") +#pragma comment(linker, "/export:mono_method_signature_checked") +#pragma comment(linker, "/export:mono_method_verify") +#pragma comment(linker, "/export:mono_method_verify_with_current_settings") +#pragma comment(linker, "/export:mono_object_castclass_mbyref") +#pragma comment(linker, "/export:mono_object_castclass_unbox") +#pragma comment(linker, "/export:mono_object_castclass_with_cache") +#pragma comment(linker, "/export:mono_object_clone") +#pragma comment(linker, "/export:mono_object_clone_checked") +#pragma comment(linker, "/export:mono_object_clone_handle") +#pragma comment(linker, "/export:mono_object_describe") +#pragma comment(linker, "/export:mono_object_describe_fields") +#pragma comment(linker, "/export:mono_object_get_class") +#pragma comment(linker, "/export:mono_object_get_data") +#pragma comment(linker, "/export:mono_object_get_domain") +#pragma comment(linker, "/export:mono_object_get_size") +#pragma comment(linker, "/export:mono_object_get_virtual_method") +#pragma comment(linker, "/export:mono_object_get_vtable") +#pragma comment(linker, "/export:mono_object_handle_get_virtual_method") +#pragma comment(linker, "/export:mono_object_handle_isinst") +#pragma comment(linker, "/export:mono_object_handle_isinst_mbyref") +#pragma comment(linker, "/export:mono_object_handle_pin_unbox") +#pragma comment(linker, "/export:mono_object_hash") +#pragma comment(linker, "/export:mono_object_is_alive") +#pragma comment(linker, "/export:mono_object_is_from_assembly") +#pragma comment(linker, "/export:mono_object_isinst") +#pragma comment(linker, "/export:mono_object_isinst_checked") +#pragma comment(linker, "/export:mono_object_isinst_icall") +#pragma comment(linker, "/export:mono_object_isinst_mbyref") +#pragma comment(linker, "/export:mono_object_isinst_with_cache") +#pragma comment(linker, "/export:mono_object_new") +#pragma comment(linker, "/export:mono_object_new_alloc_by_vtable") +#pragma comment(linker, "/export:mono_object_new_alloc_specific") +#pragma comment(linker, "/export:mono_object_new_alloc_specific_checked") +#pragma comment(linker, "/export:mono_object_new_checked") +#pragma comment(linker, "/export:mono_object_new_fast") +#pragma comment(linker, "/export:mono_object_new_from_token") +#pragma comment(linker, "/export:mono_object_new_handle") +#pragma comment(linker, "/export:mono_object_new_handle_mature") +#pragma comment(linker, "/export:mono_object_new_mature") +#pragma comment(linker, "/export:mono_object_new_pinned") +#pragma comment(linker, "/export:mono_object_new_pinned_handle") +#pragma comment(linker, "/export:mono_object_new_specific") +#pragma comment(linker, "/export:mono_object_new_specific_checked") +#pragma comment(linker, "/export:mono_object_register_finalizer") +#pragma comment(linker, "/export:mono_object_register_finalizer_handle") +#pragma comment(linker, "/export:mono_object_to_string") +#pragma comment(linker, "/export:mono_object_try_to_string") +#pragma comment(linker, "/export:mono_object_unbox") +#pragma comment(linker, "/export:mono_object_xdomain_representation") +#pragma comment(linker, "/export:mono_profiler_call_context_free_buffer") +#pragma comment(linker, "/export:mono_profiler_call_context_get_argument") +#pragma comment(linker, "/export:mono_profiler_call_context_get_local") +#pragma comment(linker, "/export:mono_profiler_call_context_get_result") +#pragma comment(linker, "/export:mono_profiler_call_context_get_this") +#pragma comment(linker, "/export:mono_profiler_cleanup") +#pragma comment(linker, "/export:mono_profiler_coverage_alloc") +#pragma comment(linker, "/export:mono_profiler_coverage_instrumentation_enabled") +#pragma comment(linker, "/export:mono_profiler_create") +#pragma comment(linker, "/export:mono_profiler_enable_allocations") +#pragma comment(linker, "/export:mono_profiler_enable_call_context_introspection") +#pragma comment(linker, "/export:mono_profiler_enable_clauses") +#pragma comment(linker, "/export:mono_profiler_enable_coverage") +#pragma comment(linker, "/export:mono_profiler_enable_sampling") +#pragma comment(linker, "/export:mono_profiler_get_call_instrumentation_flags") +#pragma comment(linker, "/export:mono_profiler_get_coverage_data") +#pragma comment(linker, "/export:mono_profiler_get_sample_mode") +#pragma comment(linker, "/export:mono_profiler_install") +#pragma comment(linker, "/export:mono_profiler_install_allocation") +#pragma comment(linker, "/export:mono_profiler_install_enter_leave") +#pragma comment(linker, "/export:mono_profiler_install_exception") +#pragma comment(linker, "/export:mono_profiler_install_gc") +#pragma comment(linker, "/export:mono_profiler_install_jit_end") +#pragma comment(linker, "/export:mono_profiler_install_thread") +#pragma comment(linker, "/export:mono_profiler_load") +#pragma comment(linker, "/export:mono_profiler_raise_assembly_loaded") +#pragma comment(linker, "/export:mono_profiler_raise_assembly_loading") +#pragma comment(linker, "/export:mono_profiler_raise_assembly_unloaded") +#pragma comment(linker, "/export:mono_profiler_raise_assembly_unloading") +#pragma comment(linker, "/export:mono_profiler_raise_class_failed") +#pragma comment(linker, "/export:mono_profiler_raise_class_loaded") +#pragma comment(linker, "/export:mono_profiler_raise_class_loading") +#pragma comment(linker, "/export:mono_profiler_raise_context_loaded") +#pragma comment(linker, "/export:mono_profiler_raise_context_unloaded") +#pragma comment(linker, "/export:mono_profiler_raise_domain_loaded") +#pragma comment(linker, "/export:mono_profiler_raise_domain_loading") +#pragma comment(linker, "/export:mono_profiler_raise_domain_name") +#pragma comment(linker, "/export:mono_profiler_raise_domain_unloaded") +#pragma comment(linker, "/export:mono_profiler_raise_domain_unloading") +#pragma comment(linker, "/export:mono_profiler_raise_exception_clause") +#pragma comment(linker, "/export:mono_profiler_raise_exception_throw") +#pragma comment(linker, "/export:mono_profiler_raise_gc_allocation") +#pragma comment(linker, "/export:mono_profiler_raise_gc_event") +#pragma comment(linker, "/export:mono_profiler_raise_gc_finalized") +#pragma comment(linker, "/export:mono_profiler_raise_gc_finalized_object") +#pragma comment(linker, "/export:mono_profiler_raise_gc_finalizing") +#pragma comment(linker, "/export:mono_profiler_raise_gc_finalizing_object") +#pragma comment(linker, "/export:mono_profiler_raise_gc_handle_created") +#pragma comment(linker, "/export:mono_profiler_raise_gc_handle_deleted") +#pragma comment(linker, "/export:mono_profiler_raise_gc_moves") +#pragma comment(linker, "/export:mono_profiler_raise_gc_resize") +#pragma comment(linker, "/export:mono_profiler_raise_gc_root_register") +#pragma comment(linker, "/export:mono_profiler_raise_gc_root_unregister") +#pragma comment(linker, "/export:mono_profiler_raise_gc_roots") +#pragma comment(linker, "/export:mono_profiler_raise_image_failed") +#pragma comment(linker, "/export:mono_profiler_raise_image_loaded") +#pragma comment(linker, "/export:mono_profiler_raise_image_loading") +#pragma comment(linker, "/export:mono_profiler_raise_image_unloaded") +#pragma comment(linker, "/export:mono_profiler_raise_image_unloading") +#pragma comment(linker, "/export:mono_profiler_raise_jit_begin") +#pragma comment(linker, "/export:mono_profiler_raise_jit_chunk_created") +#pragma comment(linker, "/export:mono_profiler_raise_jit_chunk_destroyed") +#pragma comment(linker, "/export:mono_profiler_raise_jit_code_buffer") +#pragma comment(linker, "/export:mono_profiler_raise_jit_done") +#pragma comment(linker, "/export:mono_profiler_raise_jit_failed") +#pragma comment(linker, "/export:mono_profiler_raise_method_begin_invoke") +#pragma comment(linker, "/export:mono_profiler_raise_method_end_invoke") +#pragma comment(linker, "/export:mono_profiler_raise_method_enter") +#pragma comment(linker, "/export:mono_profiler_raise_method_exception_leave") +#pragma comment(linker, "/export:mono_profiler_raise_method_free") +#pragma comment(linker, "/export:mono_profiler_raise_method_leave") +#pragma comment(linker, "/export:mono_profiler_raise_method_tail_call") +#pragma comment(linker, "/export:mono_profiler_raise_monitor_acquired") +#pragma comment(linker, "/export:mono_profiler_raise_monitor_contention") +#pragma comment(linker, "/export:mono_profiler_raise_monitor_failed") +#pragma comment(linker, "/export:mono_profiler_raise_runtime_initialized") +#pragma comment(linker, "/export:mono_profiler_raise_runtime_shutdown_begin") +#pragma comment(linker, "/export:mono_profiler_raise_runtime_shutdown_end") +#pragma comment(linker, "/export:mono_profiler_raise_sample_hit") +#pragma comment(linker, "/export:mono_profiler_raise_thread_exited") +#pragma comment(linker, "/export:mono_profiler_raise_thread_name") +#pragma comment(linker, "/export:mono_profiler_raise_thread_started") +#pragma comment(linker, "/export:mono_profiler_raise_thread_stopped") +#pragma comment(linker, "/export:mono_profiler_raise_thread_stopping") +#pragma comment(linker, "/export:mono_profiler_raise_vtable_failed") +#pragma comment(linker, "/export:mono_profiler_raise_vtable_loaded") +#pragma comment(linker, "/export:mono_profiler_raise_vtable_loading") +#pragma comment(linker, "/export:mono_profiler_sampling_enabled") +#pragma comment(linker, "/export:mono_profiler_sampling_thread_post") +#pragma comment(linker, "/export:mono_profiler_sampling_thread_wait") +#pragma comment(linker, "/export:mono_profiler_set_assembly_loaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_assembly_loading_callback") +#pragma comment(linker, "/export:mono_profiler_set_assembly_unloaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_assembly_unloading_callback") +#pragma comment(linker, "/export:mono_profiler_set_call_instrumentation_filter_callback") +#pragma comment(linker, "/export:mono_profiler_set_class_failed_callback") +#pragma comment(linker, "/export:mono_profiler_set_class_loaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_class_loading_callback") +#pragma comment(linker, "/export:mono_profiler_set_cleanup_callback") +#pragma comment(linker, "/export:mono_profiler_set_context_loaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_context_unloaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_coverage_filter_callback") +#pragma comment(linker, "/export:mono_profiler_set_domain_loaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_domain_loading_callback") +#pragma comment(linker, "/export:mono_profiler_set_domain_name_callback") +#pragma comment(linker, "/export:mono_profiler_set_domain_unloaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_domain_unloading_callback") +#pragma comment(linker, "/export:mono_profiler_set_events") +#pragma comment(linker, "/export:mono_profiler_set_exception_clause_callback") +#pragma comment(linker, "/export:mono_profiler_set_exception_throw_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_allocation_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_event_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_finalized_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_finalized_object_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_finalizing_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_finalizing_object_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_handle_created_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_handle_deleted_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_moves_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_resize_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_root_register_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_root_unregister_callback") +#pragma comment(linker, "/export:mono_profiler_set_gc_roots_callback") +#pragma comment(linker, "/export:mono_profiler_set_image_failed_callback") +#pragma comment(linker, "/export:mono_profiler_set_image_loaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_image_loading_callback") +#pragma comment(linker, "/export:mono_profiler_set_image_unloaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_image_unloading_callback") +#pragma comment(linker, "/export:mono_profiler_set_jit_begin_callback") +#pragma comment(linker, "/export:mono_profiler_set_jit_chunk_created_callback") +#pragma comment(linker, "/export:mono_profiler_set_jit_chunk_destroyed_callback") +#pragma comment(linker, "/export:mono_profiler_set_jit_code_buffer_callback") +#pragma comment(linker, "/export:mono_profiler_set_jit_done_callback") +#pragma comment(linker, "/export:mono_profiler_set_jit_failed_callback") +#pragma comment(linker, "/export:mono_profiler_set_method_begin_invoke_callback") +#pragma comment(linker, "/export:mono_profiler_set_method_end_invoke_callback") +#pragma comment(linker, "/export:mono_profiler_set_method_enter_callback") +#pragma comment(linker, "/export:mono_profiler_set_method_exception_leave_callback") +#pragma comment(linker, "/export:mono_profiler_set_method_free_callback") +#pragma comment(linker, "/export:mono_profiler_set_method_leave_callback") +#pragma comment(linker, "/export:mono_profiler_set_method_tail_call_callback") +#pragma comment(linker, "/export:mono_profiler_set_monitor_acquired_callback") +#pragma comment(linker, "/export:mono_profiler_set_monitor_contention_callback") +#pragma comment(linker, "/export:mono_profiler_set_monitor_failed_callback") +#pragma comment(linker, "/export:mono_profiler_set_runtime_initialized_callback") +#pragma comment(linker, "/export:mono_profiler_set_runtime_shutdown_begin_callback") +#pragma comment(linker, "/export:mono_profiler_set_runtime_shutdown_end_callback") +#pragma comment(linker, "/export:mono_profiler_set_sample_hit_callback") +#pragma comment(linker, "/export:mono_profiler_set_sample_mode") +#pragma comment(linker, "/export:mono_profiler_set_thread_exited_callback") +#pragma comment(linker, "/export:mono_profiler_set_thread_name_callback") +#pragma comment(linker, "/export:mono_profiler_set_thread_started_callback") +#pragma comment(linker, "/export:mono_profiler_set_thread_stopped_callback") +#pragma comment(linker, "/export:mono_profiler_set_thread_stopping_callback") +#pragma comment(linker, "/export:mono_profiler_set_vtable_failed_callback") +#pragma comment(linker, "/export:mono_profiler_set_vtable_loaded_callback") +#pragma comment(linker, "/export:mono_profiler_set_vtable_loading_callback") +#pragma comment(linker, "/export:mono_profiler_started") +#pragma comment(linker, "/export:mono_profiler_state") +#pragma comment(linker, "/export:mono_property_bag_add") +#pragma comment(linker, "/export:mono_property_bag_get") +#pragma comment(linker, "/export:mono_property_get_flags") +#pragma comment(linker, "/export:mono_property_get_get_method") +#pragma comment(linker, "/export:mono_property_get_name") +#pragma comment(linker, "/export:mono_property_get_object") +#pragma comment(linker, "/export:mono_property_get_object_checked") +#pragma comment(linker, "/export:mono_property_get_object_handle") +#pragma comment(linker, "/export:mono_property_get_parent") +#pragma comment(linker, "/export:mono_property_get_set_method") +#pragma comment(linker, "/export:mono_property_get_value") +#pragma comment(linker, "/export:mono_property_get_value_checked") +#pragma comment(linker, "/export:mono_property_hash_destroy") +#pragma comment(linker, "/export:mono_property_hash_insert") +#pragma comment(linker, "/export:mono_property_hash_lookup") +#pragma comment(linker, "/export:mono_property_hash_new") +#pragma comment(linker, "/export:mono_property_hash_remove_object") +#pragma comment(linker, "/export:mono_property_set_value") +#pragma comment(linker, "/export:mono_property_set_value_handle") +#pragma comment(linker, "/export:mono_raise_exception") +#pragma comment(linker, "/export:mono_raise_exception_deprecated") +#pragma comment(linker, "/export:mono_raise_exception_with_context") +#pragma comment(linker, "/export:mono_reflection_assembly_get_assembly") +#pragma comment(linker, "/export:mono_reflection_bind_generic_parameters") +#pragma comment(linker, "/export:mono_reflection_call_is_assignable_to") +#pragma comment(linker, "/export:mono_reflection_cleanup_assembly") +#pragma comment(linker, "/export:mono_reflection_cleanup_domain") +#pragma comment(linker, "/export:mono_reflection_create_custom_attr_data_args") +#pragma comment(linker, "/export:mono_reflection_create_custom_attr_data_args_noalloc") +#pragma comment(linker, "/export:mono_reflection_dynimage_basic_init") +#pragma comment(linker, "/export:mono_reflection_emit_init") +#pragma comment(linker, "/export:mono_reflection_free_type_info") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_blob") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_blob_checked") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_by_type") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_by_type_handle") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_data") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_data_checked") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_info") +#pragma comment(linker, "/export:mono_reflection_get_custom_attrs_info_checked") +#pragma comment(linker, "/export:mono_reflection_get_dynamic_overrides") +#pragma comment(linker, "/export:mono_reflection_get_token") +#pragma comment(linker, "/export:mono_reflection_get_token_checked") +#pragma comment(linker, "/export:mono_reflection_get_type") +#pragma comment(linker, "/export:mono_reflection_get_type_checked") +#pragma comment(linker, "/export:mono_reflection_init") +#pragma comment(linker, "/export:mono_reflection_is_usertype") +#pragma comment(linker, "/export:mono_reflection_lookup_dynamic_token") +#pragma comment(linker, "/export:mono_reflection_lookup_signature") +#pragma comment(linker, "/export:mono_reflection_marshal_as_attribute_from_marshal_spec") +#pragma comment(linker, "/export:mono_reflection_method_count_clauses") +#pragma comment(linker, "/export:mono_reflection_methodbuilder_from_ctor_builder") +#pragma comment(linker, "/export:mono_reflection_methodbuilder_from_method_builder") +#pragma comment(linker, "/export:mono_reflection_parse_type") +#pragma comment(linker, "/export:mono_reflection_parse_type_checked") +#pragma comment(linker, "/export:mono_reflection_resolution_scope_from_image") +#pragma comment(linker, "/export:mono_reflection_resolve_object") +#pragma comment(linker, "/export:mono_reflection_resolve_object_handle") +#pragma comment(linker, "/export:mono_reflection_type_from_name") +#pragma comment(linker, "/export:mono_reflection_type_from_name_checked") +#pragma comment(linker, "/export:mono_reflection_type_get_handle") +#pragma comment(linker, "/export:mono_reflection_type_get_type") +#pragma comment(linker, "/export:mono_reflection_type_handle_mono_type") +#pragma comment(linker, "/export:mono_runtime_class_init") +#pragma comment(linker, "/export:mono_runtime_class_init_full") +#pragma comment(linker, "/export:mono_runtime_cleanup") +#pragma comment(linker, "/export:mono_runtime_cleanup_handlers") +#pragma comment(linker, "/export:mono_runtime_create_delegate_trampoline") +#pragma comment(linker, "/export:mono_runtime_create_jump_trampoline") +#pragma comment(linker, "/export:mono_runtime_delegate_invoke") +#pragma comment(linker, "/export:mono_runtime_delegate_invoke_checked") +#pragma comment(linker, "/export:mono_runtime_delegate_try_invoke") +#pragma comment(linker, "/export:mono_runtime_exec_main") +#pragma comment(linker, "/export:mono_runtime_exec_main_checked") +#pragma comment(linker, "/export:mono_runtime_exec_managed_code") +#pragma comment(linker, "/export:mono_runtime_free_method") +#pragma comment(linker, "/export:mono_runtime_get_aotid") +#pragma comment(linker, "/export:mono_runtime_get_caller_no_system_or_reflection") +#pragma comment(linker, "/export:mono_runtime_get_main_args") +#pragma comment(linker, "/export:mono_runtime_get_main_args_handle") +#pragma comment(linker, "/export:mono_runtime_get_no_exec") +#pragma comment(linker, "/export:mono_runtime_init") +#pragma comment(linker, "/export:mono_runtime_init_checked") +#pragma comment(linker, "/export:mono_runtime_init_tls") +#pragma comment(linker, "/export:mono_runtime_install_custom_handlers") +#pragma comment(linker, "/export:mono_runtime_install_custom_handlers_usage") +#pragma comment(linker, "/export:mono_runtime_install_handlers") +#pragma comment(linker, "/export:mono_runtime_invoke") +#pragma comment(linker, "/export:mono_runtime_invoke_array") +#pragma comment(linker, "/export:mono_runtime_invoke_array_checked") +#pragma comment(linker, "/export:mono_runtime_invoke_checked") +#pragma comment(linker, "/export:mono_runtime_invoke_handle") +#pragma comment(linker, "/export:mono_runtime_is_shutting_down") +#pragma comment(linker, "/export:mono_runtime_load") +#pragma comment(linker, "/export:mono_runtime_object_init") +#pragma comment(linker, "/export:mono_runtime_object_init_checked") +#pragma comment(linker, "/export:mono_runtime_object_init_handle") +#pragma comment(linker, "/export:mono_runtime_quit") +#pragma comment(linker, "/export:mono_runtime_resource_check_limit") +#pragma comment(linker, "/export:mono_runtime_resource_limit") +#pragma comment(linker, "/export:mono_runtime_resource_set_callback") +#pragma comment(linker, "/export:mono_runtime_run_main") +#pragma comment(linker, "/export:mono_runtime_run_main_checked") +#pragma comment(linker, "/export:mono_runtime_run_module_cctor") +#pragma comment(linker, "/export:mono_runtime_set_main_args") +#pragma comment(linker, "/export:mono_runtime_set_no_exec") +#pragma comment(linker, "/export:mono_runtime_set_pending_exception") +#pragma comment(linker, "/export:mono_runtime_set_shutting_down") +#pragma comment(linker, "/export:mono_runtime_setup_stat_profiler") +#pragma comment(linker, "/export:mono_runtime_shutdown_stat_profiler") +#pragma comment(linker, "/export:mono_runtime_try_exec_main") +#pragma comment(linker, "/export:mono_runtime_try_invoke") +#pragma comment(linker, "/export:mono_runtime_try_invoke_array") +#pragma comment(linker, "/export:mono_runtime_try_invoke_handle") +#pragma comment(linker, "/export:mono_runtime_try_run_main") +#pragma comment(linker, "/export:mono_runtime_try_shutdown") +#pragma comment(linker, "/export:mono_runtime_unhandled_exception_policy_get") +#pragma comment(linker, "/export:mono_runtime_unhandled_exception_policy_set") +#pragma comment(linker, "/export:mono_signature_explicit_this") +#pragma comment(linker, "/export:mono_signature_full_name") +#pragma comment(linker, "/export:mono_signature_get_call_conv") +#pragma comment(linker, "/export:mono_signature_get_desc") +#pragma comment(linker, "/export:mono_signature_get_param_count") +#pragma comment(linker, "/export:mono_signature_get_params") +#pragma comment(linker, "/export:mono_signature_get_return_type") +#pragma comment(linker, "/export:mono_signature_hash") +#pragma comment(linker, "/export:mono_signature_is_instance") +#pragma comment(linker, "/export:mono_signature_no_pinvoke") +#pragma comment(linker, "/export:mono_signature_param_is_out") +#pragma comment(linker, "/export:mono_signature_vararg_start") +#pragma comment(linker, "/export:mono_stack_mark_pop_value") +#pragma comment(linker, "/export:mono_stack_mark_record_size") +#pragma comment(linker, "/export:mono_stack_walk") +#pragma comment(linker, "/export:mono_stack_walk_async_safe") +#pragma comment(linker, "/export:mono_stack_walk_no_il") +#pragma comment(linker, "/export:mono_string_builder_to_utf16") +#pragma comment(linker, "/export:mono_string_builder_to_utf8") +#pragma comment(linker, "/export:mono_string_chars") +#pragma comment(linker, "/export:mono_string_empty") +#pragma comment(linker, "/export:mono_string_empty_handle") +#pragma comment(linker, "/export:mono_string_empty_wrapper") +#pragma comment(linker, "/export:mono_string_equal") +#pragma comment(linker, "/export:mono_string_from_blob") +#pragma comment(linker, "/export:mono_string_from_bstr") +#pragma comment(linker, "/export:mono_string_from_bstr_icall") +#pragma comment(linker, "/export:mono_string_from_byvalstr") +#pragma comment(linker, "/export:mono_string_from_byvalwstr") +#pragma comment(linker, "/export:mono_string_from_utf16") +#pragma comment(linker, "/export:mono_string_from_utf16_checked") +#pragma comment(linker, "/export:mono_string_from_utf32") +#pragma comment(linker, "/export:mono_string_from_utf32_checked") +#pragma comment(linker, "/export:mono_string_handle_length") +#pragma comment(linker, "/export:mono_string_handle_pin_chars") +#pragma comment(linker, "/export:mono_string_handle_to_utf8") +#pragma comment(linker, "/export:mono_string_hash") +#pragma comment(linker, "/export:mono_string_intern") +#pragma comment(linker, "/export:mono_string_intern_checked") +#pragma comment(linker, "/export:mono_string_is_interned") +#pragma comment(linker, "/export:mono_string_length") +#pragma comment(linker, "/export:mono_string_new") +#pragma comment(linker, "/export:mono_string_new_checked") +#pragma comment(linker, "/export:mono_string_new_handle") +#pragma comment(linker, "/export:mono_string_new_len") +#pragma comment(linker, "/export:mono_string_new_len_checked") +#pragma comment(linker, "/export:mono_string_new_len_wrapper") +#pragma comment(linker, "/export:mono_string_new_size") +#pragma comment(linker, "/export:mono_string_new_size_checked") +#pragma comment(linker, "/export:mono_string_new_utf16") +#pragma comment(linker, "/export:mono_string_new_utf16_checked") +#pragma comment(linker, "/export:mono_string_new_utf16_handle") +#pragma comment(linker, "/export:mono_string_new_utf32") +#pragma comment(linker, "/export:mono_string_new_utf8_len_handle") +#pragma comment(linker, "/export:mono_string_new_wrapper") +#pragma comment(linker, "/export:mono_string_new_wtf8_len_checked") +#pragma comment(linker, "/export:mono_string_to_ansibstr") +#pragma comment(linker, "/export:mono_string_to_bstr") +#pragma comment(linker, "/export:mono_string_to_byvalstr") +#pragma comment(linker, "/export:mono_string_to_byvalwstr") +#pragma comment(linker, "/export:mono_string_to_utf16") +#pragma comment(linker, "/export:mono_string_to_utf32") +#pragma comment(linker, "/export:mono_string_to_utf8") +#pragma comment(linker, "/export:mono_string_to_utf8_checked") +#pragma comment(linker, "/export:mono_string_to_utf8_ignore") +#pragma comment(linker, "/export:mono_string_to_utf8_image") +#pragma comment(linker, "/export:mono_string_to_utf8str") +#pragma comment(linker, "/export:mono_string_to_utf8str_handle") +#pragma comment(linker, "/export:mono_string_utf16_to_builder") +#pragma comment(linker, "/export:mono_string_utf16_to_builder2") +#pragma comment(linker, "/export:mono_string_utf8_to_builder") +#pragma comment(linker, "/export:mono_string_utf8_to_builder2") +#pragma comment(linker, "/export:mono_thread_attach") +#pragma comment(linker, "/export:mono_thread_attach_aborted_cb") +#pragma comment(linker, "/export:mono_thread_callbacks_init") +#pragma comment(linker, "/export:mono_thread_cleanup") +#pragma comment(linker, "/export:mono_thread_cleanup_apartment_state") +#pragma comment(linker, "/export:mono_thread_clear_and_set_state") +#pragma comment(linker, "/export:mono_thread_clr_state") +#pragma comment(linker, "/export:mono_thread_create") +#pragma comment(linker, "/export:mono_thread_create_checked") +#pragma comment(linker, "/export:mono_thread_create_internal") +#pragma comment(linker, "/export:mono_thread_create_internal_handle") +#pragma comment(linker, "/export:mono_thread_current") +#pragma comment(linker, "/export:mono_thread_current_check_pending_interrupt") +#pragma comment(linker, "/export:mono_thread_detach") +#pragma comment(linker, "/export:mono_thread_detach_if_exiting") +#pragma comment(linker, "/export:mono_thread_exit") +#pragma comment(linker, "/export:mono_thread_force_interruption_checkpoint_noraise") +#pragma comment(linker, "/export:mono_thread_get_main") +#pragma comment(linker, "/export:mono_thread_get_managed_id") +#pragma comment(linker, "/export:mono_thread_get_name") +#pragma comment(linker, "/export:mono_thread_get_name_utf8") +#pragma comment(linker, "/export:mono_thread_get_undeniable_exception") +#pragma comment(linker, "/export:mono_thread_has_appdomain_ref") +#pragma comment(linker, "/export:mono_thread_hazardous_queue_free") +#pragma comment(linker, "/export:mono_thread_hazardous_try_free") +#pragma comment(linker, "/export:mono_thread_hazardous_try_free_all") +#pragma comment(linker, "/export:mono_thread_hazardous_try_free_some") +#pragma comment(linker, "/export:mono_thread_init") +#pragma comment(linker, "/export:mono_thread_init_apartment_state") +#pragma comment(linker, "/export:mono_thread_interruption_checkpoint") +#pragma comment(linker, "/export:mono_thread_interruption_checkpoint_bool") +#pragma comment(linker, "/export:mono_thread_interruption_checkpoint_void") +#pragma comment(linker, "/export:mono_thread_interruption_request_flag") +#pragma comment(linker, "/export:mono_thread_interruption_requested") +#pragma comment(linker, "/export:mono_thread_is_foreign") +#pragma comment(linker, "/export:mono_thread_is_gc_unsafe_mode") +#pragma comment(linker, "/export:mono_thread_join") +#pragma comment(linker, "/export:mono_thread_manage") +#pragma comment(linker, "/export:mono_thread_new_init") +#pragma comment(linker, "/export:mono_thread_platform_create_thread") +#pragma comment(linker, "/export:mono_thread_pop_appdomain_ref") +#pragma comment(linker, "/export:mono_thread_push_appdomain_ref") +#pragma comment(linker, "/export:mono_thread_set_main") +#pragma comment(linker, "/export:mono_thread_set_manage_callback") +#pragma comment(linker, "/export:mono_thread_set_name_internal") +#pragma comment(linker, "/export:mono_thread_set_state") +#pragma comment(linker, "/export:mono_thread_small_id_alloc") +#pragma comment(linker, "/export:mono_thread_small_id_free") +#pragma comment(linker, "/export:mono_thread_smr_cleanup") +#pragma comment(linker, "/export:mono_thread_smr_init") +#pragma comment(linker, "/export:mono_thread_stop") +#pragma comment(linker, "/export:mono_thread_test_and_set_state") +#pragma comment(linker, "/export:mono_thread_test_state") +#pragma comment(linker, "/export:mono_type_array_get_and_resolve") +#pragma comment(linker, "/export:mono_type_create_from_typespec") +#pragma comment(linker, "/export:mono_type_create_from_typespec_checked") +#pragma comment(linker, "/export:mono_type_full_name") +#pragma comment(linker, "/export:mono_type_generic_inst_is_valuetype") +#pragma comment(linker, "/export:mono_type_get_array_type") +#pragma comment(linker, "/export:mono_type_get_basic_type_from_generic") +#pragma comment(linker, "/export:mono_type_get_checked") +#pragma comment(linker, "/export:mono_type_get_class") +#pragma comment(linker, "/export:mono_type_get_cmods") +#pragma comment(linker, "/export:mono_type_get_desc") +#pragma comment(linker, "/export:mono_type_get_full_name") +#pragma comment(linker, "/export:mono_type_get_modifiers") +#pragma comment(linker, "/export:mono_type_get_name") +#pragma comment(linker, "/export:mono_type_get_name_full") +#pragma comment(linker, "/export:mono_type_get_object") +#pragma comment(linker, "/export:mono_type_get_object_checked") +#pragma comment(linker, "/export:mono_type_get_object_handle") +#pragma comment(linker, "/export:mono_type_get_ptr_type") +#pragma comment(linker, "/export:mono_type_get_signature") +#pragma comment(linker, "/export:mono_type_get_type") +#pragma comment(linker, "/export:mono_type_get_underlying_type") +#pragma comment(linker, "/export:mono_type_has_exceptions") +#pragma comment(linker, "/export:mono_type_in_image") +#pragma comment(linker, "/export:mono_type_initialization_cleanup") +#pragma comment(linker, "/export:mono_type_initialization_init") +#pragma comment(linker, "/export:mono_type_is_byref") +#pragma comment(linker, "/export:mono_type_is_from_assembly") +#pragma comment(linker, "/export:mono_type_is_generic_parameter") +#pragma comment(linker, "/export:mono_type_is_pointer") +#pragma comment(linker, "/export:mono_type_is_primitive") +#pragma comment(linker, "/export:mono_type_is_reference") +#pragma comment(linker, "/export:mono_type_is_struct") +#pragma comment(linker, "/export:mono_type_is_valid_enum_basetype") +#pragma comment(linker, "/export:mono_type_is_void") +#pragma comment(linker, "/export:mono_type_native_stack_size") +#pragma comment(linker, "/export:mono_type_set_alignment") +#pragma comment(linker, "/export:mono_type_size") +#pragma comment(linker, "/export:mono_type_stack_size") +#pragma comment(linker, "/export:mono_type_stack_size_internal") +#pragma comment(linker, "/export:mono_value_box") +#pragma comment(linker, "/export:mono_value_copy") +#pragma comment(linker, "/export:mono_value_copy_array") +#pragma comment(linker, "/export:mono_jit_info_get_code_start") +#pragma comment(linker, "/export:mono_jit_info_get_code_size") + +#endif diff --git a/Source/Engine/Scripting/Runtime/None.cpp b/Source/Engine/Scripting/Runtime/None.cpp new file mode 100644 index 000000000..db902a634 --- /dev/null +++ b/Source/Engine/Scripting/Runtime/None.cpp @@ -0,0 +1,537 @@ +// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. + +#include "Engine/Scripting/Types.h" + +#if !USE_CSHARP + +#include "Engine/Scripting/ManagedCLR/MCore.h" +#include "Engine/Scripting/ManagedCLR/MDomain.h" +#include "Engine/Scripting/ManagedCLR/MAssembly.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MDomain.h" +#include "Engine/Scripting/ManagedCLR/MEvent.h" +#include "Engine/Scripting/ManagedCLR/MException.h" +#include "Engine/Scripting/ManagedCLR/MField.h" +#include "Engine/Scripting/ManagedCLR/MMethod.h" +#include "Engine/Scripting/ManagedCLR/MProperty.h" + +extern MDomain* MRootDomain; +extern Array> MDomains; + +MDomain* MCore::CreateDomain(const StringAnsi& domainName) +{ + for (int32 i = 0; i < MDomains.Count(); i++) + { + if (MDomains[i]->GetName() == domainName) + return MDomains[i]; + } + auto domain = New(domainName); + MDomains.Add(domain); + return domain; +} + +void MCore::UnloadDomain(const StringAnsi& domainName) +{ + int32 i = 0; + for (; i < MDomains.Count(); i++) + { + if (MDomains[i]->GetName() == domainName) + break; + } + if (i == MDomains.Count()) + return; + + auto domain = MDomains[i]; + Delete(domain); + MDomains.RemoveAtKeepOrder(i); +} + +bool MCore::LoadEngine() +{ + MRootDomain = New("Root"); + MDomains.Add(MRootDomain); + return false; +} + +void MCore::UnloadEngine() +{ + MDomains.ClearDelete(); + MRootDomain = nullptr; +} + +MObject* MCore::Object::Box(void* value, const MClass* klass) +{ + return nullptr; +} + +void* MCore::Object::Unbox(MObject* obj) +{ + return nullptr; +} + +MObject* MCore::Object::New(const MClass* klass) +{ + return nullptr; +} + +void MCore::Object::Init(MObject* obj) +{ +} + +MClass* MCore::Object::GetClass(MObject* obj) +{ + return nullptr; +} + +MString* MCore::Object::ToString(MObject* obj) +{ + return nullptr; +} + +int32 MCore::Object::GetHashCode(MObject* obj) +{ + return 0; +} + +MString* MCore::String::GetEmpty(MDomain* domain) +{ + return nullptr; +} + +MString* MCore::String::New(const char* str, int32 length, MDomain* domain) +{ + return nullptr; +} + +MString* MCore::String::New(const Char* str, int32 length, MDomain* domain) +{ + return nullptr; +} + +StringView MCore::String::GetChars(MString* obj) +{ + return StringView::Empty; +} + +MArray* MCore::Array::New(const MClass* elementKlass, int32 length) +{ + return nullptr; +} + +MClass* MCore::Array::GetClass(MClass* elementKlass) +{ + return nullptr; +} + +int32 MCore::Array::GetLength(const MArray* obj) +{ + return 0; +} + +void* MCore::Array::GetAddress(const MArray* obj) +{ + return nullptr; +} + +MGCHandle MCore::GCHandle::New(MObject* obj, bool pinned) +{ + return (MGCHandle)(uintptr)obj; +} + +MGCHandle MCore::GCHandle::NewWeak(MObject* obj, bool trackResurrection) +{ + return (MGCHandle)(uintptr)obj; +} + +MObject* MCore::GCHandle::GetTarget(const MGCHandle& handle) +{ + return (MObject*)(uintptr)handle; +} + +void MCore::GCHandle::Free(const MGCHandle& handle) +{ +} + +void MCore::GC::Collect() +{ +} + +void MCore::GC::Collect(int32 generation) +{ +} + +void MCore::GC::WaitForPendingFinalizers() +{ +} + +void MCore::GC::WriteRef(void* ptr, MObject* ref) +{ +} + +void MCore::GC::WriteValue(void* dst, void* src, int32 count, const MClass* klass) +{ +} + +void MCore::GC::WriteArrayRef(MArray* dst, MObject* ref, int32 index) +{ +} + +void MCore::Thread::Attach() +{ +} + +void MCore::Thread::Exit() +{ +} + +bool MCore::Thread::IsAttached() +{ + return true; +} + +void MCore::Exception::Throw(MObject* exception) +{ +} + +MObject* MCore::Exception::GetNullReference() +{ + return nullptr; +} + +MObject* MCore::Exception::Get(const char* msg) +{ + return nullptr; +} + +MObject* MCore::Exception::GetArgument(const char* arg, const char* msg) +{ + return nullptr; +} + +MObject* MCore::Exception::GetArgumentNull(const char* arg) +{ + return nullptr; +} + +MObject* MCore::Exception::GetArgumentOutOfRange(const char* arg) +{ + return nullptr; +} + +MObject* MCore::Exception::GetNotSupported(const char* msg) +{ + return nullptr; +} + +const MAssembly::ClassesDictionary& MAssembly::GetClasses() const +{ + _hasCachedClasses = true; + return _classes; +} + +bool MAssembly::LoadCorlib() +{ + return false; +} + +bool MAssembly::LoadImage(const String& assemblyPath) +{ + _hasCachedClasses = false; + _assemblyPath = assemblyPath; + return false; +} + +bool MAssembly::UnloadImage(bool isReloading) +{ + return false; +} + +MClass::~MClass() +{ + _fields.ClearDelete(); + _properties.ClearDelete(); + _methods.ClearDelete(); + _events.ClearDelete(); +} + +MClass* MClass::GetBaseClass() const +{ + return nullptr; +} + +bool MClass::IsSubClassOf(const MClass* klass, bool checkInterfaces) const +{ + return false; +} + +bool MClass::HasInterface(const MClass* klass) const +{ + return false; +} + +bool MClass::IsInstanceOfType(MObject* object) const +{ + return false; +} + +uint32 MClass::GetInstanceSize() const +{ + return 0; +} + +MMethod* MClass::GetMethod(const char* name, int32 numParams) const +{ + return nullptr; +} + +const Array& MClass::GetMethods() const +{ + _hasCachedMethods = true; + return _methods; +} + +MField* MClass::GetField(const char* name) const +{ + return nullptr; +} + +const Array& MClass::GetFields() const +{ + _hasCachedFields = true; + return _fields; +} + +const Array& MClass::GetEvents() const +{ + _hasCachedEvents = true; + return _events; +} + +MProperty* MClass::GetProperty(const char* name) const +{ + return nullptr; +} + +const Array& MClass::GetProperties() const +{ + _hasCachedProperties = true; + return _properties; +} + +bool MClass::HasAttribute(const MClass* monoClass) const +{ + return false; +} + +bool MClass::HasAttribute() const +{ + return false; +} + +MObject* MClass::GetAttribute(const MClass* monoClass) const +{ + return nullptr; +} + +const Array& MClass::GetAttributes() const +{ + _hasCachedAttributes = true; + return _attributes; +} + +bool MDomain::SetCurrentDomain(bool force) +{ + extern MDomain* MActiveDomain; + MActiveDomain = this; + return true; +} + +void MDomain::Dispatch() const +{ +} + +MMethod* MEvent::GetAddMethod() const +{ + return _addMethod; +} + +MMethod* MEvent::GetRemoveMethod() const +{ + return _removeMethod; +} + +bool MEvent::HasAttribute(MClass* monoClass) const +{ + return false; +} + +bool MEvent::HasAttribute() const +{ + return false; +} + +MObject* MEvent::GetAttribute(MClass* monoClass) const +{ + return nullptr; +} + +const Array& MEvent::GetAttributes() const +{ + return _attributes; +} + +MException::MException(MObject* exception) + : InnerException(nullptr) +{ +} + +MException::~MException() +{ +} + +MType* MField::GetType() const +{ + return nullptr; +} + +int32 MField::GetOffset() const +{ + return 0; +} + +void MField::GetValue(MObject* instance, void* result) const +{ +} + +MObject* MField::GetValueBoxed(MObject* instance) const +{ + return nullptr; +} + +void MField::SetValue(MObject* instance, void* value) const +{ +} + +bool MField::HasAttribute(MClass* monoClass) const +{ + return false; +} + +bool MField::HasAttribute() const +{ + return false; +} + +MObject* MField::GetAttribute(MClass* monoClass) const +{ + return nullptr; +} + +const Array& MField::GetAttributes() const +{ + return _attributes; +} + +MObject* MMethod::Invoke(void* instance, void** params, MObject** exception) const +{ + return nullptr; +} + +MObject* MMethod::InvokeVirtual(MObject* instance, void** params, MObject** exception) const +{ + return nullptr; +} + +MMethod* MMethod::InflateGeneric() const +{ + return nullptr; +} + +MType* MMethod::GetReturnType() const +{ + return nullptr; +} + +int32 MMethod::GetParametersCount() const +{ + return 0; +} + +MType* MMethod::GetParameterType(int32 paramIdx) const +{ + return nullptr; +} + +bool MMethod::GetParameterIsOut(int32 paramIdx) const +{ + return false; +} + +bool MMethod::HasAttribute(MClass* monoClass) const +{ + return false; +} + +bool MMethod::HasAttribute() const +{ + return false; +} + +MObject* MMethod::GetAttribute(MClass* monoClass) const +{ + return nullptr; +} + +const Array& MMethod::GetAttributes() const +{ + return _attributes; +} + +MProperty::~MProperty() +{ + if (_getMethod) + Delete(_getMethod); + if (_setMethod) + Delete(_setMethod); +} + +MMethod* MProperty::GetGetMethod() const +{ + return _getMethod; +} + +MMethod* MProperty::GetSetMethod() const +{ + return _setMethod; +} + +MObject* MProperty::GetValue(MObject* instance, MObject** exception) const +{ + return nullptr; +} + +void MProperty::SetValue(MObject* instance, void* value, MObject** exception) const +{ +} + +bool MProperty::HasAttribute(MClass* monoClass) const +{ + return false; +} + +bool MProperty::HasAttribute() const +{ + return false; +} + +MObject* MProperty::GetAttribute(MClass* monoClass) const +{ + return nullptr; +} + +const Array& MProperty::GetAttributes() const +{ + return _attributes; +} + +#endif diff --git a/Source/Engine/Scripting/Script.cpp b/Source/Engine/Scripting/Script.cpp index 16931b14d..3f8df354c 100644 --- a/Source/Engine/Scripting/Script.cpp +++ b/Source/Engine/Scripting/Script.cpp @@ -3,7 +3,7 @@ #include "Script.h" #include "Engine/Core/Log.h" #if USE_EDITOR -#include "StdTypesContainer.h" +#include "Internal/StdTypesContainer.h" #include "ManagedCLR/MClass.h" #include "Editor/Editor.h" #endif diff --git a/Source/Engine/Scripting/Scripting.Build.cs b/Source/Engine/Scripting/Scripting.Build.cs index c3c98599d..21f4477d0 100644 --- a/Source/Engine/Scripting/Scripting.Build.cs +++ b/Source/Engine/Scripting/Scripting.Build.cs @@ -17,9 +17,9 @@ public class Scripting : EngineModule { if (EngineConfiguration.WithDotNet(options)) { + // .NET options.PrivateDependencies.Add("nethost"); options.ScriptingAPI.Defines.Add("USE_NETCORE"); - options.PublicDefinitions.Add("USE_NETCORE"); if (options.Target is EngineTarget engineTarget && engineTarget.UseSeparateMainExecutable(options)) { @@ -30,7 +30,9 @@ public class Scripting : EngineModule } else { - options.PublicDependencies.Add("mono"); + // Mono + options.PrivateDependencies.Add("mono"); + options.ScriptingAPI.Defines.Add("USE_MONO"); } } diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index 3741d5e6d..63c0b6fa6 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -2,7 +2,6 @@ #include "BinaryModule.h" #include "Scripting.h" -#include "StdTypesContainer.h" #include "ScriptingType.h" #include "FlaxEngine.Gen.h" #include "Engine/Threading/Threading.h" @@ -20,7 +19,8 @@ #include "ManagedCLR/MMethod.h" #include "ManagedCLR/MDomain.h" #include "ManagedCLR/MCore.h" -#include "MException.h" +#include "ManagedCLR/MException.h" +#include "Internal/StdTypesContainer.h" #include "Engine/Core/ObjectsRemovalService.h" #include "Engine/Core/Types/TimeSpan.h" #include "Engine/Profiler/ProfilerCPU.h" @@ -29,14 +29,8 @@ #include "Engine/Engine/EngineService.h" #include "Engine/Engine/Globals.h" #include "Engine/Graphics/RenderTask.h" +#include "Engine/Platform/MemoryStats.h" #include "Engine/Serialization/JsonTools.h" -#if USE_MONO -#include -#include -#endif -#if USE_NETCORE -#include "DotNet/CoreCLR.h" -#endif extern void registerFlaxEngineInternalCalls(); @@ -392,7 +386,7 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde else { // Create module if native library is not used - module = New(nameAnsi, MAssemblyOptions()); + module = New(nameAnsi); _nonNativeModules.Add(module); } } @@ -401,18 +395,11 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde // C# if (managedPath.HasChars() && !((ManagedBinaryModule*)module)->Assembly->IsLoaded()) { - if (((ManagedBinaryModule*)module)->Assembly->Load(managedPath)) + if (((ManagedBinaryModule*)module)->Assembly->Load(managedPath, nativePath)) { LOG(Error, "Failed to load C# assembly '{0}' for binary module {1}.", managedPath, name); return true; } -#if USE_NETCORE - // Provide new path of hot-reloaded native library path for managed DllImport - if (nativePath.HasChars()) - { - CoreCLR::RegisterNativeLibrary(nameAnsi.Get(), StringAnsi(nativePath).Get()); - } -#endif } #endif @@ -429,13 +416,46 @@ bool Scripting::Load() // Note: this action can be called from main thread (due to Mono problems with assemblies actions from other threads) ASSERT(IsInMainThread()); -#if !COMPILE_WITHOUT_CSHARP +#if USE_CSHARP // Load C# core assembly - if (GetBinaryModuleCorlib()->Assembly->Load(mono_get_corlib())) + ManagedBinaryModule* corlib = GetBinaryModuleCorlib(); + if (corlib->Assembly->LoadCorlib()) { LOG(Error, "Failed to load corlib C# assembly."); return true; } + + // Initialize C# corelib types + { + const auto& corlibClasses = corlib->Assembly->GetClasses(); + bool gotAll = true; +#define CACHE_CORLIB_CLASS(var, name) gotAll &= corlibClasses.TryGet(StringAnsiView(name), MCore::TypeCache::var) + CACHE_CORLIB_CLASS(Void, "System.Void"); + CACHE_CORLIB_CLASS(Object, "System.Object"); + CACHE_CORLIB_CLASS(Byte, "System.Byte"); + CACHE_CORLIB_CLASS(Boolean, "System.Boolean"); + CACHE_CORLIB_CLASS(SByte, "System.SByte"); + CACHE_CORLIB_CLASS(Char, "System.Char"); + CACHE_CORLIB_CLASS(Int16, "System.Int16"); + CACHE_CORLIB_CLASS(UInt16, "System.UInt16"); + CACHE_CORLIB_CLASS(Int32, "System.Int32"); + CACHE_CORLIB_CLASS(UInt32, "System.UInt32"); + CACHE_CORLIB_CLASS(Int64, "System.Int64"); + CACHE_CORLIB_CLASS(UInt64, "System.UInt64"); + CACHE_CORLIB_CLASS(IntPtr, "System.IntPtr"); + CACHE_CORLIB_CLASS(UIntPtr, "System.UIntPtr"); + CACHE_CORLIB_CLASS(Single, "System.Single"); + CACHE_CORLIB_CLASS(Double, "System.Double"); + CACHE_CORLIB_CLASS(String, "System.String"); +#undef CACHE_CORLIB_CLASS + if (!gotAll) + { + LOG(Error, "Failed to load corlib C# assembly."); + for (const auto& e : corlibClasses) + LOG(Info, "Class: {0}", String(e.Value->GetFullName())); + return true; + } + } #endif // Load FlaxEngine @@ -671,48 +691,6 @@ MClass* Scripting::FindClass(const StringAnsiView& fullname) return nullptr; } -#if USE_MONO - -MClass* Scripting::FindClass(MonoClass* monoClass) -{ - if (monoClass == nullptr) - return nullptr; - PROFILE_CPU(); - auto& modules = BinaryModule::GetModules(); - for (auto module : modules) - { - auto managedModule = dynamic_cast(module); - if (managedModule && managedModule->Assembly->IsLoaded()) - { - MClass* result = managedModule->Assembly->GetClass(monoClass); - if (result != nullptr) - return result; - } - } - return nullptr; -} - -MonoClass* Scripting::FindClassNative(const StringAnsiView& fullname) -{ - if (fullname.IsEmpty()) - return nullptr; - PROFILE_CPU(); - auto& modules = BinaryModule::GetModules(); - for (auto module : modules) - { - auto managedModule = dynamic_cast(module); - if (managedModule && managedModule->Assembly->IsLoaded()) - { - MClass* result = managedModule->Assembly->GetClass(fullname); - if (result != nullptr) - return result->GetNative(); - } - } - return nullptr; -} - -#endif - ScriptingTypeHandle Scripting::FindScriptingType(const StringAnsiView& fullname) { if (fullname.IsEmpty()) @@ -754,21 +732,20 @@ ScriptingObject* Scripting::NewObject(const MClass* type) LOG(Error, "Invalid type."); return nullptr; } -#if USE_MONO +#if USE_CSHARP // Get the assembly with that class - MonoClass* typeClass = type->GetNative(); - auto module = ManagedBinaryModule::FindModule(typeClass); + auto module = ManagedBinaryModule::FindModule(type); if (module == nullptr) { - LOG(Error, "Cannot find scripting assembly for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Cannot find scripting assembly for type \'{0}\'.", String(type->GetFullName())); return nullptr; } // Try to find the scripting type for this class int32 typeIndex; - if (!module->ClassToTypeIndex.TryGet(typeClass, typeIndex)) + if (!module->ClassToTypeIndex.TryGet(type, typeIndex)) { - LOG(Error, "Cannot spawn objects of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Cannot spawn objects of type \'{0}\'.", String(type->GetFullName())); return nullptr; } const ScriptingType& scriptingType = module->Types[typeIndex]; diff --git a/Source/Engine/Scripting/Scripting.cs b/Source/Engine/Scripting/Scripting.cs index 410f372f5..d5f2f7fb2 100644 --- a/Source/Engine/Scripting/Scripting.cs +++ b/Source/Engine/Scripting/Scripting.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; @@ -215,6 +216,11 @@ namespace FlaxEngine return ManagedHandle.Alloc(version); } + internal static ManagedHandle CultureInfoToManaged(int lcid) + { + return ManagedHandle.Alloc(new CultureInfo(lcid)); + } + internal static void VersionToNative(ManagedHandle versionHandle, IntPtr nativePtr) { Version version = Unsafe.As(versionHandle.Target); diff --git a/Source/Engine/Scripting/Scripting.h b/Source/Engine/Scripting/Scripting.h index 0d12737cd..cc2bdadf1 100644 --- a/Source/Engine/Scripting/Scripting.h +++ b/Source/Engine/Scripting/Scripting.h @@ -86,22 +86,6 @@ public: /// The MClass object or null if missing. static MClass* FindClass(const StringAnsiView& fullname); -#if USE_MONO - /// - /// Finds the class from the given Mono class object within whole assembly. - /// - /// The Mono class. - /// The MClass object or null if missing. - static MClass* FindClass(MonoClass* monoClass); - - /// - /// Finds the native class with given fully qualified name within whole assembly. - /// - /// The full name of the type eg: System.Int64. - /// The MClass object or null if missing. - static MonoClass* FindClassNative(const StringAnsiView& fullname); -#endif - /// /// Finds the scripting type of the given fullname by searching loaded scripting assemblies. /// diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index bfe4b36c3..785487f23 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -3,7 +3,6 @@ #include "ScriptingObject.h" #include "Scripting.h" #include "BinaryModule.h" -#include "InternalCalls.h" #include "Engine/Level/Actor.h" #include "Engine/Core/Log.h" #include "Engine/Utilities/StringConverter.h" @@ -15,11 +14,8 @@ #include "ManagedCLR/MUtils.h" #include "ManagedCLR/MField.h" #include "ManagedCLR/MCore.h" +#include "Internal/InternalCalls.h" #include "FlaxEngine.Gen.h" -#if USE_MONO -#include -#include -#endif #define ScriptingObject_unmanagedPtr "__unmanagedPtr" #define ScriptingObject_id "__internalId" @@ -73,8 +69,8 @@ MObject* ScriptingObject::GetManagedInstance() const #elif USE_MONO const MGCHandle handle = Platform::AtomicRead((int32*)&_gcHandle); #endif -#if USE_MONO - return handle ? MUtils::GetGCHandleTarget(handle) : nullptr; +#if USE_CSHARP + return handle ? MCore::GCHandle::GetTarget(handle) : nullptr; #else return nullptr; #endif @@ -180,13 +176,13 @@ void* ScriptingObject::ToInterface(ScriptingObject* obj, const ScriptingTypeHand ScriptingObject* ScriptingObject::ToNative(MObject* obj) { ScriptingObject* ptr = nullptr; -#if USE_MONO +#if USE_CSHARP if (obj) { // TODO: cache the field offset from object and read directly from object pointer - const auto ptrField = mono_class_get_field_from_name(mono_object_get_class(obj), ScriptingObject_unmanagedPtr); + const auto ptrField = MCore::Object::GetClass(obj)->GetField(ScriptingObject_unmanagedPtr); CHECK_RETURN(ptrField, nullptr); - mono_field_get_value(obj, ptrField, &ptr); + ptrField->GetValue(obj, &ptr); } #endif return ptr; @@ -227,7 +223,7 @@ void ScriptingObject::SetManagedInstance(MObject* instance) #if USE_NETCORE _gcHandle = (MGCHandle)instance; #elif !COMPILE_WITHOUT_CSHARP - _gcHandle = MUtils::NewGCHandle(instance, false); + _gcHandle = MCore::GCHandle::New(instance, false); #endif } @@ -236,8 +232,8 @@ void ScriptingObject::OnManagedInstanceDeleted() // Release the handle if (_gcHandle) { -#if USE_MONO - MUtils::FreeGCHandle(_gcHandle); +#if USE_CSHARP + MCore::GCHandle::Free(_gcHandle); #endif _gcHandle = 0; } @@ -257,8 +253,8 @@ void ScriptingObject::OnScriptingDispose() bool ScriptingObject::CreateManaged() { -#if USE_MONO - MonoObject* managedInstance = CreateManagedInternal(); +#if USE_CSHARP + MObject* managedInstance = CreateManagedInternal(); if (!managedInstance) return true; @@ -268,7 +264,7 @@ bool ScriptingObject::CreateManaged() auto oldHandle = Platform::InterlockedCompareExchange((int64*)&_gcHandle, *(int64*)&handle, 0); if (*(uint64*)&oldHandle != 0) #else - auto handle = MUtils::NewGCHandle(managedInstance, false); + auto handle = MCore::GCHandle::New(managedInstance, false); auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0); if (*(uint32*)&oldHandle != 0) #endif @@ -284,7 +280,7 @@ bool ScriptingObject::CreateManaged() monoUnmanagedPtrField->SetValue(managedInstance, ¶m); } } - MUtils::FreeGCHandle(handle); + MCore::GCHandle::Free(handle); return true; } #endif @@ -296,9 +292,9 @@ bool ScriptingObject::CreateManaged() return false; } -#if USE_MONO +#if USE_CSHARP -MonoObject* ScriptingObject::CreateManagedInternal() +MObject* ScriptingObject::CreateManagedInternal() { // Get class MClass* monoClass = GetClass(); @@ -309,15 +305,10 @@ MonoObject* ScriptingObject::CreateManagedInternal() } // Ensure to have managed domain attached (this can be called from custom native thread, eg. content loader) - auto domain = mono_domain_get(); - if (!domain) - { - MCore::AttachThread(); - domain = mono_domain_get(); - } + MCore::Thread::Attach(); // Allocate managed instance - MonoObject* managedInstance = mono_object_new(domain, monoClass->GetNative()); + MObject* managedInstance = MCore::Object::New(monoClass); if (managedInstance == nullptr) { LOG(Warning, "Failed to create new instance of the object of type {0}", String(monoClass->GetFullName())); @@ -339,7 +330,7 @@ MonoObject* ScriptingObject::CreateManagedInternal() } // Initialize managed instance (calls constructor) - mono_runtime_object_init(managedInstance); + MCore::Object::Init(managedInstance); return managedInstance; } @@ -348,7 +339,7 @@ MonoObject* ScriptingObject::CreateManagedInternal() void ScriptingObject::DestroyManaged() { -#if USE_MONO +#if USE_CSHARP // Get managed instance const auto managedInstance = GetManagedInstance(); @@ -369,7 +360,7 @@ void ScriptingObject::DestroyManaged() // Clear the handle if (_gcHandle) { - MUtils::FreeGCHandle(_gcHandle); + MCore::GCHandle::Free(_gcHandle); _gcHandle = 0; } #else @@ -407,30 +398,12 @@ bool ScriptingObject::CanCast(const MClass* from, const MClass* to) #if PLATFORM_LINUX || PLATFORM_MAC // Cannot enter GC unsafe region if the thread is not attached - MCore::AttachThread(); + MCore::Thread::Attach(); #endif return from->IsSubClassOf(to); } -#if USE_MONO - -bool ScriptingObject::CanCast(const MClass* from, const MonoClass* to) -{ - if (!from && !to) - return true; - CHECK_RETURN(from && to, false); - -#if PLATFORM_LINUX - // Cannot enter GC unsafe region if the thread is not attached - MCore::AttachThread(); -#endif - - return from->IsSubClassOf(to); -} - -#endif - void ScriptingObject::OnDeleteObject() { // Cleanup managed object @@ -460,7 +433,7 @@ void ManagedScriptingObject::SetManagedInstance(MObject* instance) #if USE_NETCORE _gcHandle = (MGCHandle)instance; #elif !COMPILE_WITHOUT_CSHARP - _gcHandle = MUtils::NewGCHandleWeakref(instance, false); + _gcHandle = MCore::GCHandle::NewWeak(instance, false); #endif } @@ -484,8 +457,8 @@ void ManagedScriptingObject::OnScriptingDispose() bool ManagedScriptingObject::CreateManaged() { -#if USE_MONO - MonoObject* managedInstance = CreateManagedInternal(); +#if USE_CSHARP + MObject* managedInstance = CreateManagedInternal(); if (!managedInstance) return true; @@ -495,7 +468,7 @@ bool ManagedScriptingObject::CreateManaged() auto oldHandle = Platform::InterlockedCompareExchange((int64*)&_gcHandle, *(int64*)&handle, 0); if (*(uint64*)&oldHandle != 0) #else - auto handle = MUtils::NewGCHandleWeakref(managedInstance, false); + auto handle = MCore::GCHandle::NewWeak(managedInstance, false); auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0); if (*(uint32*)&oldHandle != 0) #endif @@ -511,7 +484,7 @@ bool ManagedScriptingObject::CreateManaged() monoUnmanagedPtrField->SetValue(managedInstance, ¶m); } } - MUtils::FreeGCHandle(handle); + MCore::GCHandle::Free(handle); return true; } #endif @@ -528,21 +501,21 @@ PersistentScriptingObject::PersistentScriptingObject(const SpawnParams& params) { } -#if !COMPILE_WITHOUT_CSHARP +#if USE_CSHARP -DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create1(MonoReflectionType* type) +DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create1(MTypeObject* type) { // Peek class for that type (handle generic class cases) if (!type) DebugLog::ThrowArgumentNull("type"); - MonoType* monoType = mono_reflection_type_get_type(type); - const int32 monoTypeType = mono_type_get_type(monoType); - if (monoTypeType == MONO_TYPE_GENERICINST) + MType* mType = INTERNAL_TYPE_OBJECT_GET(type); + const MTypes mTypeType = MCore::Type::GetType(mType); + if (mTypeType == MTypes::GenericInst) { LOG(Error, "Generic scripts are not supported."); return nullptr; } - MonoClass* typeClass = mono_type_get_class(monoType); + MClass* typeClass = MCore::Type::GetClass(mType); if (typeClass == nullptr) { LOG(Error, "Invalid type."); @@ -553,7 +526,7 @@ DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create1(MonoReflectionType* typ auto module = ManagedBinaryModule::FindModule(typeClass); if (module == nullptr) { - LOG(Error, "Cannot find scripting assembly for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Cannot find scripting assembly for type \'{0}\'.", String(typeClass->GetFullName())); return nullptr; } @@ -561,7 +534,7 @@ DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create1(MonoReflectionType* typ int32 typeIndex; if (!module->ClassToTypeIndex.TryGet(typeClass, typeIndex)) { - LOG(Error, "Cannot spawn objects of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Cannot spawn objects of type \'{0}\'.", String(typeClass->GetFullName())); return nullptr; } const ScriptingType& scriptingType = module->Types[typeIndex]; @@ -571,35 +544,36 @@ DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create1(MonoReflectionType* typ ScriptingObject* obj = scriptingType.Script.Spawn(params); if (obj == nullptr) { - LOG(Error, "Failed to spawn object of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Failed to spawn object of type \'{0}\'.", String(typeClass->GetFullName())); return nullptr; } // Set default name for actors if (auto* actor = dynamic_cast(obj)) { - actor->SetName(String(mono_class_get_name(typeClass))); + actor->SetName(String(typeClass->GetName())); } // Create managed object obj->CreateManaged(); - MonoObject* managedInstance = obj->GetManagedInstance(); + MObject* managedInstance = obj->GetManagedInstance(); if (managedInstance == nullptr) { - LOG(Error, "Cannot create managed instance for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Cannot create managed instance for type \'{0}\'.", String(typeClass->GetFullName())); Delete(obj); } return managedInstance; } -DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create2(MonoString* typeNameObj) +DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(MString* typeNameObj) { // Get typename if (typeNameObj == nullptr) DebugLog::ThrowArgumentNull("typeName"); - const StringAsANSI<> typeNameData((const Char*)mono_string_chars(typeNameObj), (int32)mono_string_length(typeNameObj)); - const StringAnsiView typeName(typeNameData.Get(), (int32)mono_string_length(typeNameObj)); + const StringView typeNameChars = MCore::String::GetChars(typeNameObj); + const StringAsANSI<100> typeNameData(typeNameChars.Get(), typeNameChars.Length()); + const StringAnsiView typeName(typeNameData.Get(), typeNameChars.Length()); // Try to find the scripting type for this typename const ScriptingTypeHandle type = Scripting::FindScriptingType(typeName); @@ -620,7 +594,7 @@ DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create2(MonoString* typeNameObj // Create managed object obj->CreateManaged(); - MonoObject* managedInstance = obj->GetManagedInstance(); + MObject* managedInstance = obj->GetManagedInstance(); if (managedInstance == nullptr) { LOG(Error, "Cannot create managed instance for type \'{0}\'.", String(typeName)); @@ -630,15 +604,15 @@ DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_Create2(MonoString* typeNameObj return managedInstance; } -DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MonoObject* managedInstance) +DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MObject* managedInstance) { - MonoClass* typeClass = mono_object_get_class(managedInstance); + MClass* typeClass = MCore::Object::GetClass(managedInstance); // Get the assembly with that class auto module = ManagedBinaryModule::FindModule(typeClass); if (module == nullptr) { - LOG(Error, "Cannot find scripting assembly for type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Cannot find scripting assembly for type \'{0}\'.", String(typeClass->GetFullName())); return; } @@ -646,7 +620,7 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MonoObject* man int32 typeIndex; if (!module->ClassToTypeIndex.TryGet(typeClass, typeIndex)) { - LOG(Error, "Cannot spawn objects of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Cannot spawn objects of type \'{0}\'.", String(typeClass->GetFullName())); return; } const ScriptingType& scriptingType = module->Types[typeIndex]; @@ -656,14 +630,14 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MonoObject* man ScriptingObject* obj = scriptingType.Script.Spawn(params); if (obj == nullptr) { - LOG(Error, "Failed to spawn object of type \'{0}.{1}\'.", String(mono_class_get_namespace(typeClass)), String(mono_class_get_name(typeClass))); + LOG(Error, "Failed to spawn object of type \'{0}\'.", String(typeClass->GetFullName())); return; } // Set default name for actors if (auto* actor = dynamic_cast(obj)) { - actor->SetName(String(mono_class_get_name(typeClass))); + actor->SetName(String(typeClass->GetName())); } // Link created managed instance to the unmanaged object @@ -706,21 +680,21 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_Destroy(ScriptingObject* obj, float ti obj->DeleteObject(timeLeft, useGameTime); } -DEFINE_INTERNAL_CALL(MonoString*) ObjectInternal_GetTypeName(ScriptingObject* obj) +DEFINE_INTERNAL_CALL(MString*) ObjectInternal_GetTypeName(ScriptingObject* obj) { INTERNAL_CALL_CHECK_RETURN(obj, nullptr); return MUtils::ToString(obj->GetType().Fullname); } -DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_FindObject(Guid* id, MonoReflectionType* type) +DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject* type) { if (!id->IsValid()) return nullptr; - auto klass = MUtils::GetClass(type); + MClass* klass = MUtils::GetClass(type); ScriptingObject* obj = Scripting::TryFindObject(*id); if (!obj) { - if (!klass || klass == ScriptingObject::GetStaticClass()->GetNative() || mono_class_is_subclass_of(klass, Asset::GetStaticClass()->GetNative(), false) != 0) + if (!klass || klass == ScriptingObject::GetStaticClass() || klass->IsSubClassOf(Asset::GetStaticClass())) { obj = Content::LoadAsync(*id); } @@ -729,19 +703,19 @@ DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_FindObject(Guid* id, MonoReflec { if (klass && !obj->Is(klass)) { - LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}.", *id, String(obj->GetType().Fullname), String(MUtils::GetClassFullname(klass))); + LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}.", *id, String(obj->GetType().Fullname), String(klass->GetFullName())); return nullptr; } return obj->GetOrCreateManagedInstance(); } if (klass) - LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}.", *id, String(MUtils::GetClassFullname(klass))); + LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}.", *id, String(klass->GetFullName())); else LOG(Warning, "Unable to find scripting object with ID={0}", *id); return nullptr; } -DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_TryFindObject(Guid* id, MonoReflectionType* type) +DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_TryFindObject(Guid* id, MTypeObject* type) { ScriptingObject* obj = Scripting::TryFindObject(*id); if (obj && !obj->Is(MUtils::GetClass(type))) @@ -755,11 +729,11 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_ChangeID(ScriptingObject* obj, Guid* i obj->ChangeID(*id); } -DEFINE_INTERNAL_CALL(void*) ObjectInternal_GetUnmanagedInterface(ScriptingObject* obj, MonoReflectionType* type) +DEFINE_INTERNAL_CALL(void*) ObjectInternal_GetUnmanagedInterface(ScriptingObject* obj, MTypeObject* type) { if (obj && type) { - auto typeClass = MUtils::GetClass(type); + MClass* typeClass = MUtils::GetClass(type); const ScriptingTypeHandle interfaceType = ManagedBinaryModule::FindType(typeClass); if (interfaceType) { @@ -769,9 +743,9 @@ DEFINE_INTERNAL_CALL(void*) ObjectInternal_GetUnmanagedInterface(ScriptingObject return nullptr; } -DEFINE_INTERNAL_CALL(MonoObject*) ObjectInternal_FromUnmanagedPtr(ScriptingObject* obj) +DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FromUnmanagedPtr(ScriptingObject* obj) { - MonoObject* result = nullptr; + MObject* result = nullptr; if (obj) result = obj->GetOrCreateManagedInstance(); return result; diff --git a/Source/Engine/Scripting/ScriptingObject.h b/Source/Engine/Scripting/ScriptingObject.h index a75ab539c..6332e13a4 100644 --- a/Source/Engine/Scripting/ScriptingObject.h +++ b/Source/Engine/Scripting/ScriptingObject.h @@ -152,9 +152,6 @@ public: /// The destination class to the cast. /// True if can, otherwise false. static bool CanCast(const MClass* from, const MClass* to); -#if USE_MONO - static bool CanCast(const MClass* from, const MonoClass* to); -#endif template static T* Cast(ScriptingObject* obj) @@ -169,13 +166,6 @@ public: return CanCast(GetClass(), type); } -#if USE_MONO - bool Is(MonoClass* klass) const - { - return CanCast(GetClass(), klass); - } -#endif - template bool Is() const { @@ -217,11 +207,11 @@ public: void UnregisterObject(); protected: -#if USE_MONO +#if USE_CSHARP /// /// Create a new managed object. /// - MonoObject* CreateManagedInternal(); + MObject* CreateManagedInternal(); #endif public: diff --git a/Source/Engine/Scripting/ScriptingType.h b/Source/Engine/Scripting/ScriptingType.h index fe2f53486..4b109173e 100644 --- a/Source/Engine/Scripting/ScriptingType.h +++ b/Source/Engine/Scripting/ScriptingType.h @@ -65,8 +65,8 @@ struct FLAXENGINE_API ScriptingTypeHandle String ToString(bool withAssembly = false) const; const ScriptingType& GetType() const; -#if USE_MONO - MonoClass* GetMonoClass() const; +#if USE_CSHARP + MClass* GetClass() const; #endif bool IsSubclassOf(ScriptingTypeHandle c) const; bool IsAssignableFrom(ScriptingTypeHandle c) const; diff --git a/Source/Engine/Scripting/Types.h b/Source/Engine/Scripting/Types.h index fad7367c3..3f0f3a606 100644 --- a/Source/Engine/Scripting/Types.h +++ b/Source/Engine/Scripting/Types.h @@ -19,51 +19,43 @@ class MMethod; class MProperty; class MEvent; class MDomain; -class MType; #if COMPILE_WITHOUT_CSHARP // No Scripting +#define USE_CSHARP 0 #define USE_MONO 0 #define USE_NETCORE 0 -typedef void MObject; + +// Dummy types declarations +typedef struct CSharpObject MObject; +typedef struct CSharpArray MArray; +typedef struct CSharpString MString; +typedef struct CSharpType MType; +typedef MType MTypeObject; typedef unsigned int MGCHandle; +#define INTERNAL_TYPE_GET_OBJECT(type) (type) +#define INTERNAL_TYPE_OBJECT_GET(type) (type) #else -#define USE_MONO 1 -#if COMPILE_WITH_MONO -#define USE_NETCORE 0 -#else -#define USE_NETCORE 1 -#endif - -// Enables using single (root) app domain for the user scripts -#define USE_SCRIPTING_SINGLE_DOMAIN 1 - -#if USE_MONO - -// Enables/disables profiling managed world via Mono -#define USE_MONO_PROFILER (COMPILE_WITH_PROFILER) - -// Enable/disable mono debugging -#define MONO_DEBUG_ENABLE (!BUILD_RELEASE && !USE_NETCORE) - #ifndef USE_MONO_AOT #define USE_MONO_AOT 0 #define USE_MONO_AOT_MODE MONO_AOT_MODE_NONE #endif -#if USE_NETCORE -struct _MonoDomain {}; -struct _MonoThread {}; -#endif +#if COMPILE_WITH_MONO -#if USE_NETCORE -typedef unsigned long long MGCHandle; -#else -typedef unsigned int MGCHandle; -#endif +// Mono scripting +#define USE_CSHARP 1 +#define USE_MONO 1 +#define USE_NETCORE 0 + +// Enables/disables profiling managed world via Mono +#define USE_MONO_PROFILER (COMPILE_WITH_PROFILER) + +// Enable/disable mono debugging +#define MONO_DEBUG_ENABLE (!BUILD_RELEASE) // Mono types declarations typedef struct _MonoClass MonoClass; @@ -82,7 +74,34 @@ typedef struct _MonoReflectionAssembly MonoReflectionAssembly; typedef struct _MonoException MonoException; typedef struct _MonoClassField MonoClassField; typedef MonoObject MObject; +typedef MonoArray MArray; +typedef MonoString MString; +typedef MonoType MType; +typedef MonoReflectionType MTypeObject; +typedef unsigned int MGCHandle; +#define INTERNAL_TYPE_GET_OBJECT(type) MCore::Type::GetObject(type) +#define INTERNAL_TYPE_OBJECT_GET(type) MCore::Type::Get(type) + +#else + +// .NET scripting +#define USE_CSHARP 1 +#define USE_MONO 0 +#define USE_NETCORE 1 + +// Dotnet types declarations +typedef struct DotNetObject MObject; +typedef struct DotNetArray MArray; +typedef struct DotNetString MString; +typedef struct DotNetType MType; +typedef MType MTypeObject; +typedef unsigned long long MGCHandle; +#define INTERNAL_TYPE_GET_OBJECT(type) (type) +#define INTERNAL_TYPE_OBJECT_GET(type) (type) #endif +// Enables using single (root) app domain for the user scripts +#define USE_SCRIPTING_SINGLE_DOMAIN 1 + #endif diff --git a/Source/Engine/Serialization/JsonWriter.h b/Source/Engine/Serialization/JsonWriter.h index 6e6c607cf..fd500cc14 100644 --- a/Source/Engine/Serialization/JsonWriter.h +++ b/Source/Engine/Serialization/JsonWriter.h @@ -78,6 +78,12 @@ public: String(buf.Get()); } + void String(const StringView& value) + { + const StringAsUTF8<256> buf(*value, value.Length()); + String(buf.Get()); + } + void String(const StringAnsi& value) { String(value.Get(), static_cast(value.Length())); @@ -85,7 +91,13 @@ public: FORCE_INLINE void RawValue(const StringAnsi& str) { - RawValue(str.Get(), static_cast(str.Length())); + RawValue(str.Get(), str.Length()); + } + + void RawValue(const StringView& str) + { + const StringAsUTF8<256> buf(*str, str.Length()); + RawValue(buf.Get(), buf.Length()); } FORCE_INLINE void RawValue(const CharType* json) diff --git a/Source/Engine/Serialization/Serialization.cpp b/Source/Engine/Serialization/Serialization.cpp index 2e0442408..ac8eb41a9 100644 --- a/Source/Engine/Serialization/Serialization.cpp +++ b/Source/Engine/Serialization/Serialization.cpp @@ -18,14 +18,12 @@ #include "Engine/Core/Math/Color.h" #include "Engine/Core/Math/Color32.h" #include "Engine/Core/Math/Matrix.h" -#include "Engine/Scripting/ManagedSerialization.h" +#include "Engine/Scripting/Internal/ManagedSerialization.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ScriptingObjectReference.h" #include "Engine/Content/Asset.h" #include "Engine/Utilities/Encryption.h" -#if USE_MONO -#include -#endif void ISerializable::DeserializeIfExists(DeserializeStream& stream, const char* memberName, ISerializeModifier* modifier) { @@ -216,12 +214,12 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari case VariantType::ManagedObject: case VariantType::Structure: { -#if USE_MONO - MonoObject* obj; +#if USE_CSHARP + MObject* obj; if (v.Type.Type == VariantType::Structure) obj = MUtils::BoxVariant(v); else - obj = (MonoObject*)v; + obj = (MObject*)v; ManagedSerialization::Serialize(stream, obj); #endif break; @@ -365,24 +363,24 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian case VariantType::ManagedObject: case VariantType::Structure: { -#if USE_MONO - auto obj = (MonoObject*)v; +#if USE_CSHARP + auto obj = (MObject*)v; if (!obj && v.Type.TypeName) { - MonoClass* klass = MUtils::GetClass(v.Type); + MClass* klass = MUtils::GetClass(v.Type); if (!klass) { LOG(Error, "Invalid variant type {0}", v.Type); return; } - obj = mono_object_new(mono_domain_get(), klass); + obj = MCore::Object::New(klass); if (!obj) { LOG(Error, "Failed to managed instance of the variant type {0}", v.Type); return; } - if (!mono_class_is_valuetype(klass)) - mono_runtime_object_init(obj); + if (!klass->IsValueType()) + MCore::Object::Init(obj); if (v.Type.Type == VariantType::ManagedObject) v.SetManagedObject(obj); } diff --git a/Source/Engine/Serialization/Stream.cpp b/Source/Engine/Serialization/Stream.cpp index 84b772f9a..30acc3d94 100644 --- a/Source/Engine/Serialization/Stream.cpp +++ b/Source/Engine/Serialization/Stream.cpp @@ -12,9 +12,10 @@ #include "Engine/Core/Cache.h" #include "Engine/Debug/Exceptions/JsonParseException.h" #include "Engine/Profiler/ProfilerCPU.h" -#include "Engine/Scripting/ManagedSerialization.h" +#include "Engine/Scripting/Internal/ManagedSerialization.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/ScriptingObject.h" +#include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" @@ -359,22 +360,22 @@ void ReadStream::Read(Variant& data) // Json StringAnsi json; ReadStringAnsi(&json, -71); -#if USE_MONO - MCore::AttachThread(); - MonoClass* klass = MUtils::GetClass(data.Type); +#if USE_CSHARP + MCore::Thread::Attach(); + MClass* klass = MUtils::GetClass(data.Type); if (!klass) { LOG(Error, "Invalid variant type {0}", data.Type); return; } - MonoObject* obj = mono_object_new(mono_domain_get(), klass); + MObject* obj = MCore::Object::New(klass); if (!obj) { LOG(Error, "Failed to managed instance of the variant type {0}", data.Type); return; } - if (!mono_class_is_valuetype(klass)) - mono_runtime_object_init(obj); + if (!klass->IsValueType()) + MCore::Object::Init(obj); ManagedSerialization::Deserialize(json, obj); if (data.Type.Type == VariantType::ManagedObject) data.SetManagedObject(obj); @@ -900,18 +901,18 @@ void WriteStream::Write(const Variant& data) case VariantType::ManagedObject: case VariantType::Structure: { -#if USE_MONO - MonoObject* obj; +#if USE_CSHARP + MObject* obj; if (data.Type.Type == VariantType::Structure) obj = MUtils::BoxVariant(data); else - obj = (MonoObject*)data; + obj = (MObject*)data; if (obj) { WriteByte(1); rapidjson_flax::StringBuffer json; CompactJsonWriter writerObj(json); - MCore::AttachThread(); + MCore::Thread::Attach(); ManagedSerialization::Serialize(writerObj, obj); WriteStringAnsi(StringAnsiView(json.GetString(), (int32)json.GetSize()), -71); } diff --git a/Source/Engine/Threading/JobSystem.cpp b/Source/Engine/Threading/JobSystem.cpp index f6df609ae..1e9e55b33 100644 --- a/Source/Engine/Threading/JobSystem.cpp +++ b/Source/Engine/Threading/JobSystem.cpp @@ -8,11 +8,8 @@ #include "Engine/Core/Collections/Dictionary.h" #include "Engine/Engine/EngineService.h" #include "Engine/Profiler/ProfilerCPU.h" +#if USE_CSHARP #include "Engine/Scripting/ManagedCLR/MCore.h" -#if USE_MONO -#include "Engine/Scripting/ManagedCLR/MDomain.h" -#include -#include #endif // Jobs storage perf info: @@ -161,7 +158,7 @@ int32 JobSystemThread::Run() Platform::SetThreadAffinityMask(1ull << Index); JobData data; - bool attachMonoThread = true; + bool attachCSharpThread = true; #if !JOB_SYSTEM_USE_MUTEX moodycamel::ConsumerToken consumerToken(Jobs); #endif @@ -190,13 +187,12 @@ int32 JobSystemThread::Run() if (data.Job.IsBinded()) { -#if USE_MONO +#if USE_CSHARP // Ensure to have C# thread attached to this thead (late init due to MCore being initialized after Job System) - if (attachMonoThread && !mono_domain_get()) + if (attachCSharpThread) { - const auto domain = MCore::GetActiveDomain(); - mono_thread_attach(domain->GetNative()); - attachMonoThread = false; + MCore::Thread::Attach(); + attachCSharpThread = false; } #endif diff --git a/Source/Engine/UI/UICanvas.cpp b/Source/Engine/UI/UICanvas.cpp index b6e4d5497..2aba929d6 100644 --- a/Source/Engine/UI/UICanvas.cpp +++ b/Source/Engine/UI/UICanvas.cpp @@ -1,13 +1,11 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "UICanvas.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" #include "Engine/Scripting/ManagedCLR/MClass.h" +#include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Serialization/Serialization.h" -#if USE_MONO -#include -#endif #if COMPILE_WITHOUT_CSHARP #define UICANVAS_INVOKE(event) @@ -85,7 +83,7 @@ void UICanvas::Serialize(SerializeStream& stream, const void* otherObj) params[0] = other ? other->GetOrCreateManagedInstance() : nullptr; MObject* exception = nullptr; auto method = other ? UICanvas_SerializeDiff : UICanvas_Serialize; - auto invokeResultStr = (MonoString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception); + auto invokeResultStr = (MString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception); if (exception) { MException ex(exception); @@ -98,9 +96,7 @@ void UICanvas::Serialize(SerializeStream& stream, const void* otherObj) else { // Write result data - auto invokeResultChars = mono_string_to_utf8(invokeResultStr); - stream.RawValue(invokeResultChars); - mono_free(invokeResultChars); + stream.RawValue(MCore::String::GetChars(invokeResultStr)); } #endif } @@ -118,9 +114,8 @@ void UICanvas::Deserialize(DeserializeStream& stream, ISerializeModifier* modifi rapidjson_flax::StringBuffer buffer; rapidjson_flax::Writer writer(buffer); dataMember->value.Accept(writer); - const auto str = buffer.GetString(); void* args[1]; - args[0] = mono_string_new(mono_domain_get(), str); + args[0] = MUtils::ToString(StringAnsiView(buffer.GetString(), (int32)buffer.GetSize())); MObject* exception = nullptr; UICanvas_Deserialize->Invoke(GetOrCreateManagedInstance(), args, &exception); if (exception) diff --git a/Source/Engine/UI/UIControl.cpp b/Source/Engine/UI/UIControl.cpp index 5eecfafb1..37fb2f95c 100644 --- a/Source/Engine/UI/UIControl.cpp +++ b/Source/Engine/UI/UIControl.cpp @@ -1,14 +1,12 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "UIControl.h" -#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/Scripting.h" +#include "Engine/Scripting/ManagedCLR/MException.h" #include "Engine/Scripting/ManagedCLR/MMethod.h" #include "Engine/Scripting/ManagedCLR/MClass.h" -#include "Engine/Scripting/Scripting.h" +#include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Serialization/Serialization.h" -#if USE_MONO -#include -#endif #if COMPILE_WITHOUT_CSHARP #define UICONTROL_INVOKE(event) @@ -80,12 +78,12 @@ void UIControl::Serialize(SerializeStream& stream, const void* otherObj) #if !COMPILE_WITHOUT_CSHARP void* params[2]; - MonoString* controlType = nullptr; + MString* controlType = nullptr; params[0] = &controlType; params[1] = other ? other->GetOrCreateManagedInstance() : nullptr; MObject* exception = nullptr; const auto method = other ? UIControl_SerializeDiff : UIControl_Serialize; - const auto invokeResultStr = (MonoString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception); + const auto invokeResultStr = (MString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception); if (exception) { MException ex(exception); @@ -107,19 +105,16 @@ void UIControl::Serialize(SerializeStream& stream, const void* otherObj) return; } - const auto controlTypeLength = mono_string_length(controlType); - if (controlTypeLength != 0) + const StringView controlTypeChars = MCore::String::GetChars(controlType); + if (controlTypeChars.Length() != 0) { stream.JKEY("Control"); - const auto controlTypeChars = mono_string_to_utf8(controlType); stream.String(controlTypeChars); - mono_free(controlTypeChars); } + const StringView invokeResultStrChars = MCore::String::GetChars(invokeResultStr); stream.JKEY("Data"); - const auto invokeResultChars = mono_string_to_utf8(invokeResultStr); - stream.RawValue(invokeResultChars); - mono_free(invokeResultChars); + stream.RawValue(invokeResultStrChars); #endif } @@ -134,15 +129,15 @@ void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modif DESERIALIZE_MEMBER(NavTargetRight, _navTargetRight); #if !COMPILE_WITHOUT_CSHARP - MonoReflectionType* typeObj = nullptr; + MTypeObject* typeObj = nullptr; const auto controlMember = stream.FindMember("Control"); if (controlMember != stream.MemberEnd()) { const StringAnsiView controlType(controlMember->value.GetStringAnsiView()); - const auto type = Scripting::FindClass(controlType); + const MClass* type = Scripting::FindClass(controlType); if (type != nullptr) { - typeObj = mono_type_get_object(mono_domain_get(), mono_class_get_type(type->GetNative())); + typeObj = INTERNAL_TYPE_GET_OBJECT(type->GetType()); } else { @@ -156,9 +151,8 @@ void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modif rapidjson_flax::StringBuffer buffer; rapidjson_flax::Writer writer(buffer); dataMember->value.Accept(writer); - const auto str = buffer.GetString(); void* args[2]; - args[0] = mono_string_new(mono_domain_get(), str); + args[0] = MCore::String::New(buffer.GetString(), (int32)buffer.GetSize()); args[1] = typeObj; MObject* exception = nullptr; UIControl_Deserialize->Invoke(GetOrCreateManagedInstance(), args, &exception); diff --git a/Source/Engine/Utilities/Utils.cs b/Source/Engine/Utilities/Utils.cs index 12a38586d..905680420 100644 --- a/Source/Engine/Utilities/Utils.cs +++ b/Source/Engine/Utilities/Utils.cs @@ -1023,7 +1023,7 @@ namespace FlaxEngine /// /// The method to get it's parameters. /// Method parameters array. - public static Type[] GetParameterTypes(this MethodInfo method) + public static Type[] GetParameterTypes(this MethodBase method) { Type[] parameterTypes; var parameters = method.GetParameters(); diff --git a/Source/Engine/Visject/VisjectGraph.cpp b/Source/Engine/Visject/VisjectGraph.cpp index 7a98dcb6e..597f761cd 100644 --- a/Source/Engine/Visject/VisjectGraph.cpp +++ b/Source/Engine/Visject/VisjectGraph.cpp @@ -9,7 +9,6 @@ #include "Engine/Engine/GameplayGlobals.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Level/Actor.h" -#include "Engine/Scripting/ManagedCLR/MType.h" #include "Engine/Scripting/ManagedCLR/MClass.h" #include "Engine/Scripting/ManagedCLR/MField.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" @@ -693,14 +692,14 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value) const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeNameAnsiView); if (!typeHandle) { -#if !COMPILE_WITHOUT_CSHARP +#if USE_CSHARP const auto mclass = Scripting::FindClass(typeNameAnsiView); if (mclass) { // Fallback to C#-only types - auto instance = (MonoObject*)structureValue; + auto instance = (MObject*)structureValue; CHECK(instance); - if (structureValue.Type.Type != VariantType::ManagedObject || mono_object_get_class(instance) != mclass->GetNative()) + if (structureValue.Type.Type != VariantType::ManagedObject || MCore::Object::GetClass(instance) != mclass) { OnError(node, box, String::Format(TEXT("Cannot unpack value of type {0} to structure of type {1}"), String(MUtils::GetClassFullname(instance)), typeName)); return; diff --git a/Source/FlaxEngine.Gen.cpp b/Source/FlaxEngine.Gen.cpp index d175cbc6a..6e0ce7876 100644 --- a/Source/FlaxEngine.Gen.cpp +++ b/Source/FlaxEngine.Gen.cpp @@ -7,6 +7,6 @@ StaticallyLinkedBinaryModuleInitializer StaticallyLinkedBinaryModuleFlaxEngine(G extern "C" BinaryModule* GetBinaryModuleFlaxEngine() { - static NativeBinaryModule module("FlaxEngine", MAssemblyOptions()); + static NativeBinaryModule module("FlaxEngine"); return &module; } diff --git a/Source/ThirdParty/mono-2.0/mono.Build.cs b/Source/ThirdParty/mono-2.0/mono.Build.cs index 53accc4e1..8819de7cb 100644 --- a/Source/ThirdParty/mono-2.0/mono.Build.cs +++ b/Source/ThirdParty/mono-2.0/mono.Build.cs @@ -28,6 +28,7 @@ public class mono : DepsModule base.Setup(options); var depsRoot = options.DepsFolder; + options.PublicIncludePaths.Add(Path.Combine(Globals.EngineRoot, @"Source\ThirdParty\mono-2.0")); switch (options.Platform.Target) { diff --git a/Source/ThirdParty/nethost/nethost.Build.cs b/Source/ThirdParty/nethost/nethost.Build.cs index e9afa6629..c34e00d92 100644 --- a/Source/ThirdParty/nethost/nethost.Build.cs +++ b/Source/ThirdParty/nethost/nethost.Build.cs @@ -84,7 +84,7 @@ public class nethost : ThirdPartyModule { // Use Mono for runtime hosting options.PublicDefinitions.Add("DOTNET_HOST_MONO"); - //options.PublicIncludePaths.Add(Path.Combine(hostRuntime.Path, "include", "mono-2.0")); already setup in ProjectTarget.SetupTargetEnvironment + options.PublicIncludePaths.Add(Path.Combine(hostRuntime.Path, "include", "mono-2.0")); break; } default: throw new ArgumentOutOfRangeException(); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index cc7ca5171..6b9f3d410 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -56,16 +56,22 @@ namespace Flax.Build.Bindings { "ScriptingTypeHandle", "System.Type" }, { "PersistentScriptingObject", "FlaxEngine.Object" }, { "ManagedScriptingObject", "FlaxEngine.Object" }, - { "MClass", "System.Type" }, { "Variant", "object" }, { "VariantType", "System.Type" }, // Mono types - { "MObject", "object" }, { "MonoObject", "object" }, + { "MonoClass", "System.Type" }, { "MonoReflectionType", "System.Type" }, { "MonoType", "IntPtr" }, { "MonoArray", "Array" }, + + // Managed types + { "MObject", "object" }, + { "MClass", "System.Type" }, + { "MType", "System.Type" }, + { "MTypeObject", "System.Type" }, + { "MArray", "Array" }, }; private static readonly string[] CSharpVectorTypes = @@ -289,7 +295,7 @@ namespace Flax.Build.Bindings // Array or Span or DataContainer #if USE_NETCORE - if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer" || typeInfo.Type == "MonoArray") && typeInfo.GenericArgs != null) + if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer" || typeInfo.Type == "MonoArray" || typeInfo.Type == "MArray") && typeInfo.GenericArgs != null) #else if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null) #endif @@ -498,7 +504,7 @@ namespace Flax.Build.Bindings // Interfaces are not supported by NativeMarshallingAttribute, marshal the parameter returnMarshalType = $"MarshalUsing(typeof({returnValueType}Marshaller))"; } - else if (functionInfo.ReturnType.Type == "MonoArray") + else if (functionInfo.ReturnType.Type == "MonoArray" || functionInfo.ReturnType.Type == "MArray") returnMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemArrayMarshaller))"; else if (functionInfo.ReturnType.Type == "Array" || functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "DataContainer" || functionInfo.ReturnType.Type == "BytesContainer" || returnNativeType == "Array") returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = nameof(__returnCount))"; @@ -508,7 +514,7 @@ namespace Flax.Build.Bindings returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = \"__returnCount\")"; else if (returnValueType == "bool[]") { - // Boolean arrays does not support custom marshalling for some unkown reason... + // Boolean arrays does not support custom marshalling for some unknown reason returnMarshalType = $"MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = {functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters?.Count ?? 0)})"; } #endif @@ -547,7 +553,7 @@ namespace Flax.Build.Bindings parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.CultureInfoMarshaller))"; else if (parameterInfo.Type.Type == "Variant") // object parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.ManagedHandleMarshaller))"; - else if (parameterInfo.Type.Type == "MonoArray") + else if (parameterInfo.Type.Type == "MonoArray" || parameterInfo.Type.Type == "MArray") parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemArrayMarshaller))"; else if (parameterInfo.Type.Type == "Array" && parameterInfo.Type.GenericArgs.Count > 0 && parameterInfo.Type.GenericArgs[0].Type == "bool") parameterMarshalType = $"MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = {(!functionInfo.IsStatic ? 1 : 0) + functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters.FindIndex(x => x.Name == $"__{parameterInfo.Name}Count"))})"; @@ -1483,7 +1489,7 @@ namespace Flax.Build.Bindings if (fieldInfo.Type.IsObjectRef) { toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({fieldInfo.Type.GenericArgs[0].Type})ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null"); - toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero"); + toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(managed.{fieldInfo.Name}, GCHandleType.Weak) : IntPtr.Zero"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}"); // Permanent ScriptingObject handle is passed from native side, do not release it @@ -1492,7 +1498,7 @@ namespace Flax.Build.Bindings else if (fieldInfo.Type.Type == "ScriptingObject") { toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? (FlaxEngine.Object)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null"); - toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero"); + toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(managed.{fieldInfo.Name}, GCHandleType.Weak) : IntPtr.Zero"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}"); // Permanent ScriptingObject handle is passed from native side, do not release it @@ -1501,7 +1507,7 @@ namespace Flax.Build.Bindings else if (fieldInfo.Type.IsPtr && originalType != "IntPtr" && !originalType.EndsWith("*")) { toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null"); - toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero"); + toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(managed.{fieldInfo.Name}, GCHandleType.Weak) : IntPtr.Zero"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}"); // Permanent ScriptingObject handle is passed from native side, do not release it @@ -1514,7 +1520,7 @@ namespace Flax.Build.Bindings toManagedContent.Append( $"managed.{fieldInfo.Name} != IntPtr.Zero ? (System.Collections.Generic.{fieldInfo.Type.Type}<{dictionaryArgs}>)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null"); toNativeContent.Append( - $"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))"); + $"ManagedHandle.ToIntPtr(managed.{fieldInfo.Name}, GCHandleType.Weak)"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}"); freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}"); } @@ -1527,7 +1533,7 @@ namespace Flax.Build.Bindings string originalElementTypeMarshaller = originalElementType + "Marshaller"; string internalElementType = $"{originalElementTypeMarshaller}.{originalElementType}Internal"; toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.NativeArrayToManagedArray<{originalElementType}, {internalElementType}>(((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).ToSpan<{internalElementType}>(), {originalElementTypeMarshaller}.ToManaged) : null"); - toNativeContent.Append($"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak))"); + toNativeContent.Append($"ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak)"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).ToSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}"); freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).ToSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}"); } @@ -1535,7 +1541,7 @@ namespace Flax.Build.Bindings { // Array elements passed as GCHandles toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<{originalElementType}>((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target) : null"); - toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak)) : IntPtr.Zero"); + toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak) : IntPtr.Zero"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span ptrs = ((ManagedArray)handle.Target).ToSpan(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}"); freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span ptrs = ((ManagedArray)handle.Target).ToSpan(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}"); } @@ -1543,7 +1549,7 @@ namespace Flax.Build.Bindings { // Blittable array elements toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).ToArray<{originalElementType}>() : null"); - toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak)) : IntPtr.Zero"); + toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak) : IntPtr.Zero"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}"); freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}"); } @@ -1551,7 +1557,7 @@ namespace Flax.Build.Bindings else if (fieldInfo.Type.Type == "Version") { toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null"); - toNativeContent.Append($"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))"); + toNativeContent.Append($"ManagedHandle.ToIntPtr(managed.{fieldInfo.Name}, GCHandleType.Weak)"); freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}"); freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}"); } diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 56e4fecea..1e7dd1ee4 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -280,34 +280,35 @@ namespace Flax.Build.Bindings contents.AppendLine(");"); } - private static string GenerateCppGetNativeClass(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller, FunctionInfo functionInfo) + private static string GenerateCppGetMClass(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller, FunctionInfo functionInfo) { // Optimal path for in-build types var managedType = GenerateCSharpNativeToManaged(buildData, typeInfo, caller); switch (managedType) { - case "bool": return "mono_get_boolean_class()"; - case "sbyte": return "mono_get_sbyte_class()"; - case "byte": return "mono_get_byte_class()"; - case "short": return "mono_get_int16_class()"; - case "ushort": return "mono_get_uint16_class()"; - case "int": return "mono_get_int32_class()"; - case "uint": return "mono_get_uint32_class()"; - case "long": return "mono_get_int64_class()"; - case "ulong": return "mono_get_uint64_class()"; - case "float": return "mono_get_single_class()"; - case "double": return "mono_get_double_class()"; - case "string": return "mono_get_string_class()"; - case "object": return "mono_get_object_class()"; - case "void": return "mono_get_void_class()"; - case "char": return "mono_get_char_class()"; - case "IntPtr": return "mono_get_intptr_class()"; - case "UIntPtr": return "mono_get_uintptr_class()"; + // In-built types (cached by the engine on startup) + case "bool": return "MCore::TypeCache::Boolean"; + case "sbyte": return "MCore::TypeCache::SByte"; + case "byte": return "MCore::TypeCache::Byte"; + case "short": return "MCore::TypeCache::Int16"; + case "ushort": return "MCore::TypeCache::UInt16"; + case "int": return "MCore::TypeCache::Int32"; + case "uint": return "MCore::TypeCache::UInt32"; + case "long": return "MCore::TypeCache::Int64"; + case "ulong": return "MCore::TypeCache::UInt64"; + case "float": return "MCore::TypeCache::Single"; + case "double": return "MCore::TypeCache::Double"; + case "string": return "MCore::TypeCache::String"; + case "object": return "MCore::TypeCache::Object"; + case "void": return "MCore::TypeCache::Void"; + case "char": return "MCore::TypeCache::Char"; + case "IntPtr": return "MCore::TypeCache::IntPtr"; + case "UIntPtr": return "MCore::TypeCache::UIntPtr"; // Vector2/3/4 have custom type in C# (due to lack of typename using in older C#) - case "Vector2": return "Scripting::FindClassNative(\"FlaxEngine.Vector2\")"; - case "Vector3": return "Scripting::FindClassNative(\"FlaxEngine.Vector3\")"; - case "Vector4": return "Scripting::FindClassNative(\"FlaxEngine.Vector4\")"; + case "Vector2": return "Scripting::FindClass(\"FlaxEngine.Vector2\")"; + case "Vector3": return "Scripting::FindClass(\"FlaxEngine.Vector3\")"; + case "Vector4": return "Scripting::FindClass(\"FlaxEngine.Vector4\")"; } // Find API type @@ -321,7 +322,7 @@ namespace Flax.Build.Bindings { // Use declared type initializer CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); - return $"{apiType.FullNameNative}::TypeInitializer.GetType().ManagedClass->GetNative()"; + return $"{apiType.FullNameNative}::TypeInitializer.GetClass()"; } } @@ -334,7 +335,7 @@ namespace Flax.Build.Bindings DefaultValue = "typeof(" + managedType + ')', Type = new TypeInfo { - Type = "MonoReflectionType", + Type = "MTypeObject", IsPtr = true, }, }; @@ -357,11 +358,13 @@ namespace Flax.Build.Bindings } // Use runtime lookup from fullname of the C# class - return "Scripting::FindClassNative(\"" + managedType + "\")"; + return "Scripting::FindClass(\"" + managedType + "\")"; } private static string GenerateCppGetNativeType(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller, FunctionInfo functionInfo) { + CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); + // Optimal path for in-build types var managedType = GenerateCSharpNativeToManaged(buildData, typeInfo, caller); switch (managedType) @@ -382,7 +385,7 @@ namespace Flax.Build.Bindings case "void": case "char": case "IntPtr": - case "UIntPtr": return "mono_class_get_type(" + GenerateCppGetNativeClass(buildData, typeInfo, caller, null) + ')'; + case "UIntPtr": return $"{GenerateCppGetMClass(buildData, typeInfo, caller, null)}->GetType()"; } // Find API type @@ -395,8 +398,7 @@ namespace Flax.Build.Bindings if (!apiType.SkipGeneration && !apiType.IsEnum) { // Use declared type initializer - CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); - return $"mono_class_get_type({apiType.FullNameNative}::TypeInitializer.GetType().ManagedClass->GetNative())"; + return $"{apiType.FullNameNative}::TypeInitializer.GetClass()->GetType()"; } } @@ -409,16 +411,16 @@ namespace Flax.Build.Bindings DefaultValue = "typeof(" + managedType + ')', Type = new TypeInfo { - Type = "MonoReflectionType", + Type = "MTypeObject", IsPtr = true, }, }; functionInfo.Glue.CustomParameters.Add(customParam); - return "mono_reflection_type_get_type(" + customParam.Name + ')'; + return "INTERNAL_TYPE_OBJECT_GET(" + customParam.Name + ')'; } - // Convert MonoClass* into MonoType* - return "mono_class_get_type(" + GenerateCppGetNativeClass(buildData, typeInfo, caller, null) + ')'; + // Convert MClass* into MType* + return $"{GenerateCppGetMClass(buildData, typeInfo, caller, null)}->GetType()"; } private static string GenerateCppWrapperNativeToManaged(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller, out string type, FunctionInfo functionInfo) @@ -448,30 +450,30 @@ namespace Flax.Build.Bindings case "StringView": case "StringAnsi": case "StringAnsiView": - type = "MonoString*"; + type = "MString*"; return "MUtils::ToString({0})"; case "Variant": - type = "MonoObject*"; + type = "MObject*"; return "MUtils::BoxVariant({0})"; case "VariantType": - type = "MonoReflectionType*"; + type = "MTypeObject*"; return "MUtils::BoxVariantType({0})"; case "ScriptingTypeHandle": - type = "MonoReflectionType*"; + type = "MTypeObject*"; return "MUtils::BoxScriptingTypeHandle({0})"; case "ScriptingObject": case "ManagedScriptingObject": case "PersistentScriptingObject": - type = "MonoObject*"; + type = "MObject*"; return "ScriptingObject::ToManaged((ScriptingObject*){0})"; case "MClass": - type = "MonoReflectionType*"; + type = "MTypeObject*"; return "MUtils::GetType({0})"; case "CultureInfo": type = "void*"; return "MUtils::ToManaged({0})"; case "Version": - type = "MonoObject*"; + type = "MObject*"; return "MUtils::ToManaged({0})"; default: // Object reference property @@ -481,7 +483,7 @@ namespace Flax.Build.Bindings typeInfo.Type == "SoftAssetReference" || typeInfo.Type == "SoftObjectReference") && typeInfo.GenericArgs != null) { - type = "MonoObject*"; + type = "MObject*"; return "{0}.GetManagedInstance()"; } @@ -489,28 +491,29 @@ namespace Flax.Build.Bindings if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null) { #if USE_NETCORE + // Boolean arrays does not support custom marshalling for some unknown reason if (typeInfo.GenericArgs[0].Type == "bool") { type = "bool*"; return "MUtils::ToBoolArray({0})"; } #endif - type = "MonoArray*"; - return "MUtils::ToArray({0}, " + GenerateCppGetNativeClass(buildData, typeInfo.GenericArgs[0], caller, functionInfo) + ")"; + type = "MArray*"; + return "MUtils::ToArray({0}, " + GenerateCppGetMClass(buildData, typeInfo.GenericArgs[0], caller, functionInfo) + ")"; } // BytesContainer if (typeInfo.Type == "BytesContainer" && typeInfo.GenericArgs == null) { - type = "MonoArray*"; + type = "MArray*"; return "MUtils::ToArray({0})"; } // Dictionary if (typeInfo.Type == "Dictionary" && typeInfo.GenericArgs != null) { - CppIncludeFiles.Add("Engine/Scripting/InternalCalls/ManagedDictionary.h"); - type = "MonoObject*"; + CppIncludeFiles.Add("Engine/Scripting/Internal/ManagedDictionary.h"); + type = "MObject*"; var keyClass = GenerateCppGetNativeType(buildData, typeInfo.GenericArgs[0], caller, functionInfo); var valueClass = GenerateCppGetNativeType(buildData, typeInfo.GenericArgs[1], caller, functionInfo); return "ManagedDictionary::ToManaged({0}, " + keyClass + ", " + valueClass + ")"; @@ -526,12 +529,13 @@ namespace Flax.Build.Bindings // BitArray if (typeInfo.Type == "BitArray" && typeInfo.GenericArgs != null) { - CppIncludeFiles.Add("Engine/Scripting/InternalCalls/ManagedBitArray.h"); + CppIncludeFiles.Add("Engine/Scripting/Internal/ManagedBitArray.h"); #if USE_NETCORE + // Boolean arrays does not support custom marshalling for some unknown reason type = "bool*"; return "MUtils::ToBoolArray({0})"; #else - type = "MonoObject*"; + type = "MObject*"; return "ManagedBitArray::ToManaged({0})"; #endif } @@ -551,14 +555,14 @@ namespace Flax.Build.Bindings // Scripting Object if (apiType.IsScriptingObject) { - type = "MonoObject*"; + type = "MObject*"; return "ScriptingObject::ToManaged((ScriptingObject*){0})"; } // interface if (apiType.IsInterface) { - type = "MonoObject*"; + type = "MObject*"; return "ScriptingObject::ToManaged(ScriptingObject::FromInterface({0}, " + apiType.NativeName + "::TypeInitializer))"; } @@ -584,7 +588,7 @@ namespace Flax.Build.Bindings CppUsedNonPodTypes.Add(apiType); CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); } - type = "MonoObject*"; + type = "MObject*"; return "MConverter<" + apiType.Name + ">::Box({0})"; } @@ -639,29 +643,29 @@ namespace Flax.Build.Bindings switch (typeInfo.Type) { case "String": - type = "MonoString*"; + type = "MString*"; return "String(MUtils::ToString({0}))"; case "StringView": - type = "MonoString*"; + type = "MString*"; return "MUtils::ToString({0})"; case "StringAnsi": case "StringAnsiView": - type = "MonoString*"; + type = "MString*"; return "MUtils::ToStringAnsi({0})"; case "Variant": - type = "MonoObject*"; + type = "MObject*"; return "MUtils::UnboxVariant({0})"; case "VariantType": - type = "MonoReflectionType*"; + type = "MTypeObject*"; return "MUtils::UnboxVariantType({0})"; case "ScriptingTypeHandle": - type = "MonoReflectionType*"; + type = "MTypeObject*"; return "MUtils::UnboxScriptingTypeHandle({0})"; case "CultureInfo": type = "void*"; return "MUtils::ToNative({0})"; case "Version": - type = "MonoObject*"; + type = "MObject*"; return "MUtils::ToNative({0})"; default: // Object reference property @@ -674,7 +678,7 @@ namespace Flax.Build.Bindings // For non-pod types converting only, other API converts managed to unmanaged object in C# wrapper code) if (CppNonPodTypesConvertingGeneration) { - type = "MonoObject*"; + type = "MObject*"; return "(" + typeInfo.GenericArgs[0].Type + "*)ScriptingObject::ToNative({0})"; } @@ -685,15 +689,15 @@ namespace Flax.Build.Bindings // MClass if (typeInfo.Type == "MClass" && typeInfo.GenericArgs == null) { - type = "MonoReflectionType*"; - return "Scripting::FindClass(MUtils::GetClass({0}))"; + type = "MTypeObject*"; + return "MUtils::GetClass({0})"; } // Array if (typeInfo.Type == "Array" && typeInfo.GenericArgs != null) { var T = typeInfo.GenericArgs[0].GetFullNameNative(buildData, caller); - type = "MonoArray*"; + type = "MArray*"; if (typeInfo.GenericArgs.Count != 1) return "MUtils::ToArray<" + T + ", " + typeInfo.GenericArgs[1] + ">({0})"; return "MUtils::ToArray<" + T + ">({0})"; @@ -702,7 +706,7 @@ namespace Flax.Build.Bindings // Span or DataContainer if ((typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null) { - type = "MonoArray*"; + type = "MArray*"; // Scripting Objects pointers has to be converted from managed object pointer into native object pointer to use Array converted for this var t = FindApiTypeInfo(buildData, typeInfo.GenericArgs[0], caller); @@ -717,8 +721,8 @@ namespace Flax.Build.Bindings // Dictionary if (typeInfo.Type == "Dictionary" && typeInfo.GenericArgs != null) { - CppIncludeFiles.Add("Engine/Scripting/InternalCalls/ManagedDictionary.h"); - type = "MonoObject*"; + CppIncludeFiles.Add("Engine/Scripting/Internal/ManagedDictionary.h"); + type = "MObject*"; return string.Format("ManagedDictionary::ToNative<{0}, {1}>({{0}})", typeInfo.GenericArgs[0], typeInfo.GenericArgs[1]); } @@ -740,7 +744,7 @@ namespace Flax.Build.Bindings if (typeInfo.Type == "BytesContainer" && typeInfo.GenericArgs == null) { needLocalVariable = true; - type = "MonoArray*"; + type = "MArray*"; return "MUtils::LinkArray({0})"; } @@ -790,7 +794,7 @@ namespace Flax.Build.Bindings CppUsedNonPodTypes.Add(apiType); CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); } - type = "MonoObject*"; + type = "MObject*"; return "MConverter<" + apiType.Name + ">::Unbox({0})"; } @@ -798,7 +802,7 @@ namespace Flax.Build.Bindings if (functionInfo == null && apiType.IsScriptingObject) { // Inside bindings function the managed runtime passes raw unamanged pointer - type = "MonoObject*"; + type = "MObject*"; return "(" + typeInfo.Type + "*)ScriptingObject::ToNative({0})"; } @@ -843,7 +847,7 @@ namespace Flax.Build.Bindings // Array or Span or DataContainer if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null && typeInfo.GenericArgs.Count >= 1) - return $"MUtils::ToArray({value}, {GenerateCppGetNativeClass(buildData, typeInfo.GenericArgs[0], caller, null)})"; + return $"MUtils::ToArray({value}, {GenerateCppGetMClass(buildData, typeInfo.GenericArgs[0], caller, null)})"; // BytesContainer if (typeInfo.Type == "BytesContainer" && typeInfo.GenericArgs == null) @@ -868,7 +872,7 @@ namespace Flax.Build.Bindings nativeType.Append('*'); // Use MUtils to box the value - return $"MUtils::Box<{nativeType}>({value}, {GenerateCppGetNativeClass(buildData, typeInfo, caller, null)})"; + return $"MUtils::Box<{nativeType}>({value}, {GenerateCppGetMClass(buildData, typeInfo, caller, null)})"; } private static bool GenerateCppWrapperFunctionImplicitBinding(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller) @@ -957,7 +961,7 @@ namespace Flax.Build.Bindings }); } #endif - + var prevIndent = " "; var indent = " "; contents.Append(prevIndent); @@ -1016,7 +1020,7 @@ namespace Flax.Build.Bindings // Out parameters that need additional converting will be converted at the native side (eg. object reference) var isOutWithManagedConverter = parameterInfo.IsOut && !string.IsNullOrEmpty(GenerateCSharpManagedToNativeConverter(buildData, parameterInfo.Type, caller)); if (isOutWithManagedConverter) - managedType = "MonoObject*"; + managedType = "MObject*"; contents.Append(managedType); if (parameterInfo.IsRef || parameterInfo.IsOut || UsePassByReference(buildData, parameterInfo.Type, caller)) @@ -1197,7 +1201,7 @@ namespace Flax.Build.Bindings callParams += "Temp"; } } - // Special case for parameter that cannot be passed directly to the function from the wrapper method input parameter (eg. MonoArray* converted into BytesContainer uses as BytesContainer&) + // Special case for parameter that cannot be passed directly to the function from the wrapper method input parameter (eg. MArray* converted into BytesContainer uses as BytesContainer&) else if (CppParamsThatNeedLocalVariable[i]) { contents.Append(indent).AppendFormat("auto {0}Temp = {1};", parameterInfo.Name, param).AppendLine(); @@ -1251,7 +1255,7 @@ namespace Flax.Build.Bindings { var value = string.Format(CppParamsThatNeedConversionWrappers[i], parameterInfo.Name + "Temp"); - // MonoObject* parameters returned by reference need write barrier for GC + // MObject* parameters returned by reference need write barrier for GC if (parameterInfo.IsOut) { var apiType = FindApiTypeInfo(buildData, parameterInfo.Type, caller); @@ -1259,7 +1263,7 @@ namespace Flax.Build.Bindings { if (apiType.IsClass) { - contents.Append(indent).AppendFormat("mono_gc_wbarrier_generic_store({0}, (MonoObject*){1});", parameterInfo.Name, value).AppendLine(); + contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine(); #if USE_NETCORE if (parameterInfo.Type.Type == "Array") { @@ -1270,8 +1274,9 @@ namespace Flax.Build.Bindings } if (apiType.IsStruct && !apiType.IsPod) { + // Structure that has reference to managed objects requries copy relevant for GC barriers (on Mono) CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); - contents.Append(indent).AppendFormat("{{ auto __temp = {1}; mono_gc_wbarrier_value_copy({0}, &__temp, 1, {2}::TypeInitializer.GetType().ManagedClass->GetNative()); }}", parameterInfo.Name, value, apiType.FullNameNative).AppendLine(); + contents.Append(indent).AppendFormat("{{ auto __temp = {1}; MCore::GC::WriteValue({0}, &__temp, 1, {2}::TypeInitializer.GetClass()); }}", parameterInfo.Name, value, apiType.FullNameNative).AppendLine(); continue; } } @@ -1280,11 +1285,11 @@ namespace Flax.Build.Bindings // BytesContainer if (parameterInfo.Type.Type == "BytesContainer" && parameterInfo.Type.GenericArgs == null) { - contents.Append(indent).AppendFormat("mono_gc_wbarrier_generic_store({0}, (MonoObject*){1});", parameterInfo.Name, value).AppendLine(); + contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine(); contents.Append(indent).AppendFormat("*__{0}Count = {1}.Length();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine(); continue; } - + throw new Exception($"Unsupported type of parameter '{parameterInfo}' in method '{functionInfo}' to be passed using 'out'"); } } @@ -1414,9 +1419,7 @@ namespace Flax.Build.Bindings contents.AppendLine($" ASSERT(scriptVTable && scriptVTable[{scriptVTableOffset}]);"); contents.AppendLine($" auto method = scriptVTable[{scriptVTableOffset}];"); - contents.AppendLine($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::{functionInfo.Name}\");"); - - contents.AppendLine(" MonoObject* exception = nullptr;"); + contents.AppendLine(" MObject* exception = nullptr;"); contents.AppendLine(" auto prevWrapperCallInstance = WrapperCallInstance;"); contents.AppendLine(" WrapperCallInstance = object;"); @@ -1425,11 +1428,13 @@ namespace Flax.Build.Bindings else contents.AppendLine($" void* params[{functionInfo.Parameters.Count}];"); - // If platform supports JITed code execution then use method thunk, otherwise fallback to generic mono_runtime_invoke + // If platform supports JITed code execution then use method thunk, otherwise fallback to generic runtime invoke var returnType = functionInfo.ReturnType; var useThunk = buildData.Platform.HasDynamicCodeExecutionSupport; if (useThunk) { + contents.AppendLine($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::{functionInfo.Name}\");"); + // Convert parameters into managed format as boxed values var thunkParams = string.Empty; var thunkCall = string.Empty; @@ -1467,13 +1472,13 @@ namespace Flax.Build.Bindings // Invoke method thunk if (returnType.IsVoid) { - contents.AppendLine($" typedef void (*Thunk)(void* instance{thunkParams}, MonoObject** exception);"); + contents.AppendLine($" typedef void (*Thunk)(void* instance{thunkParams}, MObject** exception);"); contents.AppendLine(" const auto thunk = (Thunk)method->GetThunk();"); contents.AppendLine($" thunk(object->GetOrCreateManagedInstance(){thunkCall}, &exception);"); } else { - contents.AppendLine($" typedef MonoObject* (*Thunk)(void* instance{thunkParams}, MonoObject** exception);"); + contents.AppendLine($" typedef MObject* (*Thunk)(void* instance{thunkParams}, MObject** exception);"); contents.AppendLine(" const auto thunk = (Thunk)method->GetThunk();"); contents.AppendLine($" auto __result = thunk(object->GetOrCreateManagedInstance(){thunkCall}, &exception);"); } @@ -1485,10 +1490,10 @@ namespace Flax.Build.Bindings var paramIsRef = parameterInfo.IsRef || parameterInfo.IsOut; if (paramIsRef && !parameterInfo.Type.IsConst) { - // Unbox from MonoObject* + // Unbox from MObject* parameterInfo.Type.IsRef = false; var useLocalVarPointer = CppParamsThatNeedConversion[i]; - var boxedValueCast = useLocalVarPointer ? "*(MonoObject**)" : "(MonoObject*)"; + var boxedValueCast = useLocalVarPointer ? "*(MObject**)" : "(MObject*)"; contents.Append($" {parameterInfo.Name} = MUtils::Unbox<{parameterInfo.Type}>({boxedValueCast}params[{i}]);").AppendLine(); parameterInfo.Type.IsRef = true; } @@ -1509,7 +1514,7 @@ namespace Flax.Build.Bindings } // Invoke method - contents.AppendLine(" auto __result = mono_runtime_invoke(method->GetNative(), object->GetOrCreateManagedInstance(), params, &exception);"); + contents.AppendLine(" auto __result = mmethod->Invoke(object->GetOrCreateManagedInstance(), params, &exception);"); // Convert parameter values back from managed to native (could be modified there) for (var i = 0; i < functionInfo.Parameters.Count; i++) @@ -1572,7 +1577,7 @@ namespace Flax.Build.Bindings } else { - // mono_runtime_invoke always returns boxed value as MonoObject* + // Runtime invoke always returns boxed value as MObject* contents.AppendLine($" return MUtils::Unbox<{returnType}>(__result);"); } } @@ -1713,7 +1718,7 @@ namespace Flax.Build.Bindings thunkParams += parameterInfo.Type; } var t = functionInfo.IsConst ? " const" : string.Empty; - contents.AppendLine($" typedef {functionInfo.ReturnType} ({classInfo.NativeName}::*{functionInfo.UniqueName}_Signature)({thunkParams}){t};"); + contents.AppendLine($" typedef {functionInfo.ReturnType} ({classInfo.NativeName}::*{functionInfo.UniqueName}_Signature)({thunkParams}){t};"); } contents.AppendLine($" {functionInfo.UniqueName}_Signature funcPtr = &{classInfo.NativeName}::{functionInfo.Name};"); contents.AppendLine(" const int32 vtableIndex = GetVTableIndex(vtable, entriesCount, *(void**)&funcPtr);"); @@ -1934,10 +1939,9 @@ namespace Flax.Build.Bindings else contents.Append(" static MMethod* mmethod = nullptr;").AppendLine(); contents.Append(" if (!mmethod)").AppendLine(); - contents.AppendFormat(" mmethod = {1}::TypeInitializer.GetType().ManagedClass->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine(); + contents.AppendFormat(" mmethod = {1}::TypeInitializer.GetClass()->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine(); contents.Append(" CHECK(mmethod);").AppendLine(); - contents.Append($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::On{eventInfo.Name}\");").AppendLine(); - contents.Append(" MonoObject* exception = nullptr;").AppendLine(); + contents.Append(" MObject* exception = nullptr;").AppendLine(); if (paramsCount == 0) contents.AppendLine(" void** params = nullptr;"); else @@ -1951,10 +1955,10 @@ namespace Flax.Build.Bindings contents.Append($" params[{i}] = {paramValue};").AppendLine(); } if (eventInfo.IsStatic) - contents.AppendLine(" MonoObject* instance = nullptr;"); + contents.AppendLine(" MObject* instance = nullptr;"); else - contents.AppendLine($" MonoObject* instance = (({classTypeNameNative}*)this)->GetManagedInstance();"); - contents.Append(" mono_runtime_invoke(mmethod->GetNative(), instance, params, &exception);").AppendLine(); + contents.AppendLine($" MObject* instance = (({classTypeNameNative}*)this)->GetManagedInstance();"); + contents.Append(" mmethod->Invoke(instance, params, &exception);").AppendLine(); contents.Append(" if (exception)").AppendLine(); contents.Append(" DebugLog::LogException(exception);").AppendLine(); for (var i = 0; i < paramsCount; i++) @@ -2345,21 +2349,19 @@ namespace Flax.Build.Bindings CppUsedNonPodTypes.Add(structureInfo); contents.AppendLine(" static MObject* Box(void* ptr)"); contents.AppendLine(" {"); - contents.AppendLine($" MonoObject* managed = mono_object_new(mono_domain_get(), {structureTypeNameNative}::TypeInitializer.GetType().ManagedClass->GetNative());"); if (structureInfo.IsPod) - contents.AppendLine($" Platform::MemoryCopy(mono_object_unbox(managed), ptr, sizeof({structureTypeNameNative}));"); + contents.AppendLine($" return MCore::Object::Box(ptr, {structureTypeNameNative}::TypeInitializer.GetClass());"); else - contents.AppendLine($" *({structureInfo.NativeName}Managed*)mono_object_unbox(managed) = ToManaged(*({structureTypeNameNative}*)ptr);"); - contents.AppendLine(" return managed;"); + contents.AppendLine($" return MUtils::Box(*({structureTypeNameNative}*)ptr, {structureTypeNameNative}::TypeInitializer.GetClass());"); contents.AppendLine(" }").AppendLine(); // Unboxing structures from managed object to native data contents.AppendLine(" static void Unbox(void* ptr, MObject* managed)"); contents.AppendLine(" {"); if (structureInfo.IsPod) - contents.AppendLine($" Platform::MemoryCopy(ptr, mono_object_unbox(managed), sizeof({structureTypeNameNative}));"); + contents.AppendLine($" Platform::MemoryCopy(ptr, MCore::Object::Unbox(managed), sizeof({structureTypeNameNative}));"); else - contents.AppendLine($" *({structureTypeNameNative}*)ptr = ToNative(*({structureInfo.NativeName}Managed*)mono_object_unbox(managed));"); + contents.AppendLine($" *({structureTypeNameNative}*)ptr = ToNative(*({structureInfo.NativeName}Managed*)MCore::Object::Unbox(managed));"); contents.AppendLine(" }").AppendLine(); } else @@ -2670,6 +2672,7 @@ namespace Flax.Build.Bindings CurrentModule = moduleInfo; // Disable C# scripting based on configuration + ScriptingLangInfos[0].Enabled = EngineConfiguration.WithCSharp(buildData.TargetOptions); contents.AppendLine("// This code was auto-generated. Do not modify it."); @@ -2677,11 +2680,9 @@ namespace Flax.Build.Bindings contents.AppendLine("#include \"Engine/Core/Compiler.h\""); contents.AppendLine("PRAGMA_DISABLE_DEPRECATION_WARNINGS"); // Disable deprecated warnings in generated code contents.AppendLine("#include \"Engine/Scripting/Scripting.h\""); - contents.AppendLine("#include \"Engine/Scripting/InternalCalls.h\""); + contents.AppendLine("#include \"Engine/Scripting/Internal/InternalCalls.h\""); contents.AppendLine("#include \"Engine/Scripting/ManagedCLR/MUtils.h\""); -#if USE_NETCORE - contents.AppendLine("#include \"Engine/Scripting/DotNet/CoreCLR.h\""); -#endif + contents.AppendLine("#include \"Engine/Scripting/ManagedCLR/MCore.h\""); contents.AppendLine($"#include \"{moduleInfo.Name}.Gen.h\""); for (int i = 0; i < moduleInfo.Children.Count; i++) { @@ -2819,7 +2820,7 @@ namespace Flax.Build.Bindings header.Append("struct ").Append(apiType.Name).Append("Managed").AppendLine(); header.Append('{').AppendLine(); if (classInfo != null) - header.AppendLine(" MonoObject obj;"); + header.AppendLine(" MObject obj;"); for (var i = 0; i < fields.Count; i++) { var fieldInfo = fields[i]; @@ -2853,30 +2854,30 @@ namespace Flax.Build.Bindings header.Append("template<>").AppendLine(); header.AppendFormat("struct MConverter<{0}>", fullName).AppendLine(); header.Append('{').AppendLine(); - header.AppendFormat(" MonoObject* Box(const {0}& data, MonoClass* klass)", fullName).AppendLine(); + header.AppendFormat(" MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine(); header.Append(" {").AppendLine(); header.Append(" auto managed = ToManaged(data);").AppendLine(); - header.Append(" return mono_value_box(mono_domain_get(), klass, (void*)&managed);").AppendLine(); + header.Append(" return MCore::Object::Box((void*)&managed, klass);").AppendLine(); header.Append(" }").AppendLine(); - header.AppendFormat(" void Unbox({0}& result, MonoObject* data)", fullName).AppendLine(); + header.AppendFormat(" void Unbox({0}& result, MObject* data)", fullName).AppendLine(); header.Append(" {").AppendLine(); - header.AppendFormat(" result = ToNative(*reinterpret_cast<{0}Managed*>(mono_object_unbox(data)));", apiType.Name).AppendLine(); + header.AppendFormat(" result = ToNative(*reinterpret_cast<{0}Managed*>(MCore::Object::Unbox(data)));", apiType.Name).AppendLine(); header.Append(" }").AppendLine(); - header.AppendFormat(" void ToManagedArray(MonoArray* result, const Span<{0}>& data)", fullName).AppendLine(); + header.AppendFormat(" void ToManagedArray(MArray* result, const Span<{0}>& data)", fullName).AppendLine(); header.Append(" {").AppendLine(); - header.AppendFormat(" MonoClass* klass = {0}::TypeInitializer.GetType().ManagedClass->GetNative();", fullName).AppendLine(); - header.Append(" ASSERT(klass);").AppendLine(); + header.AppendFormat(" MClass* klass = {0}::TypeInitializer.GetClass();", fullName).AppendLine(); + header.AppendFormat(" {0}Managed* resultPtr = ({0}Managed*)MCore::Array::GetAddress(result);", apiType.Name).AppendLine(); header.Append(" for (int32 i = 0; i < data.Length(); i++)").AppendLine(); header.Append(" {").AppendLine(); header.Append(" auto managed = ToManaged(data[i]);").AppendLine(); - header.AppendFormat(" mono_value_copy(mono_array_addr(result, {0}Managed, i), &managed, klass);", apiType.Name).AppendLine(); + header.Append(" MCore::GC::WriteValue(&resultPtr[i], &managed, 1, klass);").AppendLine(); header.Append(" }").AppendLine(); header.Append(" }").AppendLine(); - header.Append(" template").AppendLine(); - header.AppendFormat(" void ToNativeArray(Array<{0}, AllocationType>& result, MonoArray* data, int32 length)", fullName).AppendLine(); + header.AppendFormat(" void ToNativeArray(Span<{0}>& result, const MArray* data)", fullName).AppendLine(); header.Append(" {").AppendLine(); - header.Append(" for (int32 i = 0; i < length; i++)").AppendLine(); - header.AppendFormat(" result.Add(ToNative(mono_array_get(data, {0}Managed, i)));", apiType.Name).AppendLine(); + header.AppendFormat(" {0}Managed* dataPtr = ({0}Managed*)MCore::Array::GetAddress(data);", apiType.Name).AppendLine(); + header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine(); + header.Append(" result[i] = ToNative(dataPtr[i]);").AppendLine(); header.Append(" }").AppendLine(); header.Append('}').Append(';').AppendLine(); @@ -2964,9 +2965,9 @@ namespace Flax.Build.Bindings header.AppendFormat("struct MConverter<{0}>", fullName).AppendLine(); header.Append('{').AppendLine(); - header.AppendFormat(" static MonoObject* Box(const {0}& data, MonoClass* klass)", fullName).AppendLine(); + header.AppendFormat(" static MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine(); header.Append(" {").AppendLine(); - header.Append(" MonoObject* obj = mono_object_new(mono_domain_get(), klass);").AppendLine(); + header.Append(" MObject* obj = MCore::Object::New(klass);").AppendLine(); for (var i = 0; i < fields.Count; i++) { var fieldInfo = fields[i]; @@ -2976,23 +2977,23 @@ namespace Flax.Build.Bindings var fieldType = FindApiTypeInfo(buildData, fieldInfo.Type, apiType); if (fieldInfo == null || fieldType.IsValueType) // TODO: support any value type (eg. by boxing) throw new Exception($"Not supported field {fieldInfo.Type} {fieldInfo.Name} in class {classInfo.Name}."); - + var wrapper = GenerateCppWrapperNativeToManaged(buildData, fieldInfo.Type, apiType, out var type, null); var value = string.IsNullOrEmpty(wrapper) ? "data." + fieldInfo.Name : string.Format(wrapper, "data." + fieldInfo.Name); - header.AppendFormat(" mono_field_set_value(obj, mono_class_get_field_from_name(klass, \"{0}\"), {1});", fieldInfo.Name, value).AppendLine(); + header.AppendFormat(" klass->GetField(\"{0}\")->SetValue(obj, {1});", fieldInfo.Name, value).AppendLine(); } header.Append(" return obj;").AppendLine(); header.Append(" }").AppendLine(); - header.AppendFormat(" static MonoObject* Box(const {0}& data)", fullName).AppendLine(); + header.AppendFormat(" static MObject* Box(const {0}& data)", fullName).AppendLine(); header.Append(" {").AppendLine(); - header.AppendFormat(" MonoClass* klass = {0}::TypeInitializer.GetType().ManagedClass->GetNative();", fullName).AppendLine(); + header.AppendFormat(" MClass* klass = {0}::TypeInitializer.GetClass();", fullName).AppendLine(); header.Append(" return Box(data, klass);").AppendLine(); header.Append(" }").AppendLine(); - header.AppendFormat(" static void Unbox({0}& result, MonoObject* obj)", fullName).AppendLine(); + header.AppendFormat(" static void Unbox({0}& result, MObject* obj)", fullName).AppendLine(); header.Append(" {").AppendLine(); - header.Append(" MonoClass* klass = mono_object_get_class(obj);").AppendLine(); + header.Append(" MClass* klass = MCore::Object::GetClass(obj);").AppendLine(); header.Append(" void* v = nullptr;").AppendLine(); for (var i = 0; i < fields.Count; i++) { @@ -3004,30 +3005,32 @@ namespace Flax.Build.Bindings var wrapper = GenerateCppWrapperManagedToNative(buildData, fieldInfo.Type, apiType, out var type, out _, null, out _); CppNonPodTypesConvertingGeneration = false; - header.AppendFormat(" mono_field_get_value(obj, mono_class_get_field_from_name(klass, \"{0}\"), &v);", fieldInfo.Name).AppendLine(); + CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MField.h"); + + header.AppendFormat(" klass->GetField(\"{0}\")->GetValue(obj, &v);", fieldInfo.Name).AppendLine(); var value = $"({type})v"; header.AppendFormat(" result.{0} = {1};", fieldInfo.Name, string.IsNullOrEmpty(wrapper) ? value : string.Format(wrapper, value)).AppendLine(); } header.Append(" }").AppendLine(); - header.AppendFormat(" static {0} Unbox(MonoObject* data)", fullName).AppendLine(); + header.AppendFormat(" static {0} Unbox(MObject* data)", fullName).AppendLine(); header.Append(" {").AppendLine(); header.AppendFormat(" {0} result;", fullName).AppendLine(); header.Append(" Unbox(result, data);").AppendLine(); header.Append(" return result;").AppendLine(); header.Append(" }").AppendLine(); - header.AppendFormat(" void ToManagedArray(MonoArray* result, const Span<{0}>& data)", fullName).AppendLine(); + header.AppendFormat(" void ToManagedArray(MArray* result, const Span<{0}>& data)", fullName).AppendLine(); header.Append(" {").AppendLine(); header.Append(" for (int32 i = 0; i < data.Length(); i++)").AppendLine(); - header.Append(" mono_array_setref(result, i, Box(data[i]));").AppendLine(); + header.Append(" MCore::GC::WriteArrayRef(result, Box(data[i]), i);").AppendLine(); header.Append(" }").AppendLine(); - header.Append(" template").AppendLine(); - header.AppendFormat(" void ToNativeArray(Array<{0}, AllocationType>& result, MonoArray* data, int32 length)", fullName).AppendLine(); + header.AppendFormat(" void ToNativeArray(Span<{0}>& result, const MArray* data)", fullName).AppendLine(); header.Append(" {").AppendLine(); - header.Append(" for (int32 i = 0; i < length; i++)").AppendLine(); - header.AppendFormat(" Unbox(result[i], (MonoObject*)mono_array_addr_with_size(data, sizeof(MonoObject*), length));", fullName).AppendLine(); + header.Append(" MObject** dataPtr = (MObject**)MCore::Array::GetAddress(data);").AppendLine(); + header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine(); + header.AppendFormat(" Unbox(result[i], dataPtr[i]);", fullName).AppendLine(); header.Append(" }").AppendLine(); header.Append('}').Append(';').AppendLine(); @@ -3113,7 +3116,7 @@ namespace Flax.Build.Bindings contents.AppendLine("{"); if (useCSharp) { - contents.AppendLine($" static NativeBinaryModule module(\"{binaryModuleName}\", MAssemblyOptions());"); + contents.AppendLine($" static NativeBinaryModule module(\"{binaryModuleName}\");"); } else { diff --git a/Source/Tools/Flax.Build/Build/ProjectTarget.cs b/Source/Tools/Flax.Build/Build/ProjectTarget.cs index cc7549cd1..cf1439335 100644 --- a/Source/Tools/Flax.Build/Build/ProjectTarget.cs +++ b/Source/Tools/Flax.Build/Build/ProjectTarget.cs @@ -62,20 +62,6 @@ namespace Flax.Build // Add include paths for this project sources and engine third-party sources var depsRoot = options.DepsFolder; - { - // TODO: rethink how we should expose mono (and dotnet host api) in general - DotNetSdk.Instance.GetHostRuntime(options.Platform.Target, options.Architecture, out var hostRuntime); - if (hostRuntime.Type == DotNetSdk.HostType.Mono) - { - // Use mono headers from the host runtime - options.CompileEnv.IncludePaths.Add(Path.Combine(hostRuntime.Path, "include", "mono-2.0")); - } - else - { - // Use in-built mono headers - options.CompileEnv.IncludePaths.Add(Path.Combine(Globals.EngineRoot, @"Source\ThirdParty\mono-2.0")); - } - } options.CompileEnv.IncludePaths.Add(Path.Combine(Globals.EngineRoot, @"Source\ThirdParty")); options.LinkEnv.LibraryPaths.Add(depsRoot); diff --git a/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs b/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs index ddaf0e52e..0cb1fafd5 100644 --- a/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs +++ b/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs @@ -452,7 +452,7 @@ namespace Flax.Deps.Dependencies } // Update source file with exported symbols - var mCorePath = Path.Combine(Globals.EngineRoot, "Source", "Engine", "Scripting", "ManagedCLR", "MCore.Mono.cpp"); + var mCorePath = Path.Combine(Globals.EngineRoot, "Source", "Engine", "Scripting", "Runtime", "Mono.cpp"); var contents = File.ReadAllText(mCorePath); var startPos = contents.IndexOf("#pragma comment(linker,"); var endPos = contents.LastIndexOf("#pragma comment(linker,");