From ecd2320ea670a10f6a8aeeb056a680f372dc2a02 Mon Sep 17 00:00:00 2001 From: kmsmg Date: Sat, 22 Jun 2024 10:09:36 +0800 Subject: [PATCH 01/11] Signed-off-by: kmsmg --- .vs/ProjectEvaluation/uniluax.metadata.v7.bin | Bin 0 -> 185161 bytes .vs/ProjectEvaluation/uniluax.projects.v7.bin | Bin 0 -> 106238 bytes .vs/UniLuaX/v17/DocumentLayout.json | 181 +++ Assets/Behaviour.meta | 4 - Assets/Editor.meta | 5 - Assets/Resources.meta | 4 - Assets/Stages.meta | 4 - Assets/StreamingAssets.meta | 4 - Assets/Tools.meta | 4 - Assets/UniLua.meta | 4 - Assets/UniLua/.vs/ProjectSettings.json | 3 + ...6b17d053-e231-473c-b85c-c8b40fa403b4.vsidx | Bin 0 -> 497 bytes ...b0b9c650-9b98-4f86-b71d-f8224da3660b.vsidx | Bin 0 -> 187403 bytes ...c6591743-cbad-45d4-b47a-5ee1205bdefb.vsidx | Bin 0 -> 15851 bytes Assets/UniLua/.vs/UniLua/v17/.futdcache.v2 | Bin 0 -> 113 bytes Assets/UniLua/.vs/UniLua/v17/.wsuo | Bin 0 -> 40448 bytes .../UniLua/.vs/UniLua/v17/DocumentLayout.json | 61 + .../.vs/UniLuaX/DesignTimeBuild/.dtbcache.v2 | Bin 0 -> 90125 bytes ...aeefe867-2127-4859-a58f-e4b2d051e1bb.vsidx | Bin 0 -> 191018 bytes Assets/UniLua/.vs/UniLuaX/v17/.futdcache.v2 | Bin 0 -> 112 bytes Assets/UniLua/.vs/VSWorkspaceState.json | 5 + Assets/UniLua/.vs/slnx.sqlite | Bin 0 -> 299008 bytes Assets/UniLua/ByteString.cs.meta | 8 - Assets/UniLua/Class1.cs | 7 + Assets/UniLua/Coder.cs.meta | 8 - Assets/UniLua/Common.cs.meta | 8 - Assets/UniLua/Do.cs.meta | 8 - Assets/UniLua/Dump.cs.meta | 8 - Assets/UniLua/LLex.cs.meta | 8 - Assets/UniLua/LuaAPI.cs.meta | 8 - Assets/UniLua/LuaAuxLib.cs | 1440 +++++++++-------- Assets/UniLua/LuaAuxLib.cs.meta | 8 - Assets/UniLua/LuaBaseLib.cs.meta | 8 - Assets/UniLua/LuaBitLib.cs.meta | 8 - Assets/UniLua/LuaCoroLib.cs.meta | 8 - Assets/UniLua/LuaDebug.cs.meta | 8 - Assets/UniLua/LuaDebugLib.cs.meta | 8 - Assets/UniLua/LuaEncLib.cs.meta | 8 - Assets/UniLua/LuaFFILib.cs.meta | 8 - Assets/UniLua/LuaFile.cs | 209 +-- Assets/UniLua/LuaFile.cs.meta | 8 - Assets/UniLua/LuaFunc.cs.meta | 8 - Assets/UniLua/LuaIOLib.cs.meta | 8 - Assets/UniLua/LuaMathLib.cs.meta | 8 - Assets/UniLua/LuaObject.cs.meta | 8 - Assets/UniLua/LuaOsLib.cs.meta | 8 - Assets/UniLua/LuaPkgLib.cs | 664 ++++---- Assets/UniLua/LuaPkgLib.cs.meta | 8 - Assets/UniLua/LuaState.cs.meta | 8 - Assets/UniLua/LuaStrLib.cs.meta | 8 - Assets/UniLua/LuaTable.cs.meta | 8 - Assets/UniLua/LuaTableLib.cs.meta | 8 - Assets/UniLua/OpCodes.cs.meta | 8 - Assets/UniLua/Parser.cs.meta | 8 - Assets/UniLua/TagMethod.cs.meta | 8 - Assets/UniLua/ULDebug.cs | 45 +- Assets/UniLua/ULDebug.cs.meta | 8 - Assets/UniLua/Undump.cs.meta | 8 - Assets/UniLua/UniLuaX.csproj | 17 + Assets/UniLua/Util.cs.meta | 8 - Assets/UniLua/VM.cs.meta | 8 - ProjectSettings/AudioManager.asset | Bin 4124 -> 0 bytes ProjectSettings/DynamicsManager.asset | Bin 4280 -> 0 bytes ProjectSettings/EditorBuildSettings.asset | Bin 4176 -> 0 bytes ProjectSettings/EditorSettings.asset | Bin 4168 -> 0 bytes ProjectSettings/GraphicsSettings.asset | Bin 4112 -> 0 bytes ProjectSettings/InputManager.asset | Bin 5396 -> 0 bytes ProjectSettings/NavMeshLayers.asset | Bin 9196 -> 0 bytes ProjectSettings/NetworkManager.asset | Bin 4112 -> 0 bytes ProjectSettings/Physics2DSettings.asset | Bin 4260 -> 0 bytes ProjectSettings/ProjectSettings.asset | Bin 19764 -> 0 bytes ProjectSettings/QualitySettings.asset | Bin 4544 -> 0 bytes ProjectSettings/TagManager.asset | Bin 5416 -> 0 bytes ProjectSettings/TimeManager.asset | Bin 4112 -> 0 bytes 74 files changed, 1462 insertions(+), 1463 deletions(-) create mode 100644 .vs/ProjectEvaluation/uniluax.metadata.v7.bin create mode 100644 .vs/ProjectEvaluation/uniluax.projects.v7.bin create mode 100644 .vs/UniLuaX/v17/DocumentLayout.json delete mode 100644 Assets/Behaviour.meta delete mode 100644 Assets/Editor.meta delete mode 100644 Assets/Resources.meta delete mode 100644 Assets/Stages.meta delete mode 100644 Assets/StreamingAssets.meta delete mode 100644 Assets/Tools.meta delete mode 100644 Assets/UniLua.meta create mode 100644 Assets/UniLua/.vs/ProjectSettings.json create mode 100644 Assets/UniLua/.vs/UniLua/FileContentIndex/6b17d053-e231-473c-b85c-c8b40fa403b4.vsidx create mode 100644 Assets/UniLua/.vs/UniLua/FileContentIndex/b0b9c650-9b98-4f86-b71d-f8224da3660b.vsidx create mode 100644 Assets/UniLua/.vs/UniLua/FileContentIndex/c6591743-cbad-45d4-b47a-5ee1205bdefb.vsidx create mode 100644 Assets/UniLua/.vs/UniLua/v17/.futdcache.v2 create mode 100644 Assets/UniLua/.vs/UniLua/v17/.wsuo create mode 100644 Assets/UniLua/.vs/UniLua/v17/DocumentLayout.json create mode 100644 Assets/UniLua/.vs/UniLuaX/DesignTimeBuild/.dtbcache.v2 create mode 100644 Assets/UniLua/.vs/UniLuaX/FileContentIndex/aeefe867-2127-4859-a58f-e4b2d051e1bb.vsidx create mode 100644 Assets/UniLua/.vs/UniLuaX/v17/.futdcache.v2 create mode 100644 Assets/UniLua/.vs/VSWorkspaceState.json create mode 100644 Assets/UniLua/.vs/slnx.sqlite delete mode 100644 Assets/UniLua/ByteString.cs.meta create mode 100644 Assets/UniLua/Class1.cs delete mode 100644 Assets/UniLua/Coder.cs.meta delete mode 100644 Assets/UniLua/Common.cs.meta delete mode 100644 Assets/UniLua/Do.cs.meta delete mode 100644 Assets/UniLua/Dump.cs.meta delete mode 100644 Assets/UniLua/LLex.cs.meta delete mode 100644 Assets/UniLua/LuaAPI.cs.meta delete mode 100644 Assets/UniLua/LuaAuxLib.cs.meta delete mode 100644 Assets/UniLua/LuaBaseLib.cs.meta delete mode 100644 Assets/UniLua/LuaBitLib.cs.meta delete mode 100644 Assets/UniLua/LuaCoroLib.cs.meta delete mode 100644 Assets/UniLua/LuaDebug.cs.meta delete mode 100644 Assets/UniLua/LuaDebugLib.cs.meta delete mode 100644 Assets/UniLua/LuaEncLib.cs.meta delete mode 100644 Assets/UniLua/LuaFFILib.cs.meta delete mode 100644 Assets/UniLua/LuaFile.cs.meta delete mode 100644 Assets/UniLua/LuaFunc.cs.meta delete mode 100644 Assets/UniLua/LuaIOLib.cs.meta delete mode 100644 Assets/UniLua/LuaMathLib.cs.meta delete mode 100644 Assets/UniLua/LuaObject.cs.meta delete mode 100644 Assets/UniLua/LuaOsLib.cs.meta delete mode 100644 Assets/UniLua/LuaPkgLib.cs.meta delete mode 100644 Assets/UniLua/LuaState.cs.meta delete mode 100644 Assets/UniLua/LuaStrLib.cs.meta delete mode 100644 Assets/UniLua/LuaTable.cs.meta delete mode 100644 Assets/UniLua/LuaTableLib.cs.meta delete mode 100644 Assets/UniLua/OpCodes.cs.meta delete mode 100644 Assets/UniLua/Parser.cs.meta delete mode 100644 Assets/UniLua/TagMethod.cs.meta delete mode 100644 Assets/UniLua/ULDebug.cs.meta delete mode 100644 Assets/UniLua/Undump.cs.meta create mode 100644 Assets/UniLua/UniLuaX.csproj delete mode 100644 Assets/UniLua/Util.cs.meta delete mode 100644 Assets/UniLua/VM.cs.meta delete mode 100644 ProjectSettings/AudioManager.asset delete mode 100644 ProjectSettings/DynamicsManager.asset delete mode 100644 ProjectSettings/EditorBuildSettings.asset delete mode 100644 ProjectSettings/EditorSettings.asset delete mode 100644 ProjectSettings/GraphicsSettings.asset delete mode 100644 ProjectSettings/InputManager.asset delete mode 100644 ProjectSettings/NavMeshLayers.asset delete mode 100644 ProjectSettings/NetworkManager.asset delete mode 100644 ProjectSettings/Physics2DSettings.asset delete mode 100644 ProjectSettings/ProjectSettings.asset delete mode 100644 ProjectSettings/QualitySettings.asset delete mode 100644 ProjectSettings/TagManager.asset delete mode 100644 ProjectSettings/TimeManager.asset diff --git a/.vs/ProjectEvaluation/uniluax.metadata.v7.bin b/.vs/ProjectEvaluation/uniluax.metadata.v7.bin new file mode 100644 index 0000000000000000000000000000000000000000..80a2ddcefa3466cd92153f86abb8d3c3aed1048f GIT binary patch literal 185161 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%0A`=_dBLjVFg!jRt)gs5%0y!wN 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 literal 0 HcmV?d00001 diff --git a/.vs/ProjectEvaluation/uniluax.projects.v7.bin b/.vs/ProjectEvaluation/uniluax.projects.v7.bin new file mode 100644 index 0000000000000000000000000000000000000000..5f4a180e0f4a210bc6295faf84e29f45a1292963 GIT binary patch literal 106238 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 TK5=F>%2sJ!jdF^=C&&K-S3r+) literal 0 HcmV?d00001 diff --git a/.vs/UniLuaX/v17/DocumentLayout.json b/.vs/UniLuaX/v17/DocumentLayout.json new file mode 100644 index 0000000..f7bfeda --- /dev/null +++ b/.vs/UniLuaX/v17/DocumentLayout.json @@ -0,0 +1,181 @@ +{ + "Version": 1, + "WorkspaceRootPath": "H:\\project2\\UniLua\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luaauxlib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luaauxlib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luadebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luadebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luaapi.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luaapi.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\vm.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\vm.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|solutionrelative:assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|solutionrelative:assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|solutionrelative:assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 11, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:0:0:{004be353-6879-467c-9d1e-9ac23cdf6d49}" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{34e76e81-ee4a-11d0-ae2e-00a0c90fffc3}" + }, + { + "$type": "Bookmark", + "Name": "ST:9:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + }, + { + "$type": "Bookmark", + "Name": "ST:10:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{a80febb4-e7e0-4147-b476-21aaf2453969}" + }, + { + "$type": "Bookmark", + "Name": "ST:1:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "LuaAPI.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAPI.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", + "RelativeToolTip": "Assets\\UniLua\\LuaAPI.cs", + "ViewState": "AQIAAEYCAAAAAAAAAAAlwFQCAAAlAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T02:03:44.522Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "LuaDebug.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaDebug.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\LuaDebug.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaDebug.cs", + "RelativeToolTip": "Assets\\UniLua\\LuaDebug.cs", + "ViewState": "AQIAANYBAAAAAAAAAAAlwOQBAAAPAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T02:03:35.091Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "VM.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\VM.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\VM.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\VM.cs", + "RelativeToolTip": "Assets\\UniLua\\VM.cs", + "ViewState": "AQIAAJICAAAAAAAAAAAlwKACAAAHAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T02:03:09.098Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "LuaAuxLib.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAuxLib.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", + "RelativeToolTip": "Assets\\UniLua\\LuaAuxLib.cs", + "ViewState": "AQIAACsCAAAAAAAAAADgvzECAAARAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T01:53:02.58Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "ULDebug.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\ULDebug.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\ULDebug.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\ULDebug.cs", + "RelativeToolTip": "Assets\\UniLua\\ULDebug.cs", + "ViewState": "AQIAAAkAAAAAAAAAAAAAABYAAAAqAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T01:43:36.299Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "LuaPkgLib.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaPkgLib.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\LuaPkgLib.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaPkgLib.cs", + "RelativeToolTip": "Assets\\UniLua\\LuaPkgLib.cs", + "ViewState": "AQIAAK4AAAAAAAAAAIAywL8AAAAJAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T01:42:42.258Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "LuaFile.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaFile.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\LuaFile.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaFile.cs", + "RelativeToolTip": "Assets\\UniLua\\LuaFile.cs", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAA0AAAA1AAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T01:40:33.009Z", + "EditorCaption": "" + } + ] + }, + { + "DockedWidth": 17, + "SelectedChildIndex": -1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:3:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Assets/Behaviour.meta b/Assets/Behaviour.meta deleted file mode 100644 index a97a3a7..0000000 --- a/Assets/Behaviour.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: d7daa4568f9cb534f89a493483113005 -DefaultImporter: - userData: diff --git a/Assets/Editor.meta b/Assets/Editor.meta deleted file mode 100644 index 7065fec..0000000 --- a/Assets/Editor.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 3b0b1dff7db84464b9ca2706fd4fb39f -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/Resources.meta b/Assets/Resources.meta deleted file mode 100644 index 6a039a4..0000000 --- a/Assets/Resources.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: fda4ce3ccdcf24d4794cea8c8369c73b -DefaultImporter: - userData: diff --git a/Assets/Stages.meta b/Assets/Stages.meta deleted file mode 100644 index a5e91bf..0000000 --- a/Assets/Stages.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 68d0e371377a43c4291d80ec510d1c14 -DefaultImporter: - userData: diff --git a/Assets/StreamingAssets.meta b/Assets/StreamingAssets.meta deleted file mode 100644 index b3ab26c..0000000 --- a/Assets/StreamingAssets.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 4dd5041feafaf57428c9e95e6902147e -DefaultImporter: - userData: diff --git a/Assets/Tools.meta b/Assets/Tools.meta deleted file mode 100644 index 99affc9..0000000 --- a/Assets/Tools.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: a22a00b92f35fba40b0bf47ff2c2f360 -DefaultImporter: - userData: diff --git a/Assets/UniLua.meta b/Assets/UniLua.meta deleted file mode 100644 index 3aee89c..0000000 --- a/Assets/UniLua.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 9196ce4e34714564ea3f80dcc1f5789f -DefaultImporter: - userData: diff --git a/Assets/UniLua/.vs/ProjectSettings.json b/Assets/UniLua/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/Assets/UniLua/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/Assets/UniLua/.vs/UniLua/FileContentIndex/6b17d053-e231-473c-b85c-c8b40fa403b4.vsidx b/Assets/UniLua/.vs/UniLua/FileContentIndex/6b17d053-e231-473c-b85c-c8b40fa403b4.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..c851d4d22df534ff720e48f389cdca0c627e657a GIT binary patch literal 497 zcmYk2O-=$q5QPg-!5@CTf@>ozT(F`Y2#^efq%(<&*$~14V*H_D$2GixM{&yqyaZR^ zRm~ehrKi4rHLt2W9rXr{vdF$57B3m34Guf$*ZOm{m~Yx?^0AD!v($yK*o0g~@3RnE zPxJ8j{C(*C{TI6IE*dcs>oQ;GGTWarJeiaEmveBje3BaMyCC%pt)bU=MP8F7QfH{| zhP);3$a}IvR>>M!CmUpwd?0tAhMwyrl0Nd-vKKF}63YnH7}Y-X6e^a)v_Jhz*yCkl oyNS7`*hlC{Fhx5ZvX>ULlQ*mCB=zQ@Z=v_r7-x_l(&-~0j&Q0fc>n+a literal 0 HcmV?d00001 diff --git a/Assets/UniLua/.vs/UniLua/FileContentIndex/b0b9c650-9b98-4f86-b71d-f8224da3660b.vsidx b/Assets/UniLua/.vs/UniLua/FileContentIndex/b0b9c650-9b98-4f86-b71d-f8224da3660b.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..4e4eb08afefde6ba85ced5ea4c35de5602214ff9 GIT binary patch literal 187403 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 jz`=&eoNvbY2Ah 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 D_%V^T literal 0 HcmV?d00001 diff --git a/Assets/UniLua/.vs/UniLua/FileContentIndex/c6591743-cbad-45d4-b47a-5ee1205bdefb.vsidx b/Assets/UniLua/.vs/UniLua/FileContentIndex/c6591743-cbad-45d4-b47a-5ee1205bdefb.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..8e489fd9f2f4851b6c5b9f0735310f3cd535194c GIT binary patch literal 15851 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 o`>DbCA%50h_Wb$N&HU literal 0 HcmV?d00001 diff --git a/Assets/UniLua/.vs/UniLuaX/FileContentIndex/aeefe867-2127-4859-a58f-e4b2d051e1bb.vsidx b/Assets/UniLua/.vs/UniLuaX/FileContentIndex/aeefe867-2127-4859-a58f-e4b2d051e1bb.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..631e4c57a7f992b347d2c538ae64dc861462ec80 GIT binary patch literal 191018 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 CgtzGc literal 0 HcmV?d00001 diff --git a/Assets/UniLua/.vs/UniLuaX/v17/.futdcache.v2 b/Assets/UniLua/.vs/UniLuaX/v17/.futdcache.v2 new file mode 100644 index 0000000000000000000000000000000000000000..758db894dcbeed57807ef0b44d8125ae7da8a7a3 GIT binary patch literal 112 zcmZQ%U|`Vqu!<=t%FjwoE-{J;&CB#DO^k6YE>0~ehVdYR5qinRAazVYJ-p8Od1;yH zrA3J)nfZCFE~!bS=^Oz$i6v?IMY(K_d6muqp)2e4Pra}S%#WLNhvW1E#vSoM8URPx BDC7VD literal 0 HcmV?d00001 diff --git a/Assets/UniLua/.vs/VSWorkspaceState.json b/Assets/UniLua/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..186c9a9 --- /dev/null +++ b/Assets/UniLua/.vs/VSWorkspaceState.json @@ -0,0 +1,5 @@ +{ + "ExpandedNodes": [], + "SelectedNode": "\\H:\\project2\\UniLua\\Assets\\UniLua", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/Assets/UniLua/.vs/slnx.sqlite b/Assets/UniLua/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..ebbc483dfdae1ddb58fd09697f956f90ad293677 GIT binary patch literal 299008 zcmeEv2Y4IDvGCyv`rT0yNl2n(QPN2iMS;Dl*&ql~5DO>}RIwy8AaRsnQv?No66G4o zC2nzx<2Z2=$1Sm)*l|g5oWv!0PI0Q8W~V2PUlOOibUXE**}cOZKv0q$C+~mXcl{Of;<;0Lc?0JfQa z&-e4kOzrqf0t(B2MVW>2U%hvGOFX^qYg|`3zvJNSJGkrFSJ)`KeZC|t`u`aZIMLEs zMRNFd`E9d1l9LH_X6V?V(bPnjI-Ze({U;R}M9J;lu&h#yjm8z-H_I79O!CZXW| z%3!3g56e0b2?mBj)t7GZI(&Y=?Mi<(K02Wm7QOIV)QpJ*I{QLJN-nzBQNPS_VmPrM z{2L4Pgrb#$(Qtntx~H-?w5KvK9E*epAld%VKn$#c|KYyA4O%LL>C};ALQR{sbr~vx zHz6A84n;!)!O&3UUR@(JnN4Po?O&H8KoZr43f#Bh!7g+JxFHzm3gxl7LVY2Fr5i&X zIIuGi4Q>lW*EP1ZRObvX@T;!UJv}jTY{ztbA~~K^6U7q9zaP3@FVqslUwVmkZeVOo z&190J$q6iC&aH)F1$A(aoKa-61F@kD9m{0ZLpc`~lF*fvhW2amWnXG6j_os=Iy!#= zbfI8sV*1eJTshHQJzM8-_(q^zjgWRlEFFtaPO9l(eC(h)GS_t4$_fR&`K_#wJ#RXu zHdm+vb#HF&`>QV=c9Rx&*?!XE3bhKaJ^3xJkPZ3kEv}GdZZoIQ;jV_q0ygFe{`!C+eW5=eTm(+VIJqx|%#gd2AOg4UKYJVkm z9G_W{PKU3$+II0KQV;dSX!7}2uKYTf&otFQongL7r%>}~ z&Bz%{i(_=N^(XCR^?Y+hJr!lVWg8t1U&ycDvcifyG8j**li3mMwhMXAqW7;*%AA7f zRu+ok3q!G|^9FdF5fcg(urAMb+8w@gpyxYg^n9jPsAWA@)71Zs3Bv{#@)wUeZF zlCqtk5M_e-wP;SZ=#}CI+fQP!p?MPHiaEae;%z+bq=QB$ZSq#3okD&CDP)_PNFnRB zH5F>JQOi%^O=RACVDxpQAH(-4{Cf?r1pitOAI_j}_E&a>=e`E^#WUH+XhuyRQQ@`7 z=y|ob#mcTwcVM_LRyj7ECM`Crchk_wQ=G%sP+^;0L7K^sn$0FB50Eyky>C+rpI@Km z%8_bBUiYcOe2unxkhS}2YHWK*&B+{wcQkb*qaL1CC*iFv|B}nAHwDaflTi6LfM)e< zkImt$sIVPZNt&8%8e;R(*sD=ZRZgS)$7R2|InjB9a zm`;-c?jiVSO^&JO;m7eRO`vl+Ig!Yd%BW2 zti#W6VvoiR(vRwVAuTJ>eZfkeXMzhz4%CXwFnp+MADx+A_1ND1 zHny~mHTpY7$J;wbJI4HKM*>o+Z)<{-np*u$YTIaITl;uR!&sYtthKSdwQX$7-`W;$ z_cwQpwff^7iF$wIs5;)%+L34<9S5P&@#glH<~D!*sM-oPB^n`PDC}56V`99iC84Sv z9sWc|V?*OuOTypL))I%5Kr-Ie(&TR(Z)tBG9UmR9Z)@`>#>d)PIvP6s?TI)TKH5Cy zA5Ap3_#0YV5{;u{(RzO(0nTn7Z>{%tw8Cu} zON=M#Tic;fjg93to~iN;!3@lyxHc-=P}@}7BFc|54tbD~pOs&dZ_9Bc_!<;q(G zfb0LaIDg5=zmmTyKO)~MUnytgeR5E)lHJm;rDvp%NH<}{@D9D?+3j%doT8mcmv*b-ZC%i`K9L@p2t0Rdv5ex;2H9ix}SC5 z=04_*ySKX=-4(9yx<2Q6&~=4tx2qhow*D*+SRSxEV0pmufaL+p1OGM;tlMH|PPe)2 z`r6%|iPUI(VmJfgr^qW!$WHRcZ(TQW>$?;Tpa%wu8sU5@pFmeiOH`HO`< zn(W@0OXClgt%PcW$!3!iCbF-RnlU_?m_9URVk}-^XI7$oA900=v-C7Ovj#Y^_k zdoYzS@qEi^auACTOXN+A#mi`Nk*Q!RL7D}z77SZfLCXuP|6{m8Q(tn_q_0A?Q=@M!Ou!gef0=30CHCWZ3Rn2O?oZ8?y2MW~6b83-HK5J=NPAxKuADE^jD@yH5 z6*aOyo;{eaxMWc-&2S{2wRjJG#5W`ROf{bG*>x zSUzu=lyft=q50e;V$R6I+g;(!6%P8mRKDI)PcFyKWHz5y;m#>`Lcf;JT9XgbnG%?CKJF^__ zAy!Xw#jRjzDLRj3Rj6k0Xfr7-u+es1djy;B-kDE)xd-R}w|H)6#8uwy@+;ya@=wJl zyrzpR`r{k$9oEQ_OhVytjHUm;BOcQi=Ed-U{z$J%19v?ER(Z331qS zyTprs`L{jpt%NNPSRSxEV0pmufaL+p1C|FY5BwkWz;f<%oBnYgI~TKXVR;mFh`oJZ6%HVeTA#YQ)`#70M;Ivm_0{Mp{fC2g;6q^S*4p`%N!9$2)j zjVQGk+yPo=SllUX!otUwygiPI${|4d3}S-)%5TT;t+=bk29ZL9EUZ*P#ZC z)Knpc;hD7}x5AbilUcJ67LMz;j1I&oi@6qkjyZ4iWi_TrhFn&mleKY{m6%>`aHUe> zR@#gal@%r28k>0-LzZX)`XI<+ zO&~Y&;nM{4;f``mAUDQQwt%a`B#nWMQcXo4%~*tHf`m4Nu~5IH;}#3F1apHGB^n_& zLLqDAG7U>eS{C|Pgs2%|3_y6bRC1#Z9!hx5(GXSIC#h7s=oU zxnJG}D+jj9QMp}uN!}p+Np6(a%9Zj`xm1>9CyX2XP5K|{`_gmLv(gu(&%pS>qtZ|Q z4|d6x$(9E!4_F?sJYadi@_^+5%LA4NEDu;7usrY|^nk$GY|UE;+)Usm0yh%aL0~(9 zZ3tUh5w2}P*wl=$stI9DBY_PB))QDqU@d`u0yiLBUxTn}J;HU>2-mLTImT9nU@d|* z2o#=k*;eDPRR~rhs6?;=!D$GVBUpx@0>M%QOAstZ;6qT3pbP$L{Z{&s^i}DT()*=%NS8}TB~^+^XNXhcF7J@H zUA#i7msX08iT$2e#4|j<^oG1|kYw?n;{SLjJzw@-?RlSgulHe3O04um#23Wp{)1J< z%F6P9oV~@=I*mtbKEbi(f=8n%kTCr0rGC+&8z8w6w^OR*|o;>9hB1 zTTHB`W;3g*=|uL`G@eo+YZ_jg4{PdQLpf{ePJBaaYE3?^@#{XV*5cAb-7#E_YN@&l*#C4L2Cn%iH*S2MY)rA_WH;agnAXZPK_kI|<0y?g~I z(m0BhBvE66U*=Z=FBdbhVgbK~$)DmU3dS5iQ7}#N6RTj7+7t^>QNpigaN?TKaGIZ_ z3WQwT!xCL2H_@+)7&HC4NN%cM7cu7g7xGmkBhzHRu9chZCk8{_`gDKpTAT0JQ#B_1 zb&4_LuNTrh<*#RyoAcL=F-`jGDH*f=x{ztwUl%gw{fW!LWNqS~+&_KhpIqou|Kui< zcmaV{mfYmO$S;Swqs0brB-i}ue+N`Iod3u8e@@=Z$e)*Q0A&4H91@l;!nh9#V5r3#dnHViZkN4 z7!w0xow!`|K(f}K>wyP$Lz( zioK=;PESBe9i<$5>CO^3HUTNMloDC7t^|%su)%2^3Q1?-H~#xKC2%kT%B&$W3;t@e zm%ynANLh}Qy)!rMIJX22L_o?ajk12M1WrOgN+qSd^^DU?-~Hty}Xq4qj37j>66w#o-`2t9BQpycqxv~U~6+nt? zP~a>9q(~a&Zg&ZsAb=FFMw#VH;Mf49cnk_07JwADMrnMm1WpM+ic6z-zE%PU1R%v> zP~dC;q}VCt`qaH8a4-N;NcG)2bIk)gOW;HRqzF_7DR345Qdo_0#f2qs002^Wjk0MF z=l^S@e=_nP<)6!cm45@f|9ww>7)*xlwenH< z0(nSQVc);Q@+Nsi-Xr(G&VK>9PWDOvlw0I#d9}P8P6_bH!vA_Rw+yg6V0pmufaL+p z1C|FY4_F?sJYadi@_^+5%LC{E+{RBK8~be`8~be}8~e4bBlIeSjcXCstwC6;5c+C_ zYgQp#z7pZ8N`#dw5UxB8;gaPDS1dz#S_Q(TOA%HqLAY!&LZ1)e;&Oy#We7`45tc7P zSh5h|q6G*SmLOapBNQcsP7$H(MJRa?dff;;E`)9;LYD)f0|o?OoJ&B+@dyPDA=KBd=wnYcpT?bulE~oPu=QYkfPQ~$C$0Lr59NQgb_8;2sv!81Z+RKGs36BZa3cW%F{~~`M zpW@rNzjIG_Vo=1Mk0fKAzBSYg%-1Z*^D|Oy7YMBAz_Qz@Ny7vEhEQZmGZd%-%TIH)!9w}L$gU#tKn3|M zSKC=A-yi8JA`euM&v3PYLiw)n&LZ+a1^F~rdq$yr|8QRsd7y&)VXpS{LiwTL&LZ+a z1^Fqic59)0psSeuKn3{}SGfh`!QsT8)A7iZIc=Wh50$iU28q?ZxtbA*M&ZO%y>i43 zrqy@?_e+`15Z7yLflqR+n?Q4A*sKX$ErVi;z!mrdT>Hj3Iraqm^}Ae55!nJi&b4;T z$+16lB1PZ|yvl8E2feC@+0vms1F^vF6BtVc1U|vFw#~^kIy`U!Rp1Kz7}wkidMkQz zx$X&v`t*A>r<8;#@S|L93ur9~(o zu4!#S$%bOl@IX&76DddF!(7vv0wwToXGm`dc^OfTz;ELM3Me%g-9xM|+_NpFm%CVo zc>)68!?mo2B+Rw3GZN_w1&aDbV+njW=U)YC%QqP}Vjx_!E&^HLLtNcT5MQyyBpw;i zd+PkM0bSs`xYd=QP*F`4Xp6`%4$pT=tt&vt)Q?9)-FapNQ^#8coKz7-esg*AGL)tbsWUJX8VQC+hQeo> z3f-lS*P1yj-%+~00<{>6wiR*z$qM@@>Axr69Z7=n!^>qCbT`_YDtiE3mkb&GL1nTgy!Pka9HC6NXl|Cp^#<(x0MmH}w+d zu~~jYX=5qqo4gF~Ke1@Y^j4{BY7CZNU)s6|bgGOVJ{s=YJ<=B#Dx#HRvHZHy%?m-# zZ@iZfW=~(FGtg)1f%Oc{T$ZmY?OXubO-5%x`27LsiVHf{yaWsZmS0=iSYnhmv^y3J zj10vBLH$9l`N_m!d8Kr-Y*-ETIUJ-q#cO*Wm*rQNHcOzbwG+JaP!o$}Y38u}s?tgk zw3bxqZ4pY8R~7im@;Wa_ET^rbKd`$X&A#NJByT zr2>Tt{NnNk2gsS8R$bxfP)L8tp`8}(Lny<;FIwDY2NlyJbtv335Qq&&O+6KKbyO?I zWBG-?pa67|dZ7f%mz1{gdASp}7ThaCo!&0^z-_&{ z2VnD6=K^fJN&(n#C2q!7f8_#zbyoxc`Y%rb+;I6Cfa~A13*fpp;p~0YWdi`$T*d)Z zF6{ug`jSb2D=t|9@U)Ag0GD6v0=V?}8332eCIK#~eyKix&9C|DpU@ z*a;vZ&#+H=radG4&%8h3?&R+0KJMVS&k29we#CuK@NmDkI~^HeQn=T#!f}h^YR84% zXWZAgo81fCZ+EBNZ*+gy^$+(K_$T?7?NNBq>u2v^&t~_**Zn%SoPChJiDkH5?6chE z>5g&7nL>S}ilxPq?Tt_k5=!msT|_-_f1I6uvc&b0GP=T^tl&Q*?|Iqi;n z-FNW}-^{P!L#}IG7rWl;dWY*l*HLag?-Sx&tNlg$AG}X^qOMPPYTP0DPoAqhm9F1& zH@lwaBn~T6?yrpVv$&mPIIAA&QYX{{@vO@HX#ux}P;t}DY%(>;{88do5DMAulKF!! zFg$f6J~6FknBOnts)#`DHG=t_$Sv1M36=S+euaZC%>T&TO2UIJL6egQnBVB!;qYXZ z`L&m;AY8oomCou+r6!nP>WbUoYgkP)zbN5Wvt$%UBfO+rO12hde(vFxu%UsjaA1J> z8UF5$MEe6V=BK4x4GaBVaAX_2q~n{$nIY!CF<D$~zz<^?zB zgWu`o6!T*w?@A}LV9SqOTp2N&`C+~hKOjj>$2Ga{qdNI4WWML%7O;_C=DT{av>d*J z$3W&GcIPBZ=sV2C(}8@d=oRkt6t_Cc&G4ZXeOJE2hs`L~a=7fD zp2#MV@MSa}2=IG4J(*#?MCw8^Gj=eZK7c7?m@lFkp_!@1z~r&0dSG~p`2s2#6y|9x zFxi_ee>tmmaA&pd@XQ8lBckATSsGR%Kr zZoz}<*g4?fv2&PD=b6}uDSZk{iJt0QljwqN@yvE;92w>b%riWhP-oNx^Emn` zkVy10kKr%yV=wbbbUD`0Ugi@hJ1~7{R899XAIA$?$$Obcv5e3_#^PD#V`$=FJUezU zmfEJKRpt>ikr43XU1dIs_K<6Gb3Q`v@MHoFVm|ET7C`~C%!e>ZB*jw9!)Og*KZMl5 zRAxLm!#s$V!QsyE^8rG}bDL+F59&20n1b}~M>DbT1F0-?ALiVX3XgZkC%}*opd?<# z($gyQel!y^iA+LC63o4L9iBX*rn4mLdq~%y-;nK7W6a%1$rS{)xn`elq&b$p7@O%4k{~&Xd-Z<0DTgg3ualNb>m|<=t zhR`c$#BVWQ2ALbs&qJYDAlfs6ZTxz??lG>fLvf7{iCv4A8XGRJF>yip%_c5fUX6BW zxtwDl@j98yO}qf}CKE5fT!!VRX)>4MZ)yy4iB=96_zp(8Ld?Zl zIrQt}=$`(-P;WgmtN(0Z-iYU2_wVVw2oJ?3pE|u4A}Ku7djTGR9PI^-^YJKWc&8%# zXzzK*=nTiAz31Xt$iP6~1&^67I%iB5funeUvL+UoIijVeIegm0?3~G>9fOgfk-$tw z|JgZ{#vGB_d077yoYH>4`= zMB8I2+PNISBdEhLJdmCyPwa8bmNXr;fRn%!=%Zx}kFxF>iK_95iPRYB8AnmNYosTg zI!dnNC_@lY{A0RvpViKS4EM)HHQ;7;}Wr1ALmQF(2227a*KX9)gxSrcU8Y%@8U;n%MTE z^T_NloHdA6#8TP#M4vi&AbT)^>YdZ$*gFrPSYT=jO4x6{D}89`oY|({qSWn1R$*d3 zd_3ah&^FUWtjD+r?dZmP32LZYbXpw0^yq+Ai4kqZM z(RI27G4eTEo4X{V$bP**+5qte{aPFQt;t=}af$VM33KC?)j5hj5W6my1sPCot!a;||CJ%2n@$rVH!$Xu=0ju;FZuF@SD8-Ov$l~`M$uHdM8rJg$-L0q8= zl99pFNTR0Uz~x9VkLxWXN#QLV*jb@ls=YNY#j1_>D{mlf$s8(DPR)*Na^y_#ii=0v}t|_>>z=ClAHb$KX}Lt^%!=yhmr#yBq1tqA(_Z zf`L#0U_k{~$-=1yV+Vs1@k~Z&1zH7)2UF0A^{GeHiHz-G`MZqA&dF>){}Aw3p-$h3 z{y?xj0W=1`>z6I&n(#HLGdUTVN=K6i4ralURNCG+!S=Htz{x*A*(R9%e@Xs<?% z4~qAQcZly2-zHu!UL{^CUL+n9GvXoffEX9|io;?=48zy(7O_oi5NpIW;tFwzxJVR5 zhsbze@%|1@6a0zyd){w)zvBIz_et-g-iN&(@ZRNpxA$${>%3QZk9*JaX1#~J}~PZdaJyZ-X-3JUXPde{N3{>&u=_G^Zdy3ZO_*{U-UfXdCc=s_-en$ zbGzpj&yAipdoJ@_o`o-;fho<>iNNAWE8lzU{4(_?f0#r=Et zFWoP?zwiE*`>XEHyFcarxcfuy``qt!-|D{Eef_Dgdw|G?qY(9Q4n#j-+`|yWJ@i22 z!zPG&sMF#ed^GYw`ls}Y^n2-7(of;6#P3MokiH^)UivhgnfOuZK{z+@F6mb3?b2JM zH%o7lW~K9_X(=Tor7>y0v`g9{t&}RHGD((P5-0v${ImF5@fYHY;t#~<#jlB95J?+*FRi;cKwg* z=dK^SzT^73>r1ZBxE^;s0;2`@y6$kj)Ad%@HLf?g-sn2!O1sW+C0zSmJ6#diHdny4 z(beSI;9BE4&E<2IxLmLz;;+s>IDh5*Z|4u3&%s)cr=6d6e!}@-=l#z2Ip5=aJB)Q) z<-Ejsf%Awnz&okRn7`$sZ)f}i+?&^hBYEDIbLvl*YOR< zmmQyVJmL75;~~fU9d|n3<+#alt>bdXtm9lq#xdbg9cMXqIR+hJN2guqOYIlhkJ_i~ zN&BdMuRUh(w|Co5x3}9H?Cb5T?aN>kNwPx(j_```JK-0?PlWFY-xR(gd`@^$cvN^; z_<(Si@NVI4!gazG!g1j|AuAjb#)T1Kx3ELlE(C?mLW@u5qSRZ{Ga&W z@IT{!#DAOr8vjN9DgH73qx=K>J^bzbE&PrAoB7N5i})G-Fn=~b#_!{Y`2oI%KZEb! z8~GYu;g|E}yv#d!8}}FP_uMbJ7rF0q-{QW?eV+Ri_i^q+*ih}9jdk0;PSMvWdX}PR zDEcZzU!myB6n%-JFCuc;zCh8_6n&ne&r$SQiatZpQxyFdMW3eVQxrW((GwIsPSIl& zeUhS2Q1o$%9;N7G6g@)GM=AOUMIWZ;=TUSnMaL+bq39?@M<|-6C`(a>qBKQ^DVm}vMbRWhhbWq$=p2g9 zrYK3#L5dDgG)|F9QG%i|L=M|1MRAJWK+yKvjUW&F;6sBk!MLiUCQxu}8i=rS!ofHKqI)kFqDcVZW z7K%1gw27jP6m?M4PEi|0trWFT)J#zmMU50SP*hJ*9YwVi`6=2!Q4K}wDXOMu9Ys|X zt)*xUMG8f$DOyF*N{T8eT0zli6fLJ{8ATNoEv0A)MT;r&QB+P*8AYWOEuv^4MGGh@ zp-84kqDZ93OOb~nH$^UroD?}IvQs2b#8bpk#8PCVh#`piCq@6D=@L(VHo{nxd;Hx{{(RD7u`YH&JvMMVC@^2}KuEbey7D zirz?8M_)wXg#=ze;Q0ieN8q^x9wTsuz@r2nA#j?&EP)vU(*zzSaEibbfs+ItB5;Dh za|k?}z$AeO2|PgHIDsmG2?ECu3Zn$Z348;ABLtpB;C=%45xAGYGYQ;7;BEqU5xA4U zVFF_W4iOk7a0h{d2-ygM0|fRH*hgS5f!hfTBjmRc*h649fgu9B2n-U~Nnn7$GYCAL zz^w#sA#gK+n+V)UU*_P*hpXlf%OE|5m-y0pTG?SlJ);QS^v+I z_5b`jLa!olErDwYR0t&N|9P_hpC{}8d9wbWC+q)tvi_eZ>;HMO{+}o7|9P_hpC{}8 zd9wZ=rfShwWc@!+*8lTl{Xb9E|MO)1KTp>G^JM)$PuBnQWc@!+*8lTfk^))(&y)54 zJX!zGI|D9h4c zr5B|yN)N$T>P6B4sZVNx-TpZ7m*UsON5$L3E5s>rw|Kf(C3?Mo^!~v68Se+ZZ}(p6 z&3Ko2KH%weU+?;vYr^?+=Np}F$9;}w`mEgvGFf4o^9Y0jr4aYoY_9aqTIIDEu6ioeP_Vp*n(y2^p zJX_lz9}C7|K=)WCTRW6EXJ12WZF6l~Lu1FjEY4hJPasg;)m1>B&-4< zm4-DqQ|Z)HhM(nNH8)r^d+a}E5iA;t!;~z}CRZhm(<^ zlU8_5=42H;18eKifIa^<1B$qIFD%W+OsoIJOpCh|*75%fF3sJqxqZl~x)g!{{sotw zf&s-`3ZVr5f=hFm7Imo#fd`oQmREJZ0+We!Dw)8VTDvPbnMfVY>}zVOt*`B9*;hOp z2wQlavT25FS{jRIa})v|FdKM|o}gFFKwsGosWjG;WX#W!fl!PzzqvI;<6xtMhsmx~ z`kaYWJfU~zdm&`vZTrGqA?-Jr+a|s=UM}_xOv9WDh1!GiT!;`s3l99N7W5C16>oDgYiO&j zH;A>w0{tPq79vd`^W&$#UYQ4{(`j`wyH9)XG384gL^Iado$5GLK9dZ!jp|aSZfGq; zwxFSr|33^RtK0@B;#nxbq1s@4Dn6Q=NM@6&-fj*;Kn>p2U~zl3S5I@Jgf>{LHvsa! z;S4N8$|lF-W7$k(Iy*I;g@scGHP=i+91iC6x_c&9_iN3!jvs~)9?Wm~>rpc7cxX#3 zQCyg;k6~P_va=r!h+nvxP$~#TJE^{O6`{czW{}DqSYNi1P*+lF?%aA`B_XdN{6PO&dL&6J99nEjIFgbXhgkR{HQ$44jBzT_yRQ@)I_R_C#R?yDel znlY%rVjN9jX}$tkiGm7C@)dID-Ip)USJ02W_xbV_VEqd$cY%}^mlH;nZW2rvAJpBviJjfDE5ZXz4;i&K0d27JCq1_!i_dLX%^Zv804Ba{eQ0 zg*B68!pixNu&@vkq2~$#kEoQEi|*QbVdz>Lv_Y zm!RN*!7wDW&_$@U*7fzNGe~oqXt*vKXeACpqxH2b1(Z^|DLt*pjAa%HgbJ+%st+zI zN~0)m7RAZ@2B0qH2$dGwSRVwOc9w9$Of@_XN0XELqOd3%O1KZcU$J+m3%7RHCMG5{ z&iSyUHaIxUHrt41h*_g)5+4&i_`Kdc+XiscER=%TcpiX`vjDVj!TtYXB9)O_rJqO{ z@7>-KPp|tL*HzB%!0hS{?t1nWHp*@XA?wfbz$towf6%wfZ=2l#uk7l~(6K|KsR?-V zOHRU5Gc`Fve@-62k(qE}geth2~pdXf#FyrJOIh| zhX!I`75oqP^=;5nfj8kJN$A?l+PVxC!J7aJ%R)gQD7=9j*H^XD|ixt$tocs0Uj3S#Ihz(^3hA7oT zITsd^(3KEEh_1)K*W$~*6htLJ`;4ZJ&R+msD43dWhcnq{UsfpR~9_t-@Y!c}~sAYjGsslUJC3t-k2Z+FU5T9_Lx33+5`XPMFjF zi#Kvyu{yV==`Ak?E4nk;_@Sx&mDqX2!u`;bLVtxd(eHBj>Z)zWWl|IMY%#qN1Ui8l z=GJcO@IZLSaPG;Y%jA?y)l27T1%qddPN60jbR;>hHtsT~=ReLk9lq*n+r^tmJ=7DU z$>(3W^6Owe(^La>hWRF)Ld~N!BWExzj?vB5pR||N^UW3YRFv_SZFD$%A-{gh3M=vm ze8H)c*%9ov3wh3>_peaOoPz0A7K-5uL$Rmx26&ti6ABfuF3)z_9lmp*=R0Qfe5O{Y zWj$BZ)c={p9a?#`SD-?*lcaW%vYnt1WrF#&Xim21mEs25Phzm4c@pD_IllVhZ9MIy zgGMK9@>ZdpLVg1&WSg2uA?vj@6>76l%TM7=WZrvVbnc`dqmT6bcdA08=XtXIYdw58 zgW2q_gb=FSTb17J_Qf;V$S8@ggx4aY=hfa8E4xD70oYiga*PfVj$q&o>87EPr#OeN zp~5!1f;1C|>&Zf39ck0r`!=QU`Soe89H~a+b)PEC*J!H;S-Y>M#fvd165iVKFS)#WQ@~s|36*~XXjaem*c`r!3fpm&q^a4aAvQ0Ky&Bb2F+@Y~wQsWw}?;ffx><=KrIWn)_<~d1_GMs;YW!1i_NgZ-ZY9nrZG9}XpJ;?t(QNDW5$ z!;TN9pn)F_jSFDZp($_FfxI3@)p6Kd0Uq=a<*fa}`k)Uy8g(PbE}gHjFFLu=MUy(I(FI!jt1qjN9loX}+f}B~l6+4W z@oC9?%{}LnqHR9Mo!f9v;VV`jKRHqRD&FpO4VvxiI%HYs&)2snGK%wBh5&Q!)+(rB z+yCx|NSE)U3%5 zYx3hYjdWO(ABAm>JcUgYFY^o$;SPe2dd_D4zl(wIl|s_#QU}Bxzm*oM=1C|FY4_F?sJYadi^1y%E0~m0tFeLt8VMzSH!jSlXg(30(3Pa-m6^6wB zD-4PMR~QoiuP`M3Utvi6zrv9Ce}y6O{|ZCm{}qPB|0@iM|5q3i|F1A4{$F88{J+AG z_rDvNc_LTkobRvA@TnTL*oAxhQ$9X42l0& z7!v=lFeLt8VMzSH!jSlXg(30(3Pa-m6^6wBD-4PMR~QoiuP`M3Utvi6zrv9Ce}y6O z{|ZCm{}qPB|0@iM|5q3i|F1A4{$F88{J+AG_rDvNc_LTkobRv#Q!TK{$C;S{|br!S4jN7LgN1w692D|_rC^@&5{m|5r%- zze3{w6%zlikobRv#Q!TK{$C;S{|br!S4jN7LgN1w692D|_?iU63W@($Nc_J- z;{O#A|F4kve}%;VDrC^@&5{m|5r%- zze3{w6%zlikobRv#Q!TK{$C;S{|br!S4jN7LgN1w68}%n|5Hf(zfw)?C-MIZiT_tf z{J%ot{}mGduaNkEg~b0WB>rC^@&5{m|5r%-ze3{w6%zlikobRv#Q!TK{$C;S{|br! zS4jN7LgN1w692D|_ja(^L$mOsno>z9rtn_#3W!M$(*V4}++TaJ$w_#truS#E#J|jITeFApIdq}!Z zx?8$KdN=GkaHDjsbft8u^hVen?}&6*nt)vhMqz)v-O`XWAcdta7#-LswMg|+jkFfV z2bM`bX`v)aPS~a3AL1+GAH?5?FTt*PKZO1JzbQT=ei8P~`;_=e@e%Q1@qXCd@J{ho z@g3q@#p_^y!^^}sisy=1aZ)@ej*9!lo#LRlUF;IKitS>fxItViR*FmE3;;=Vimdl< z-amQ&$NLiOaQJ=ibKYmYUxeKco`5|LKjgh1;wNtRzSDaX>~eUe_Y&`g-WhM&I|2I~ zzQKE@H|8DiZu54+PKT}DdhdF0y7gyy!193Q0m}oH2P_X*9>5m`0FAkU@|}a2UZ9f)s*D1cwkzAUFrX*$9#d4k9>!U>t#p zAc0^E!6Dj9?RjjR-mrv?FLk(2Af1 zK{J9T1dRw95Y!{6Lr{yrk6;6W8U*VRR3li2pbEiS1Zxl|2v#FlgQ}M&YORXL-Q#faL+p1C|FY4_F?sJn$d)!0c1Y1P^SI zHoWHIE9#hPg>7vft8Z-@>+sjBjSc?h*0FYfys>4}-`uQ@wl|G7w~UX);jmnFVj`JQ zCo}4K7zwZnx2B3uCh#cB0Gz|OYGdVI8X>T%ZZb6nhhQfUtkRaVud17#%*4l4zd?ZA zI>ydX6DG=J>S#PYxv`VkLf(8fiXUj1+)rev;-RFXEYSoXq-=@ab#YN#^Ome&6iYDUQ&i*4#H7hDjtP8 zb?ivoJX1$$%{Y?7_-lC5o%ZQiVr?j2eSCmhy7Fvh-p zuoGErL)*T6kl;RjXEKzBhSC)wJDv?Uz@cXft0vl;#}h4af3vDWy=`vq@OLB<34cQ( z(cC&d-qAMR&_VXHglI3Qjniqm2MyixOxxLP_9-W)HwF*0#%c_?#?Te&9PYs?j{jCu z_+M-aQ1Q3+ldb!(;zJ#MZ55wv*{4ryzt2;32RI9t!aT zYGRe>z5wU{1^ETj`v3p{u<{VrvhiYKjOH^vE5My=d#~tKi3|# zmkYlV9uuw=dW8!9MgBfM#kX;P=bqxO;*wkk=VG5{?_rOzVRnh_W!o2Q@3tMb4cnH1 zS+D*t-0Nmsb#a@^X0sV5E08fpHBC=XsGUQfOM%nw-EG@3sV$h&sVBv<_61ABptxj- z%?XM$OA1An_tb0y-tsnLU*B+GBr@0+(#(RBDME*9b)vwZ&(-wI5snoTjtTsETupbO zaA-#n;m{6&KbKn(0%6}8Y6j+OmgM;vskRFQR&-$5ZPcXUfqp|MGNl;`RDtEEx!Pc% z{9t5P5qY43e3q;2ER^q$bQO^YD#&NJ+CZUvS9oU;d7y%PnyWpdP`-b-uZTQQLH;mT zdwQY#&~RrFd7y&)6j!^oP(ILA%zmJPe2S}t6DrZ+#Gljg$doy4p5+gfw8M#!uGPJ{ znh}ad;m8%ea>Nd%)p!Drk(tgA*K2HnPjanr%%f{%*sKX$ErVi;z!mrdTss`xSde2+ zuwTE+#T1b(@Z(%79I#lBV}IyGiog|kmD>zwBD$&~W=n_m48#JvPhcz+5cmYw3WpsQ z&_36a(}{R+ z2+lwl)C7YQsmyd*#R1=1$`JUyTooL{=UUXETUbOETDriW$<@F?dal(CG+iU9xe7eL zTWW#h@LX$xda5I_u27&0PLj~1p;sejU?-xp1b&!nfWz!uE2-^-H$1pAU}~X;5@85@ zjB9`+>he?uqmfvoSU!Xy@Izb^oG<5EZQR6x;r>{lXQ+sd#u4}(ToW7>XI6?0!!}>7 z%|(7PWf^*06N;VXWh6j3z=}?Zq zhq)#=JS*A#?D9t zri_dFMPmtkH|JjkYRfknH)0@Mv@QZ!;6q&9N)TVM#UvgX(0l6qvH@M-ySUYrpiogw z6=;jd_aD!9O06qE$kdO+UZi4xQ?wWi61?>As`PO69^zq!158A{WJ)Cn{2Bf;>?6F#xql6jr511 zm_|VgG%1_qn|)gs&!ZpMenNd@vwV}U-Us?Cjd~F7n(GrRBBir@L+RFXQ;yyEAQ~DO z3`Iw}`-X?M6zV3)w8cp|r6S^i5ud_n%laWO}RA zeWfv2etl`{BG9QadiZF#YxhWBV5o>zj>YopN;fYAJ-_i@LYO^$k+L zsi1q>%1Vb zoVJes!0v)H`;v!}&@Jc;mS0}F$pZ@2xuy{w0cJ1=yNR1zuc?7GCN|42E3I?q-w-cIbV2c%&OL ziwzEihPxtA;SK9_^+E}jFDY%~^KvI{Ex1>Px^cT)r7avN8qclp2pqdGl;=f5Ph+vX zy>t}|Y8BPGBT**bP@XSeY6F>KpQAkM!SDZm<{n1=tbBufro2@8hx94w3aMRMD83-R zM@)(vMbZ0h?|Z#jZ@ZWGJngyK6Z4e2|Kk3V`#tUh?q;{(`ljnH*AZ99RqA}v`H1r> z=UL7=C*$~n<3`7bV}tz_`)BNLw~yLe>|Wt}!o$KP!mzN6e}R99pXK{_ANOPKK5m8! za$fcu?7P_mY_08&w#RI5vPEt6Hjeogm`49fsL@~p z1m-8c>RIfVmoyRSfe1V+_16_DOi3)r{3fwX~c%LFqxr3Hw@2Nw>U6713Fs^Z?|99dCY4`Zr0DoC2Wq0muov z-u#@3DQP*O()*>_S?qSnH>_S4ix@{s1PXVS*Un-Wt0~Z=iYQP9DBLQw&SKYU)OHwh z3r4#1$3a19G$ttC47D9QSEIJiuL!vrif>u4VHSH_A3hCPTYq4vx4wvlgbw*!Q@&xA z$ro>!N4x>VuP9%45lEA-cu0JY{w`xK2T(!sk~05=AgK)xkoUu4!j$3SE-I^n)nNMY zKzOLA><}b;Zh6i5y1h1Av=_=(#9l&oanofj=YcSBq78hpn`9R)reQEyE>l`_u8{{k z?}};=I?Ej{Z8!$Pq~ei0us>tjV!2dl!^|9&Voga?>14Ud(uSjRREkw^O(no` zhf14{fC}kRa)uS{zjU1$mOH1kWg3(WkImmZYg*8Cvz%Jml%11T(cVih5-7z>{TWcw zs>onuXr!ohl)-XmmHN~9;zct+aWrXvY0Y5}C+)yyBh(@lh0s}UUun%$zHqTSh{8dZ z+gnwnBTyLb!kMN1$$YCL`t#k~Xiz!=5BWW%b%#K_f`01a=NyoW*sXC`ZdYmD zM1ew4FA{|S_+_}%e~w`gCC`@u*dHscJG&tLqHZS%q2Gr}{mFv#i&bqZ&vMaH|G@(B zVy-9R;QJk=4F^D6Yi+R<9C;4scNMW;XSulLOWVdlWi|a0G&#M9mWk`)BzKJpidqdK zM~f6uA#?}lm1`213mvvJr88H>%ehOIj)8Eow_=X>Y#s$(b(p+8cENEU@rjAl7>vD- zouj1%pB^|Auh!;sU4mc>l(fdtjG(67lTIC-M>WSnz4axV-(ciQMvcjb1Nyx%*L*Gu z+Uv^NM?iZ`NXs>d!5i~rYw$4N(@Gl80?iet6U}V;ST`ICAJfP3a|O*YP)A;{aX;u( z^$?vv;_T^6c4s^dN4#VTP0eG1F7vWnzYlbmZy~y&nJgS|5)2or>2%ciZfWCQ!@{nS z!Bi#)ccf4y$3UGA%MEAhIyM`y(&{`qlmR-2N^16i$`U%~)iqLF9;qO_v&6p}gex{d zDMfbK^)T^#ER~H<^r@2vvIn*F=1w7-WE=v!VNvS<7O0=- zcTSJ@B{SK1bu~Wd)vRdhN1N!l4Fudk>zG%KvR&+|Wo><+w49EW>HY4!YPx`nm6qc7 z{|@HIjQp(p9{HfWNp?xkN$-=6N!z7muy@}5;t|*d&+h%Q_Z_f{U7OeLdCqgU=K>f5 zsP?e#Z@C|GA9wF?pXU0x>oM2$u7qo&YoYTO&c|RKz&__H$8Q{uI?i?UIehk)?2p^8 zwh!Bv2|pJ;BwQ@S1i!%WU*m7#(|nLG=YGz8io1(D#zna`>|fbu*!QtBY%jaa_EXzO zY}2-Gn-5HUjem`^_%K`%AUC3G`p}fQM(3_;bH7}Iy~eX)mOK(^>kbWcg>w@KIk{R& zW(9k7*@jtsBrc)i-H~WN3^+|Dp{5(j)>1NvuPfU+i;u$^S~pp5EeiomaKH7caTftNjX`q5|C43^`LsIkDt~4CUnVus}$soR>ylNJo zjb(Hq0qvb5j6|1x!Lq7Zd=A3UBDyA5vO;mzE-$E>CC@#--iPH`0r!qxb9QO@`dNJ1 z`RMGBc|KQ9AEx99S+ILJWfmWA3vf8eX3NbPn`E~ExJ^|w4j5@;a&QxL|d zl{O?sh4sNGvoH)o@!x~WkIyKwq=gy~FvgNh(m(|9=gQX3;`7LdZ)sFq{}wc4;Ukm( zVp+>9K8e=Q_Y!2nJ3%@Qfvj^1s54;fkN*tRLwq)wj2}qq?+Qj1K!Z%~0b%mop>BbP zuc@1+!Ws>PuP;|-@mZs}dPtqnhgx;XiE$9S6u#&2v7$L-D4R;F@NSf6v`z%^1TGY)DpmW)1WKijZ@eh2eRN;pZYwJp8#tz~ceo&Tttvn7WR>DA9FDSyDL&ea{ zRAXTB7!KF!t(N9yW`NpaFmbzKqKQj;(n2Lr;mg*|hCv0!dG(xf;{=9y6si;VeW=sh zKvb(1m^yqmeh0ggcXH(ZR%9!NoyP(rSV69gyb- zgA6J+l()@xf(q0EER|tOVcGIHXyHL$-E06f$r>`+();40YQE3$E)gnfjF$Un&j1Z* zIhfbBcxF3v>iGrIi73C{w|@3?kk{@hIRPp6QcUl^MuURHp!IGAVXgHB5{dkN2MHh+ zDqAzVg^HmK&`sovAp!Glhey(8kb`~<&=MDoGvv-1%+S1J#PU8?Vf|d3B2if zR_R3WCi~O!RkO_?zX%`OtgW!ugKJ3i$K~s0n?Oi&3?>*$sMxjP0Kb?)`G%&r3+?Uf;Ws1w~&4`k_we8Iz+z@?q$P zPRmz_6;&WqQ0OYJn_W&7^ac}vj}rZBpSl(yp`uM2;Ni23mH^uTSc}`NNyw;$b|VD-0`J`S>X&kJ=Ao;drOXr8h?bAzl55F1;I&i zcoWGti_%c~S3dmy-^F|#=l`#h_sbikS784CT4|rO0_Okk6Az1i?;pL7d#`|9>^FJ- z>iL1^G0)pQ=X!Q|>OHdiCHLpu?{=T(-sj%pUhMiatOWR|>pEA`)$LmC{D<>-=R?kG zom0*o&PL}V$4ib+JKpIy=Gg6Mb2#i@vA@keVy_qeB79P~OxPi;r2HG(Btae ze_x+EQ>)V)f`hrMtmZhrL@cMD0DbWcd;{ceBo)_a4hM6mRCgTTB39D3b(EwJbj`z5 zK1T(OJ4)9d#}|qUx)vcg4cp#K>RmAr*GOp0?PaTu<6Fg|8q!n3M`&KU({U8Kt#sva ze4zj#^41$U(<~Hh1L`ajNMT(`) zQ73D4mdnAst+M?%d5OSre0Vn^Z!JWsh@OcHsyCF>AIDb-GOL2$ABRl$#3Wj)almoc z`D%{itHkOCQUsIG+}s?@H4E#HllKVv(V<(di^dPBbBc3$W#e&tm4HzZQXE}ojt-uJ z{{Pr}@9;W`>u>yS-@R3~EXf7ixOcgC8<16OVHKm|LX%}#wuNO$NV2i%)|IFsgg_D? zkU;1?w9tEpKp^x`lhAt)1OmU$IcIn8-mB}p-|zGM{(7JH{;}uI%=t{8+1Z(M&M+DU zN#+#x(9(iMo%$8TV+<5ycft4`T41=sPJUdOsaVGioY_N5jO+(1vg*q$!>+yO_t08n zjGU|lnB3?CK81n*j@6wry@wVb-Z58Ng9JEJCFv}f+(T;+ZV&8X^RZ8`^#eXu2bzNx zAj9PpEu%R|w0mP_Sq?*U@G3;)3^|w>-IAnX&@ss!v6_d^>7kX#C=sDfF=avdi8|K$ zoGCrDBEgmp{Ti~T!`>KihYp(9!)uZ0yvh7u60r`(xS}PRh&1shn61y zTim|D(IVu3i(8yGt%p`4yuMJB%m(n<%dh!`!$fBrtog%6^w9bvcLFy} zX?3j^ys{7u!Om{E=UD051^MLcp8H9Q^CG|8ZrR2G;1nqB@e-Ft&~*P1?r7lhBXDn z9RwD)xW&~~#r|G9ViC7tO?F22@=(i+TJ|_QhBPYsSlKiT!u9sEI9#|6{ViG0ivmc%dp02V|x-{akEVV*EInqaU0fH zu*HLHt4f2Vt0^V7VU0l>#lYsakuRx^~7YqU0^CyHRV_f=Kb1^QMs@T0&G2`~hU zO$rXy-l&-{7~JZssD|8dDh_rU)=1>SN#&wEP@ZxWc?5#(K(MEffJ~N`8P;%AnuTDu zt(T`1dB8v}!`e%m*kgiaxSZ&FS}duIcs_J}MiEdeg7lc6Y)4hFYGWspD* zv?DtWYY1Y|QnBEGClw1EhBX-Nqk_S0#!^I59w?W%4XXfUQ^4kyjl2U9!DU$asGSg4 z+$JpXw3tx%5)?g88@>BD1iRT?22CPw7YH2eG^|0|h~3A6$t`qIFuQOVR<1K-_c4^n zNFD`ssVHW6-A4d5 z%9YSSjH_{+-tKMDrza*sl-gZ6MZ0$ZH;qo?C6DFZ&D%;~tZ*|#L9%8w$ermS6^wP4uxU30t2%*l)S-86^J;nNt9l=eC^c1~7 z!k(40Xm=;D6Uup!K#bTs=wcP5tf~5;Kp&AaWB1_zLuY}00`|Yz(-WnyUqCtl=}3pr zIeXTmC;*Vda^~!A2ZS5bJMaq#B&DY#OH{xPLP~AvDb>S%YSxq}0Fc$_@Y?`!PhBbE zJs|{e0MckpPlGmvv!+1-NTUL!*_vLO70~+4ayClIOAugXIrDZO2G|%`%(1fj9&mv$ z0H@>i7Yco%nxVv}iNE2tziSicB$A0E63ws#up}`hF)A@Ip<_?r?f5geq3^2rx!4;x z2DkAw;U2#I<4fX`aF<|#wmd!}o`|clZ`Chj@9T=%jvMzLjNKBuJa&HUENxcoq}XxT zNjNCBGPYlAMr>3p5!0goihiiQ9(@Ip1@}d7h+Y!?6>iMi89fZQ_;3HJ~X^Cyd*p!oa20_t#Urq&ea~!ex}~qwKAAgI#Gaw5Qs`Y|Hviy~TQ0JxlvU z?X_OA9@U<*ZnLh`bJfe$+1AU!-uv({W@&NN4v`KD?7%XrUt$#~4T)40~S*f`fX%{bmT+-Oq&0j-H* zV}UWr*vm*5x;jw*Sbr1p6Zh#i>sRRK>t|?-)iOP)AFhtpy0wG#je3o~Lf=Q9p^eo? z7dLj`tgqP!g_PS$mN&3W672!Dv~6c|tIEp}ZHQXj+St`K)7+NOMyWI&WvpO;X=C8V zs3*mR_D-{Lpf*9}GoqU24$^MeXfANHJmT4C&Li|PC_QZD?LTu$TpNj)ab~c*y}R8U zKS-ORibPmNdsAa8oh6!MIYp9JV>KXi?_6z?BtTKN(A;Pa<9LXN4&uzAVXZ(|%psIN zepg^at+o9Kv%pW1CQma@@{hf7(PK7q2SCOIr#&P^)!vPdLUSPdU=rRTXHi{dBB~8j zi<(HLt;>wXwBaaS$F4FMDmH$wwOp0nuJ3cD@%q#F2YW)(|5fr_*3wqp(P_L=pv?@{ z9922CU5!Wg;D0}*!zC$h>o)G7BC^Z4ma2DI`^H^n6ITsYCmpJkwKTVGG!OO}&2@fF zR?-2Fxt82TU0p4k+qPlT$*l344td$s+S1f*9w4YwlXN?AG%HA+t#tYyScXI$mTBnOG$29M`LHR`fSi~K)yB|8EI|B+a4R|Eo>OO zOAB*nLXYnZ{Yu#RWF&Nr?`UZaJ_t1?JADU<$(K2&U9-9A5~}%NDnUW!rrDEt#+61*VN_t-NRkA zwY;m?_qv;NRZ+gIR5CW3(hCcfEbqAk-n3fN$v6R zJo2^U{9xMa)?5APym!IAobTqA){6Gcv-D571>`kR*G_HFY%Jlr6F=IlH70O>bKfPi z7*VvUp}wlDysEr*MQMp4l?6YD(wCDh0%I7DR7lL$RT>v?7V%%Ys6INwoy%=X;p!=p zbZcvMCq^Z(7kObT)ss_yCvh2opzP^;agpJ|^b5#^JZj+7HhBNkll*@ZxqCG>ZE2=; z65d5y^?wN7_0s>Ir%mr~^=D;P-~A~zT99^mCkx82`+NP0a?V`JIaDvpq{rS%g$*pr zLLWr5VTvmeT177w{MRNkm_7qTKk;7@I0)TI?dn=FXrRpq?HW#3Odd4wXRUTM^YduF z%FzlG)|xqz=0em|W9Kf;5@g&_)y84jy*CfirYV`a&N`uFKP^e8$Y9VT-LCb7beOpoZW`C?VZYxjOT4wxsJw`&MxIWuB?XYPUSyRJvh!+evl&5 zib#1!;-&sq)`Ai~FJa_XUf>?qP|>`}EzrNDh~(jxN0UsJcW`PSN|hnMsVe)sl(>{+ z@S3_+MRLbt?8>u(E@|ha|C*;wLxsC9+U1R%8(?f)d0Kd|$iP9q@)yYgzXYX{zmswm zwQW?sr?SxDyL_jrw^CYg*W$Ja{a(rk9PXPe!eRAmD~oDY>WwZVGG3+M=EedC%@3MG zH6qCy2L=8g82G=AvPC@GHni@dC6>09lk4nk+_efu)%6!SQgTYC|2V7-QA7;8l7l*0 z%G;Vc>)JbXOcm4AqK+0`Dx;H@wl;6;G7h0?@O+JfdEL0GTrcBHv~5Jelz+P`%+QZi zC4A7WU&+~^^(~DqeLpT}1$J;tYn3ksXcLq)HH$;2!-|jh`Z$9l*tqe4?a&?AXp~cb zB9W)i-5k|MJ|oq5nE>wwo|=qG&H$XXMg>R7Yvkf`F1z|Y7iB}2xGqg|O(&!b+{qNs zP`kCIqqez2X{3TS)Hd#D-l&vNZS#M$I``rVhEb?eNu8EdZ#K$@h;p#+;g0x2=wpI8 zD%#sNyIgCj>$2wxY-n{gHFh*B2l{>`%}uV~L7WmN$}3#&kV6?q6@{^~Q@VBoRTMdu z4V->?7izS*ld@mW(W1Fir@+b@&J(&Em(a~q6_-;ImRQ$uEy({vsh>2shrs1sYfD-- zw{$Bt9Fgx^+kt6DsioOD#ah*T1SPGkO6Qdb4oLSbYVFw4sMK*8ifQ2_O;8;+jtRY~ zysoGdwad*j&121t^gU{H8mrZ-jdK3t9AU)t|LC7XXa9Nq9{p@~B_Nn%~_OS9n;)BGC*h9D>af$jv;`~Hk;;6*tL|vj3S_Lx`6B2`=Tkw7Sx5N*O7suzs$HnvFM(kg)w`0%8o`~HOyDs+o*csS4*coe$HL8cI z=f&2>s$TQ!ejOwT9LL&JKDb1z7YEerzziQ>+Rjj>*id$+umfa(|%@G z+eOA-As;cu&ZB(=bAt7b^{jQfIYc{0+h$#DU1FVS9dC75hgwyTn;376P(QNrAQAta z`Jwr$`4qG&t~W1KtJV3&mB#OkGmK-@M!1%$h3aTEU*##Uti2Nh#@v_sHNO7q+wcwA zs-8o`9zpzBxes-6h>6TJm(pP6?@GKI&AG0Br&&j6*J8o4;?OVY6BfN(zI5q5f)^O} z24)hQ?{ChaDX|nEex3XwYfhu!vX-`uv>DK4PV$_xS1^IONiRzF0Y>`hisl{2&0dsc zj0pa$kJ2QGESn}pQo6IHn?=?Po|MQ*0%^v-2?DN?=B_5=b6Shz6zV;qIBxnUMM35Q z-{6FHcC19s>bqNwms}LNjmM})5CtzBj0b4|!9`*sw6|+KAZ6(6>ZURocT-elcw>wB zlW~_@&GarY_hVjs64MH}+29wH@X}t0!LK>jiiL4gI`7rw^y+_S=*%lPS9G2V9Wvu` z3Pszx@5Db0(dLpf%SI2)LId%ZOmndM1LfNFP?iqU7OKUy5SRCN_q|gBbu`5(Ci!Mz z@3kKFMxt--=1}M&ipTW}{efN+T(RByqiz7NWo$|w0g#5?QbnKX@25O?1f!EdQKHM- zNUu5BCu*Ro=2s5-FP6R7w_8JTQg5c-S?hN6PU@ZJ3NIRVE%#g`zG9XU408tu6>&{q z$FIAYhlqMdrpHq1j?#B)@#4V;R%aKp>P_^Hk`RBPX^f_{+^)VebQTRLG3G!fN;HBs^#6q(ETN&d|>T$fD2*T(xY$B-HDs;hJy=_0YtC+SMPC8AB=H z+U4a8SD;ovFXH75wJqB^TG_~=c;|COwCN)5I1R4lSheHRN_>V02RkaeHfsrL6c{Vu z4KHEguju6syfhY{!KRi_m+OnU5nMBWiaA)Dtk@fb6xN-q-L#Ka(lCy^}Msbr1fBaaPL88|u5Td#IIj zUBZcq!M1saY+S6NL4ZifmrE($wQigZ+#mhksqN1#1a^!ps(o#xhldAEB`r-9w^q*` zTlmCVYCx;@asmESE>;JkWqh4mBb1JdtO}$Q$Y~8XfuzLV+5ukPfeqA^R^j>c(wQrT zzYbRn)#h^*uz%WzV;OxNQ0-8^bMwIqb@Ia}mdC6ur>j`XH@fH#9+9*1E%R4y9 zaZ!Qz)P#rZEG~BgbyxmQ)@JbFXyDB|ZKj~P&;OjJk238i>c0H>F8y^Jz5N2F?{cEr zaA+-wI{v{F8OA3mNrfJz$jDK%GQ@+I|2J#|Uhe5;4c1db@(hR=`Gut&OA`ZoseelSUC4jQ%x>s4 z&UYuT5%qmM2W^PlMlXIq>1d13LDFQ-lrfxGP(V!?-QQ~z*93EEHwFIRC`(EupI4>T z2P%u@PpvY7^M)y;NqdI@tVQH8btF*0& zwt4sR-1v|s_i&DqrBD==7wh=1D8xkv#3H*8;_V)CduRKhFKMn~9~|n0KJobFdo}cF z%1t`Ip;u@&AZ{9t&7t?xoo~?KazmT8di!&FRe%e-tJR*9wo$tDZ)hwNC@3Hi`i2^e zeUU5P;3J2eWQRVa(MoQ5ztEvz=xZ-dUVw(aqV^&N9=T*DHS~p7PHOeg=bnppJVShx zMeKC;9{R|Oi@#Jt-=#ahrMe|v^#uRlc<*26O_zDwE?$eh>gHqHE?S=Pw$W=efPvq( ztH|F2YE$xPOvvULvYtAYeTI5fNwpHGZ>+N29xjoE!-@3&* z$||-T^9l1bv(ii$Pa3~64l%~zC8`(_?(|&bqCfE0lA+vpdSe2jL6I$lB|Pd zy0irXF$reNsDuDB-Ja4zf_8pwAY=~!a2Hy0dr0ceFB7egFlTjTgLq-UO?77WkVKxJ zGv43ZkPRgvz)Z0h_plV6*Fz+PKd<%-w})i*QaG$$X$_VY=Y|0{8aR^I^Kn?# z^V%gF&Ils&hHB=&+h-jmn^j>CZ4+u65=r1hqVwV(>w$f$24@ef}uI<0BkScL&G zj6`oDkv+eCm|@T3Di93xh{)0&lHT*%hl4S;nm79bZ2gmW!+{@;)Jc>tJ#~`4^G)yf zhf6TfdxaPGkVIcPT8;{`RUBtdf`J|up5H^leg1sH!StE3M=S*bITXE$r2PEWVkFkT zdjuj3xFOEM9uoEQXJ^J?h2;yq_Ae}l0z25A-b3dKCs8juQ({?%4!z zo*0iNU^Wo>Lri$oxgtDVX z#`bKWl&7K2RfUd(+(<~wxscqBVW|fdOzmj|8`KGz%{})@V|D$Ay*h7Z&w8+raqV*K zYU^&4lcyk}Hs$SDYI<rvaFeVkUu74z|Ca9k=Z*wK!*D&!GSe5nBZf{keVC#rd;( z4w3wD_UZgBZ4625DQ_x-GI&1EvQNcx?Wnp4x0+KD*2g<{$!(%wN(| z1MoCjA!Bs;(aUjYcC>^Md@wS8K(@5`EHpcsg9x0PzfaF9fTxR0ekyJEd^J1V4WtO- z7&O(0z^m)j`D!}UKXxUMgX*dZWSQ1FbSj=@;G_o;SRXvTrxM_T=~7*UOiPPAz!>@| ze@;&Y7`^^Z{_bIWKYrJrVBh7B?^zj$pZ0gs_{oD9zs#TAv%kbo9TYjOfP6yH77T(Q zf6yOFv>)Y+=_v;ab17@yX2i~sTcOwU#`LU6aZx`H#z}6(^>ohIp5?+tJtr#{GJ11( zNlzKr+z#d);?p=PfgEfw;>-OHPV6ZGqc_*~;}qEk ziu0!Z^nKSrL4 z{4TOFQW*XM-~T(qOPn8^r=8z9o1B@@_zpf3oqN z@qlqE^!$hE@9THyeR{P%M0-uUP;1BSf4X{?dJ0bX3)KP2+sci~@ygQB*P;9W+vk5U zY(|nM4tz9`qTjLx*+=o(W_u&;f73pI7vh8u%_~jPWHD20JNDmr=@0JD;~3#}`THel z-k2sDRGAV_{bR}GaKgoTGml?CSUiCx*1rSUwkaRN7BEx1K2T{|uOt+!rXA>y^4(-nHG^D+v}0zTp05!1Uxk;Pz`i zbDHq_uJ{A-Nx|&o(qOJiGIaU9UR8l9$6eMs$~y(~lS_bt9cIZDo%f}`(o?up7}EQD z!QA9xAYmdng$(X41`0($*;{m!2awN2!F+mw{cFz)L27pw6ebq}#rBI~tPUq8sqIKV zCD$7rUb$`X+~k7H>;<=6eNb@2)lqINSeTp-oZks46X{!+nMm2+L?*96WzGXOtuoU# zFtb8|yc|>BTp<0KC$)VUgkba1QO=9cP0k6H%-^5vUxR)Sa7QKPC1(qc79K3|%z{e& z=72yDRprLSg5)eI76EBi`foFq7e>%kn096Y>JKn)OSFGhy%6LS0(i+8K*6B7J5&N2 zWBrks2~yi;jxrm=b9yjM+W5#ey;iV*1ce~Y!U40Bg+Y|J!PP%KF9fKen0BURpm<*- zD~dya8kCruoC=gbbT}Zec@t=JKM1&ZVn%WbaPB*&t}$(U&Ift^)Bp}%7Lx&SUlx=` z+SjxEm>gB&OHB_^$jl0RuT*^tf(!Y&yQZ^tJkCjjC1`_x9Y zUz~~tc!KxE=+fkP@J=C9)AV+BD>`kvFn~%62L36$Ud93Mk8Ebx(_9w_1on{ui<4u4 z^?M`-r*9QzChct$I-$Gc3zK8|rJS}=m;Gf~>;b3&IU<|p?C%AdvDsz`10W#aHIYT63qZxhp!BZ2hSTUonW zh3w~m|IGNbbymMT^MrKRSMy68P3r;g~=gc zE+}H=;5#Utom~JNl{-5*m@+|YD8$~}yp@97a;9UvK*#CAR8){c(YDSWQC^_qY>h8X z<^$zgRY;3GYl3MUj?)~Tp3EcsTwbfEg=WL6PLn+)IS7bc*$Yn9os7hc%7fvfWNwNZ zJZ`KR+;F1i8gl0(2ZDRJn3wV@Cp*Lob(}TvImrPjm{&X5VP2@?RLA#A<^VRSp4%xs zN7=#YJdRTyo|#Ng6!W?I(u1=`p*qX$>B%@S{$_gct0uMW?SI!8P6?_!284ecnEI|s zC8OXTBAvUUA+S(QV<&&`?}su(z>jZ2`qA<-ur^CWxQkW8S&9SZFfjfh zgtsJh%bbCddO=!Ca_IZNGIV7q@fS$!Hz(%C{~f7~sm9sSSCDu=8+!6%arS?^bs99_=UO&) z0RCXMnhT5{jJu7KjIGALMpS=AzeI1>7eaI33GGa6y*5RQt8c1Tt4FGf)e*{9%Kgge zN`o>HQUK2(YwmACFU^G`Y0F4a%DsN=7toy~Y}?8m+Do%wwoh2wh|KAwDbF<*L4r0S zO5?_ZNerSkv|o@4!tE5(^5^u@#20{xL{3(i1Oc{J{-3L#qk2vgk3P9m!?D4M840GnTnb) z?V-Ii1!k+s1TM+x<(W=SW7A}~Q&F*G4pnDbxMRd~^QZUHMCaO{>sK{C(5sxdoj0?W zCOX$Xo>!nOX?a0v+$@;VOVb@}*6~=P`(8I}-;50PhpBOWz|dZr?y{9Pu103{@}yRT zn6TV;wXjq16t{P_Q%SuL$B2f0kw2rCrZk>g7)1KjSuqqqkdyQ0_RX>4RMm6Y;FpS1ps4QS>-1|W~^uYN^yj z_aHlrmCk`G0*aXZBnYS>`Gvg>P^fxp`+gnFs|~Mz zMI8)28vu7N&g(?|Q}II7s8ukj*8(K9v*yOy52Qv7bS@LT**aHLjm+*f5IC|3Syi!% z=_;0{;#t-Lv!t|(>4rE)By>mq;$9u73FRJ&bXG;9GaE7$O6Wi3FYMKTc1;m2!#Sd- z4w?m=3MB0H`7?V}V0ohA{Ic$B7M$dUFqfejm0%f5MU^xQ$PFRX`9P7Nk6SamGlvgG zZ-Izz?beJRLZ~zHrzMXAitiVp{E>0sED4b}@t=}EIe9Gj-OEd$i|kv2N~OTQ;665g zV)7U;<2DldErWc2mZ+;c!P<#ki9L#7|Mc!Pai!Gh#2uybQmo>Q8){XoG$Kv(21NbU?mQ<~9Pps7GWi}U9tj{wxO zOT=A_)qS%dsfTeGfcxYZCU*en+FFA4HmP!F0eOHaXp`*#xNTC|*yWiHOVu-ZBJS}8 z6O-L3*1FD?ZT%u9Pq2#rISCx2G* zZ~(Y>W37k#!mFU3-yhbHt2V4$iww5{$5S!kSlc}thy$Fka(3R#%x@!u3xMMWz7cvNvx|a&synKU^-T3`W zEJ5_I9n3szBLXXlZ-HqDVqn7o*~*5I5MVw5=Fkibva$yZLV$T2m_sr!Y1`MST0uGp z0p?Y-!@or zZY&nFVxj1F(J!JOM&E*F{tMB+KyTnaXy@M;y*heH^mozUM1KK2f}ZG6(eCIr+$h)( zT^l_hx_`7dx+FR`S{R)W-8(uYIxrfE>XHAz{@{m&AV`KPP@BBrQ&i?~Wf8 z-yUy=C4{E_4!H@OkV**hP3F_Hyjm*psnGV)w=Fh}|4M zC7gt1g6-k9@aFLP@VamfY#x^2CWd+8>EVgtQQ@KC+;B8(I6vZMhR<+A<3F5NV7cH) z=V91Cyw$nhxzf4FInVi(^K<7!?BMKjI-RY!!SN7hHFk4WI7PV2aW-Vq$2lXM0w>48 zL9P8g_IN(F-?87YU$UREAGaT{@3e1*b%V?73+!|3U&2yiuYHWY!)~{?*o}|`skJNY zQhOhJzCFX9WRHgJ#6fn`U9Bg8+gSFPu*r>sY;dtpKG2J0&8V(WbC*VgH< zp|~42M|N4QRx@lLtg%*E<<>H5u{Fn<1}g|7t--LW7`8O?2lH$56Z2j3P4i{*uh2Ak z(7en1lX;zaxp|>^F6>$S43-v;HIFbm%ofO@9Awr(6Q#`D*IWRLi<8YU=3Zu=88VArJtss zpdY92)DPDW)0^~z^?JQZUk+Ou3-ww06n(5dT+i1Nx{bZDe`{ZAA8BuEuWK)APiv3i zhRi#(n`ARgImuQ}H#J4IRcQASIZepVgq$km6d@-IIZ4QgLQW9UC!|+MQb>=G-9nBR za-5K3g&ZT~Xdy=lIa0_jAv=W}A!LV;?LxYRbP4Gca=4HVA?-riglrSiDrBpW!-TX5 z*&<}KkWE6Gg=`ekBxHk-Mj`8kGzd9V$RR=w7IKh~1BI*;vR23%A*+Sd3#k)QE2Kuq z0YX*@sTNWtq*6$Qkd;FA7g8={g^=Y!%7l~(DG^dEWSNj6A^Qp0SI9m>mI_%SWU-J% zLKX^HAY{Ifc|zt2nImMjkXb@z3Yj5fx{yL4(}YYFGDXN_A(Mnm6f!}`cp>A2j1@9Q z$Y>#>gzPP3q>vFrEQOocQn-mNg`3z?xQQ)=o7hsgi7kbj*iyKOErpxdQn-mNg`3z? zxQQ)=o7hsgi7kbj*iyKOErpxdQn-mNg`3z?xQQ)=o7hsgi7kbj*iyKOErpxdQn-mN zg`3z?xQQ)=o7hsgi7kbj*iyKOErpxdQn-mNg`3z?xQQ)=n;3G(QWM<7mcmVJDcr=C z!cA-`+{Bi`O>8OL#FoNMY$@Et5J8q$xQQ)=o7hsgi7kbj7_!E~!cA-`+{Bi`O>8OL z#E>i&7H(oo;U=~eZemN}CWid5uy7Mw3OBK(a1&b!H!-Ayg~e^+;o{m$$S@&8g$xlg zSV)18d?9&41_{X(GEm3>Avr=4LgGSVLZU(I3HesYzl3}vTo zN66hm?hF;@&_Ro3b{bY?}hwM$oWFf6Y^Uj=L$JT$k{@EBjndYekJ5A zA!iEtrI0g({6fg-LVhmfG$B6|a;lJ1gq$qoBq1jXIYCIDkX|84Aw5EN3ppMax+&Um z{5+PQ$MExLejdfoBl)?DpF8<^1V4B1b2~q~`Ps$KPJSNF&klaJ^Rtbg+xXea&#nAC zjGrz1+``Yz{M^LPW`1tuXA?b*4g756=X!oN@bgf99>ULq`FRjO59H@Mey-)`8h)(me&+Bq!Ou89WBiQrGs4d>KOKJB{IvLK^3&j_&QI9ELmR2O zrZ{>y`k8W`_Un*2-JA#;^h3>DGin;fkH)`@&y4qte;BVA&p~tlVdEa-R^xhDnY+k1 z4|@DRH%^3Q`dzRSxYgJQt^Ufh^MLF4}&{SEyk z{Tcmn{Q><>*sQ-+zYKN+&(VLWpQ`uj$LKpC53ogV)DP5a^$NWdmh0#1GxSNYFE~se zq{nnq`$_v&`&|1#`=|CQtPMV;J%U>TZ_{qjuF@{n&ewiz{n>gb@m=DJ#D|Hu@D=|8 znZPH!Qvsc_#9BxdmjGP+j zjT{r%5owQXi8R7WVQr)$QX1JOG9NcFPKu0<42ukk#3E++r|`G1&F}$kMR+y*eE6yG zBjJ0)w}o#AUlqPMe17=X;nTw>g?ERK40nZF!_BxSVNG~dxIDZpyf{23JPj5OM}`N7 z2ZUi09hx0qJD)(l<4xyf=daEa&V$Zf&Yzs?oXedHopYTtou4^<*4?o3@JH(k>krm% zt+OEWae{RmZa+BOI?QUa4z}uHwQ#w$pS2M8AWX5wTEne;D`DA|V*cCw()`GL+kD-8 z(R|u`4EG}3Vcuk3V_s_h-aOkp!#u@Inn#=4%{Fthx!zo7)|e~J5_73J&p8(NHFV&P z$qmjyPMuSUdmHw37Qi0BWM_=Cmy_qj9m@&X-`QW-AL1T|*X$SUzu1r3_u04GH`-U* zm)O6ve*-O*lkFbd>d`ujXh&?_`j7RE^{Mrq z^>^!U*0b^YcvXCPd_U}x&5BQnkBtwH=f`fsEt!|XR^{2)DLW;Wj2#`@9&5us+4|VJ zSWSBW$Nd*2*fX04>y;B@qrA}&8;YH?D2)kN+4vFnVtf|j<)E$d>cCccbzrN!Io*)q$<@>cCccbzrN!I{QM-V;c9!n8rOarg4vqY1|`YxaNy<#yv8oagU5?+#_Qe_sE#WJu;?p zkBq6@Bg4uYgbTwwFq7AWyei}sA%7F{vXGaAyeQ-aA%P_A&(1rOvs}`9ue}ekcWgkDC7Yl_Y1jC$h|`D5puVXyM){+e-v_^kZXlpBjjo!R|&aN$Q42^7jl`9ONCq_vsVyM-Jt4bskr=i)&cx5FTf+hLH#?J!8=b{M2_I}Fme9R_Kq z0T3Rfakb`ZMU-r=wx5uFh3q3_sgNZ?77JMr}LPiPMTgXTuBZLeWvX_uyL~=B4;v9{eI7eGAo()0{6>^A>gM}O<H8^H-)?*D?GeVvg@)sdb33*b; zpM^XjxmUzZI2)a1jKZ0yrhlz}7(GURRew~!Ir?5K4`2T0L#I4v5I0t_x z_Db|h+z)Vf>_*%!_`B$Hv9rQ&$9iHNkV~kCOu~}b)Yx9(FPvWIY;~L3puT~d03K9t zRxiW-e>ZBEYG-RFYe#FX+QC|-RvP_GTcrL*o34%325V9Ed)V#&QD16*V83cVg)hdN z?2BQw|0MNe_2gL8KGtrtH`oU`m+LLj*X>nyxxLI@Y|pW$=^O0fb_`#NA6u_kPg-|b z*I4IReO9N{U{&J8dLr!g>-gGz(|ppr)x603m3bo0qc@uenw8qe=0bCvInemY_|kaS zc-43YyDZlj=c+2C5nfL`mAD)72j?YDN$gA`u= zb^N^e&*DeNTjK|ZH-ziMEAS;h4PWsC@CE<1ajY>^e_j9FILIi2oyMm_>bOuY$&2_V zGL0meiga~$Me|m^4gWhaK3OK3M=qwc~S_{-z9UU>R&V5t2p0Xd~bnn zG1e11RNi+pzNWLKyICu8OGr|8+I}2Obwk~@j!n?n*7kJ+Ns&t1hw_a|g@%v*m`0p% z;EDj!%GCx@mZ2_KTWql5SOnps8g)hyB}NXq8%cdA%~j^Qq)1lKr7j@LujO4(Im0E5 zJ77+mExqaQx_O|uFVit+Ce#Z31u}5EvU!*OS1M@gil}0>g72c?Yi&v>gDcpGDqj}_ z`>AB=yDM}rrR!T$eTllPZ?&Iqth+H623CD9*j#Pgrv8yq^8M87$lfYlEUic>+RHc5 z9TB0cm<=v&h!EejuzVZcpNO7su+?fYD?v&V%{tp%4th-Eq#@KNw-s?s4{&SVyTORB zdO!_(?#0w*RO8g32a{!1uKvxCfy9WTD2#ajaoI=XD>zh@KlStJl{SW0pmKBSZ<3ls zG|!ZK0{?#|i6C*$Fog0zf3KZXLZAbB;mRMg_#Hu|a@A3l-v=FsQGKKgB`9}gxKE+> z^)%g-yVG2!(j@^I+R4hL**rTX>#ScZ3ct!l{k__0+`I8n{VP{zdTa}TL{(0?q`%kU zQuirsUgd&*K3fAY5q?$v(BG>~>N2PUtz4YNuS05$`Jh{@T$tf*b=_icyivJ6!@XPF zp1!?uZHBwscXJZTH5qO!)-jZ6myyWth5SYcJ~+tp80vE?c?=9BpOxCj)ZJ(l*R_Xk zqzLJMbsJtl8$(ypkYr>2H&Bz8;||A8{& zUPRrdyln^FNXn+!jYB7}32*qp7!cRb64tzfYUSVZS>NGD5NY< zQ@R}2P}Zy~uPP~Bn-|wcxxQspD3Rj;bAsw|=VQN&eSzYO<6dahN~Yl>5@ z%KD1^0ju%qEfic?F3pT$1xDNERqZWp-K1=7uBSeLH%%oj-E668?lxCbyOnRE z$=^hE@QYIJfW44<6edM#Ad+Rqy-NQ-T;C%1xx7c&K-~1sBirTL4g8jB?v^)?`fj?j z*=6@^g=mq02Q7uP?`RMqLNcI)7qAY6y9MA24=^p5 zV`!Ag@c5BN9{w8N@}G@64K^GPpOVJzM&m0QdSo!b_>%tdElyw1pj}>P@Y)2I&$hRB z823@$P{H+bpM`NR#Rlu?#w|41Rv0%>FDrL1%)kO}Q-*t^bSqgI;nGfYlQy#6rCu5M zKbxl*^gU+ND`c#<&}|7YZ`HX=uk?IStvsda?@0bzx{XO*N%TKT={L3P4B_t(g@^UZ zV3C>m@qXZ~O|=pGp1Y`v{mzkNdvb`>DS#NStzqVL8unZB5$C zJn2;_kVwYT8(F0$YgTt~ns8#N1ocE^3xmnMs$3mIfiMc=T1QftIb{z^d04_d3)spr z;`Z!GDfef%cTpzUh?w$t>hEdPQP`%5`>N&(iGv=;Q^#Tt414ABG}mzw5iFu8JdHD( za;&86>UDJ~+*2q>tYa%j$~!z@ZcBNvzt>Tcl5i=!toAH>DM!mvfu?dd+kBO)Ebd&N zlcZ$CL)rps6~0+XSj2-zSIR@VUGnWAloL`huq6rQ)=ZC+N&mk(bVn%hWa8Y!>ckA3 zeLn~J^d0fa_-II;KMoy$&RA(|Q1o3$@t+o5kK6R@$ZL_yBS+x;ITsT3SA;vmMd87a zFTdS6%~=my=|9>}+UG$Ayv)vnjQ3qQ6Rx+$o1f#1_YB-FxYUdrFB*S<+`ufzO5dt) z*O%!U&hk&yR%4d=hHU|^QO7G^!V17?%7Mz5&?m@Vw%?3i(o`EMW)R7Ytp#kWJ)@U2 z*!=9duN+rTgbgw<$n^*0Fnd-nDX@+5vgZc%Psj@ZsKqYqZ2@RF*?FbxrRiU#l5th9 z40}stMlY$X`5BXt{)xE$NMm!Pu$Oe!{4}J4_A82b1F#8ckhYqe21dBNwlWaDKOh@X zU#zeu&52h;R*3HpNRvIUmz34U6?4%MTc!$`SNvcQfQ)|v}MoO=QWg8*D_kL@M3 zwOlf!Om=EKRemoa_<-$DG$d)KxeZAMzHotE$|S1K?FRsKFhHb|767GLGzx-TYet5B zkiB0o>7-2;BMg*M1!;NL<2^+0!i);<7mjofw3qafirN%XB1f4Jh17gdmoAuiAQbR* zXgAVUbDNsryvEIvGW!Fv7MUhxwLqrb8@h1sIPNja0!<4?6l?5dy`;A`Q%v1cs_ED5 z?J*8-HwKZcMvapqTcF0Xc5I5>@7nd@dA+2|=Jp*5^CpWdX?j6Otq$`D>8*_^qH5-P z&ORkjl&MLf7MUbHwLm7bj&MTxW4s1wk%rosB1($W%04?1$_+sl53r~9lA_wMg+2_M zURjC-U$C#jXdwMGcQmAQ6usU;x`~EeWl!!UrL-ZUE-yNZ8Iih*jD}r_>8u9K?o^YZ z#^^=tc_a1;(6Urx@eb8rcd)|n}rjTtfZXND)37otxVf!Q6a z5=nV~ZbV%U_61IbQ<0&0sSK^HZ1;`Cdl_OsuuevM&jqX7-o@=5Y1fxvp-Nt0 zoP>Tf2aH~~Ywl>py}cQ^@J-a%6Vat-gWa2=`1?46TRxf*_XIG{N-@_oZ|k37@dWdD zFwaaequp`bkP)+Zf_W^MXQY@>vHh9F6U<}KIMc!GHcpXy!F@*Do;Lua5qn`O_H`|| z!EyLf_mq&2a38kpT)!v5KK!8*d4+&eWDZKzTPg<^0reP!xh1nq*d2WoZ(DlaJ)D&5LLMMbv$H@`W3H2sdE7YpA+kv`dbdsc<$Rc;6>K$|ddP9IIh zE{qH;q`f12SSo~Iv4IQvXhMcjS4u7TDsb!D2L{6kY9}W5@w6=0_XOV)KE``dXi8#E zA5F||_EPhEW-6%=q@li-v!IWrX*YYYrQx50W&(p@7NGCUSky;THq82RJ$AMq!7rzD z6Lh@&SLjD7#_MeL9|iOJXbR7(WxFn2Ek}Cq2ES-Nh7V~AiN&(jHxo1ZXgW`bL70ln zTxOsu0C{83l0KT$VM91Aqa5#l$461l*TS>a?a#Fn(AR+nbHit zQvCvY?^N}%oQZuj)#u4oP=S}K&+EQb)%$V^`)I0n&9V2h{wCF(datUt=S=P6>7G8- zRE1vcw4K$0m<#>b#h3DZJ=kf&hp~KOmsf5kyZ<6qF9JJF`YwCgo7j)te-*300Xt3n zE_>R$*k|`&#_9=Rr|I8imltnlX2h5Bz8hVGCVtmSxA)@B1bF@gIWjS|k6r<83Tba- zKSTa2SzU_}NiPDoRfF&3bZ&~f7ID)nz^|JwoE~Oo#(yoV69>=gqj!PZ%`n>1-s67! zegKWZ@zdt?(d6%rdO>6xfT-Ho0-b29uq9*n2G6Vv)eBGH6< z)x>{;(fAuVXkOn4@Wbjl^(o0p*1;DDqLDW|Jhg8)fd8`^R6fJl*bD6b*l0p$4_Msu z#s+(%8kE;^X7vpNAaJ2aaE0SnIbG=CEpwD-QJSHdrO7%sOKH3rT6r9)4N0Yjc7*-l z_Mkx|$)F#A238(L0}lqsZD2uUYv5D}mF&TSX?+EN?Wu``TUr)Pq}-1}<);c22+nNW zKoFWpxfe|Y(?DJmNoaNq!6R zk=w;vX!=0$r4*Y7PwpECc6Z2TZC}4_*AHIQHvr7;E3IhbVcWZK0M~^h-hiz(X{NM5 zN@)#Vr8xk*uTp-`?g1MNBj_r0jRc^nv0uiw!Dm(^x`qT$*QlB>wJ#2kJ36u>#Fx@2 zFIdabgQ_PnknQ)E1_~(LKr%^ZTNdKe+*bw!(tnxqh`%8`T#2!9bQKCiF#s zOt?1zWtK<~)CEfhP3{YW(`_gY$jVLKZrQ-eeNH-azdk@QtfZ1p#Ou`tv-f(<($R>Q zScm7#>9fG<4!6{IMP^P?Ap}bdp4exmQV4u<_*LV6b10$wiG4`NU5u-gOt56n!UA3&{h@}P0OM^YK5;N}us*Wn()XJG8m zi3KxzcTvt{)wzm>ZN@ienxCfHp}rwgdv{XYbeEE%AYGmeQ*q-sztHn_?Bj;*-FpPs zhfF|LV3>}N`_q{1WAZ2T?f{E#u01`w^x@1&*!Hg6n%?c;ENVbhio$|T7=~Dkc6V-P z!PylMlxXkF+>qKcBWi00Hk!LBhjQjXN%@wrz0C;mj2L!zPGN5snB5JZy7sKw0G>Bu z?~Kjr?F7Kxzreyf`*B+;0HDKhhwe^4u@e*F(> zU4KB@!-c)=!8Ed-AR=2hUz#@ufVMDw|L-4qFqC)<`tgS(W+jyPm9R&*e|%W%z1Yo= ztgnvk9sN3bKfeE0M~6i|iQEILd$p0#;Sa;NhffTz4Nu4S|3k1LSMLn9|A}+|HTGy| zOP>e3ZH1O$K5m{4N%wKEt#+4jicxEf(BFpc|1P~m9{{^%mucPFQf+VbJN0Sx_v%J< zni^96qMWB}Ru(B5GW9?FEjfXvM!v@ey|J+ima^NLOPV*~>23X>zj22t%m}t(IXQDq zpsA8C4+8wZKvO|hERi$$1ez={A=4O0zhlu$%)MtZ79Tk41ey=={vqa+EMscWNbXW0 zRxCDPMjuUvm?d~nZr{f9USP!{7`)OYz=}n&ROWe5u2S|SDEp@(a+X#sGGKBaO?+-C z5LJCgwglj7#lm=t(wyhkR6y)2Gl4*m6?3qFqS=n`2~w0IjOiWC#pM|*4Jk`npcS(R z6!!6)C*`5{!I~}piILx?p1&2da>w`42%;}>!&Rtb-fmrk^6${UCg{cq>IdgK(j6Rz1yj!QzryFl# zgy4!yLj)O}H>Z!LGdHEwypowxDuiIU184N{#6~g|bYE!NloLqFpL5JGAT+i4nM<2N z0uX-+G4+A7`e}b2FeDvgdTYuigg1J2kRL#x&6p}S0pxybA;L_-oM2*p7(tf;+MI$S zT0b~*kOadBIyh&1-$p=l>G&G=@%iUSeqtilW8|X$HG$FXe{YKP<_X z`*aS9=6Tfq!H6c%XxY0w70vJT`oq}ZKL{|lD{|B9VYUf|QHu9szBv$3cfO(EJxm;d zAOhZwtgcJXYW7)xa1uhWn~>hx^z`;Hn-VTHpX%3Qxv&O6cV~@b^`%168b<_v^vf|) zRs-OUl$6Ae&nzN8`uW(+sRyI`xeDooEWF}NCFsTER|j@?@r#>6NJFDgfPTPLlx2z)(6XaC%V*c6To(C<7GaW+5QG z7!zs*nB4(T-9X(V`^X7~!Ai8gbilm6m8tSzb>RsMW!76Dh=B8RXY}n4p!X6?mptK)ve$(fhC{Wmsrw1LED$5 zGK2S5*52azQwo0vq%;M=yD2Ng^C!rQfRv;lh%G3EYVex#lye)tmmxjA)x z`+~iwkzZuIT1U_xw+Z|t_smJro;I+sZ=bYmQ>59m!P#!ZuH#Yw+|Cn_jPg@-MWeJe zsPrXZb$c`I=46{YJb%hg4Q7JHfVeY3Kn5x^OMxH)mSc8X1fV;+QB!3<#!iJ0Y(DnT zL!tN8Ng-e3{QAVju$6a;)}a}RqZ4hga$ll8XTOnHf^+&o+StVG#N@;%?YKl!2I|mZBu+OqzS%@y$>7q&&QsC zit%l+%V06>q}Z{s?$}|mHL#1eC^jQD2A0s&=vUFVqc27ugx3E>(KDlc(IcWQ(YomJ z==|u|=zyq#I|1H;p1`}1MR+1|KW+rLB66eAfkug_>}2cy4$c?BhqVck#LNmh+ILfQY9DS;Y{x!IjSBk=|HI9b|0x?OtW=U#ba7)xH>9+U{YWc}eU?GC zeJg}`S{u8%jQKv}vc}fNwx(udA?esKqfx|vi)vTS3?1+Noe|niYEGmIseDcPDV2?# zTixDkR+2_bWn)X5EVT8Rq*Fs~+SWAlNl~j(XWh68>=N>%W**9_IJ^zyc^yJ(ORP#p zU*u+~@8oDo*x9(Dxs^i~u@+5pZ%H&Gm4a z>j5_}c=-cp?49l$?DFzfhjC(>D;9L=E7Dxc(_C}XTw2hjO;2-~L6>@D(53vA6;Iu* zbCCY;Wss+16aTv#Gg*EHl*Z!T$g^@>QMCQPjRobA9O6 z!m6!wo1|Xj23FU?rJ+L?P(sxmOWh_x_lIW22JHk^Yu(;h(Xy?jyUTW)wSp{SU`$D~ zdX1g#`-+=Fc{Rl|XMi?=G+xUaDvQ?E))f`6)CX#le4pZC+%Z-g;c^jES$R!u-KyHs z`jYDMlC_4bE?eF}+O*|Wb(q+pV!yqSRFb{30(~~=^1+i-&9vceam&ieDft7_oyBf> zOAnWkk+78_mb2}ivj}eEO>lTPT)Ng4vL2AWa!Mf1Z?A}UNZ;ds@DH6Gg zQ?Hpw5X)CrndaR($G6@Ipsz* z5;bM5uU>Gy7JPBl6jsU_G*f$x{5TDt80ez^DWxHx@NGa&Fu0H zb=$U~uD-UkrlhE@Xp*PDU01(qbx{Q-B+-?wt4HI_n={3C*R7~Q<|q5?bw$f6N+y}klSCkf2jqxzG<;$yz>gsDsO}Do;)S!!^ zTcc=PngJds`&Sgz*5wY;rg1jdXL&{SvZ9LGfxahh+^Z~YD6Offu9?FPhF3vdW9R1P zZsSk>jBQ-+wZ(tcly^Ht!>XdX6>jtBYuPjdw9U!0wjM)bt-gjQ8`rO)wse(#Fu#R7 zpUR?|mHHt(+&!<7(y}6`uj>c$IBjNJD?IO zV1t0Fk1YU^N`LusuDb@W)0UUe$Sm;cyL4?Su5d1|(GT^y2^zk3T~%Gt+65j2J~j1K z^8?Px(#nNiw@2vm;>t?A^<_}OjY+O_Nq`+*i+ScieoCuW5A%YMF7j%5%~~AnCF^*K z0)TxRyw*O5XB5v{U+u0Xj4AFPWeFJ*LcwP;BPQgcEzlfP*z`a}`(~CqGQ^Tk`{r2< z`X>x*-)!XaeBIuJvz;#OUpzChL;ELp`f9uqlrUEt4!+$bLzmIZBLqJ3X>T0O-8Oji zukP;eb+m_)T_}SU(d9tB+t|eo%%|&J-WjeTO4#fP#eBB*4P$MOhp!xXk}L}4pX z?&eP8I4{q%R-@Oov0JLfw}Rp2&!6Uvq!%OEPB3~repZ4uL@yf&kkdGldmgz&f7lQ; zbn<9vYwX+wgJ$#|gc}mT%5%JugG24}|Bd7HE1Gxu3yRPW{k^_tesC!({C~^+f3oHz z<@W!NyY~)^qq^G0cc<*`Y}HDZw31i0CHJQ04yMSmEXzd_l5As|kY(8x*piWCW77j< zo9GE8A(VvB5>luk1QI%dP!k}u5PAp@Y7!s`8Vpx~yYYw%b&_nDTHGDT#Dw_vRz{V!nt zQ=buM46mSk#+(O=9>Ou1K&bx|onWnRsvl-2z||@?(aY%KdYS!5yEWse(|)A#3!&tx zr)S9EdBn<7U0^>_GD=X!Wyn1CBj<-=AYVaG-OldzrjG6vYu0tHEJ=^_>aaM0P3xQ1 zbk;jBvkvN<-(#iSecSap;)dxP*gCRJ6VAUdVTu3hYvT6m8_;LSKZ@{V1*y`-@9fTq zxZX3Doz;)>CGvZ%)O5nt3Yw22^2wn+FDll(VO!r&pYwA2K|deB2(NF8^LO@xbHqvQ zHs`~fKg&AaCC*}Z*AVvTZ0hMf)_F^I!s%@P|EdFV@2&}*ig5OSP2`GlAj0PJExj8YaC*mfrBiOTB1*rV6rYE2)ps z{HlylOwABpb#mIDmVnfZvT26ZR(2zNGYknPeW>SUXR08ZhLQtgH2XT6cehgs@N9xl z?7khFwwv}qnf15Hk-@@}RWX{6T||LLx${IJW)}Odid_qt)t1bS(M&C3Qj^JmbOw^s z5}9rk1dD58Vw#riH_Wj!hhPen0)OfB7|qgJVVe2OWK)y^Z@4@rCTH{5B^0=PH8Gls z74wd;Hfie?vj|o$;uEskOgHqRBhWOOixrc%f{}TFr3rj(6|FCs7o*8oG26)c?2Ir^ z8PZK5N@+(a>A6PMd%9X89gO8AbupT86^oUk z1a=XbrwkT=b0BI(Q?6Fq=?vy$AQ}3LQ7f8hwQ5BZJ2s=4bge`>81-N*$zTX~lzEB} z>0rzOV{ryUIMB?)5b0n{17lGJgFd5e>s0AliF7a~mCT7P1Ox5PdpR?~yqb#;+B~*^ z3lIh~@`;{ZrS!#IWRy;g%_qWa(x=%Fkz*D?DRLK<$L2vVU&Qeu&9{H79zwCl2RASc z-eMXrpJ`~O)X)pp6wZy+fh|uhjHWaDL`+##%Vg;9SFj*f3w<&BPNmTf0r946)!O8w zMc@TWro?K%6Q-G>sX{A@ROl@&k5xl0UrP~fWN~aRl}#q7uqQjVA3nu)?C2XX$4Z)p zG2fW0ZDJ$5Jv28q2h>vb8^gmWKb|s3LSX3O4F$7fv!P$iu2woR(J8B%p-$=0?kJcU zn+5G6b}+MS*Oq+BNOtSt_R^ZzOz4(1&?(235PE^nr_K^E+RAETGb{!^Li&1kd_=q42+#7) ziB%DKp0H%I3-ge}GjOp~QU&?8r%GflN>K*YX0j13!|*uC(x>r&G-THF@FjgS*$5X- zm=~J}{mE?Vh~=hsOnuVCViv_FF~Y%;>evJ>1s&kr3CgxyikXb7ATYivRsq8JnWp_- zZmq)J(9~Fza-A*uHLD`#p&B;I%46f9m+!_5yM6n`${{rOLw4i+3|=epZVhU-3k^Ns z{GwoStPEtih~C`YHiSE346Y?3>L;K^?9>Lh0^T+T)shkQoq~n2Qc&e8Vzc-_7=uYq zbRi<*9}1SmNpQa&%@K>765Q(I` zxL|243}thlX?kgOjOxj$6_OHtCTxETK$qPir1_X>0g)!7T_LMo%^b*m?Ql-JED6y< z=*6I&hLw&n&buiwlz`I+SH}XNiRYx^#5;7p-4ikyhjGH>8KHwp3+~6@}`mLD4?`p zO3X!!v=y>Y$zlYGORHl#XDr?gwha!AbPn}eYGMhcx>KgR1BHdtVj2k23_739G^M!% z;X?ZUU+TEU5xOn3JG5W$@4=r2M}pOXcM#L;n819*BfG(Wg8v}jr@osJ17NoIWA82A zE#4ADggeJr>G{laBi6(feCwa-KFIa4>w4EV*EGZoyi#w)F8@2UA#H~G3ViOjD_<%% zDHp;c|599TFFJqiyujJ*EOoqzg8v7<>Ns5xzHS{e8kV;-wDRQA@}}mFrlvgP934d;7l_ox#TCI1 zL-XZ0mu*UvalX=-ak?ZbYv@$dYqM-m4oMkjgv;Y}UF3UijZ=Izak>WN)!5caZ@>1d zQ7lzfo9TvL5-FJzSHT$Ti$D_a20-0f;w`R@D_j6o)og-QPu4fnl@d?s)VPxf=`RAI zkwrkzCp60ey?o6oQG6}2Qz5K87G)|<-oQp?305}z(Jb~WrYAeZyv9(qrH&7J<(_a` z>=fiR{Wy`A7%AZ*7{iNw-^f0)%V1EBzX~_SPNpVq6*+eG4Uc462<;;?QsZ9A?g?vu5@}UQL{y7g6klk0NGUangxH)zL@|oCg^?K&my^jis zPUpvAfpT6^Q;c?K$R09B`mc5NOl7LkH^MD3+Q1>N19)oQH8em~{#rR%>Xg?Idg*wp zPL#{nZk(x1`ScdG#b`r_yq>7K=}!Gx)yiN{j;q55#b~ccX^-gloiu^>wQ>@gl*97! zh8S%fDeDzE@aEvJl?AK1k;k&~gJQIgMAiap80oJ%`T&r#hxXRW+f8Uv4h=;I#)dct z+Po;lU#k*A(#Ev!W$<}rUaiQaX54|X0o17CaFL05k$*)NrW!J+ z9=Bg?2Qrx6lG``?&ISE3$LNS{2YL3exIW0pmun|%QF7@kT5R*v^afR(MKQDjW#ae^ zv15^G-Ck}|4(aRUi|Z<@C|n2QeamCVP|ls))*PL$kuzFdW~`0%Q>%GA%W6WtJb2=N ztOgg2Z;Wk2ewDO|m3(2C=l3hJvJ~kq2^X%6ZAC8A`^;{$O8ttA&{>u)`pJ*4)-9Bk zye918eP@Mwc+oq3|AXEkvzUCBgI2yewi)^1o)eo;GH#=>Ys1-PC{r&f#rwy4kz3gY zksCMrD{^5aVml)XW1GO19*W3Az*lgE6M+KQ{;Z7kfS7%9sFq)mL;B>9u2JB89Vh2# z$|~#Re05fOf%DbEhFCYql}Cz;q-zj1)%ovLjLrN30^2uiCp7g?fh)_JVn-p5sXZbO zaru9(TW(k8+%fsl>yOqgdM#Tk82)mapzCA=X6iycq4$ zk*u-Tw9*n>cg~7QOJcN1M=mAW*OqdMvkQqEt!jvE0Cz6$1VdH2Y4&VrkOLRw@Us=D z)&(UEG1|Ig%L9G8?>y`Zl!vRNF-E(3Y7XHuz>BH$$=csbIpwVgGO;v}i{tZ>MKRj! zGnrkdQDtR8WAQ0(V!ns+Y0r-{tQ6a3@+itj_;tG?g+?nm7FTYOjh zE>>EUBVf~iqHl-q2;W-Yfyy-BeBUhJBwvZo?^C^>d*AcE;{Cn%e%K*g@4eD{F{0X! zgnopW_UpaP-X(~EH_01forC#%w_1G>+dQj>M!e0 z>G$iufaU*X`g!^p`fj~nKSFQQ57y`FGxSM%ME7c6YM*LvYfo!;D`kia|0C@R?ORGx zJ3|}MHenaQL0X+Q8M^>n>X+(2)ps$&@-X%R+^AlqUZ}>^y~>5^7ImH4pw=O-VX5jx z5YEq(50tl*mk2)w$l?hqYx-bD--KW|dtERBoh*_DdwaH12$w3du|e<| ziehr3tAxy7#KHky=3V22jJ|J%T(J0@s%+2Iav4=W}G?B$Aa2tiQ9!a;d%7HurAp8e9p(CCBaJ)QJSlePANq zadkR{E+x#bI<6(#HbJ5k$8EB3>@1<>S;sGISAs{>nXU?#L4SABUv*bHRUH!DpYe{U z?#z?6nak`S8phz)<3w=SkkYQcPerwfXNP(tHO!n1Q_rNHY3tD6VRQzB=1%fcr2WM9 z|0>FtE@E+OXid~{az;{z>2&%)yUl(et~IHqrfd@R4EupSH+7*+qKvm66x$CB+kx{F z`@!R)fpYy$okYFfhBfBReWFpug%HLK9Y{s4L=+t?OvjE|f(fYMPdi|6AL-w3N)WwP}N} z#@D_fg@|3IeN$$*wrzcrw%Zi6E!X07i6e8^ho37ev8JtIIc)H?6J+<%@#;ghJ>s-N zlMb;hnmdq=$kJZhD>Gfw)T)h|nKo(X$>ddQ+cgnE31u~#9dn}01PRk_4e=R*{zWWNHd!Yz-H#OKCk{TS|i<5~W)OJTHc|17v04S46Z%|J+Jo ztK!Ak31ZYiHlVC_{7SS#`itRmHhqVXjsf@cv7uN0g;}p-`*1=B9&iD6hAJ#>v*nz>Of!$i4 zs7l*1?65(G?~0>A@+1UP@nTWsHVTL6xR}fBUbSv*yW=8pF8a5xcHAY(YFXp-iKM8I7M`(-1SSLZ$A}PlL^Y58Ark%8}CnI z0Zv96zK>yR}Jwi_s}erD?*N*7THr31uAd8J(YbSWlNa>C$b} z-qSzi+?tcJS+oy2E{FL~ecSw}e4hSys`<~^C;m08ZE{x7?uE4*SD#9qiV;qKnN9#Z zB36D(YV@>GP7~s`<@zf$E?{rex=#IXRMWNn16YB<3Z0G(7a$6ATeX*N4|;Hm4b;P0 ztxz?Owfi#;)mP~}V{-|fFP$zg?O(!y81hAQLL4B#Bt2d91hsu_&mJ*N(g{!0>ffch z*s0>DeI8I3!S*^zHdznrqR2yh>iuPwo#K_l;u%NqSrgYed7r%*= zDIF}^Gh!1h!&y&@8uskAi5iZl?I&P$V^@@j!AGlt-CaEc+tjN?(ehBeM)U<8bsje~ zqW;i2?1%0T(z>1f1L{>YaEOd(>2q)gUTHV0->0kAmZ)Bt=5!#y^cCr&_QB)T%hTE8 zv~E!^OAB!x)$dtHJ$uwk#W|#kVHZnXt@@p`6vyg!Eh(ZI?o`ENUep4{@i@LXUC@dh zgPYZh(&~udIXI+Vn9d9*NBwsCXnEgO^;>Cb;~;{NpPv@uP`$ts_F;$UdFgx`uwSrV zJtr-uWA$9?a2O2~qqL}GLof0=E1ffZQLCdetKMzmme%KG9nZoSS1ri&+S`MD(+l}p zq~rV>tSR@_UE8yZZ-s4eNK(jYUT;-TbGEw^XFj$JWp2cEgK_{wkeZ zd)ZRf!1lWF~bt>Y?3=+V$cp`$}H5Ly1tU@X`XoB$hun*t{WmIVy|lm1KnTl{st zfB7Epo#$KUEA+nTy~aD}U5ps>Z^8TjS;nD8mFI2G&pl^*HX&Gv;(pBi1NZUn7IzW8 zihqoF_f4*V{ye^Td-dtszhV1-l{Tz3Xd(4^>|Z}oZBYZt3-~G>QVvo)@BsL2=Vs?J zXQktF$CIeqtT;`6jVG6GiW3t)wiV3Ikz-pnSIab`*zsa$TAXINO6!Dj%K$DWIUU2Q zBE?tics@8aPE%RMHDU@SCre6j>&1@eiYCNqvMNLY9~9^MjLg=%iyhB~C&p<`s&pz0 z(NI0AkX@LOQh8M%0Q z|5{xqP(<&I2QHs?GNQ3UN$h|ou_htDj#mQi73eStL07INmu1`PaVDeo;@a-f7 zU~NP>O;$NrF<6&}lTHR>Lq$z|xy5MQp7(M~Cxfwm!rVA*a=`6CKU~{+iZD~5zpi3t zTx@mVe#&>^(`UV_cxIe-KA3%)C+GC(?kt)ar#%l+H(!UQd$R*q2JLr{S4QJ@L=f&Z zH>ziz;!GLp-yU8Rr(F-?cBb~W45#4ZB zr=1YuHbYp@5jd{02e&bYopd@lYr+fSv=c&%9?YS)M0$_TERAwACE%^bRYN->#H}XF zve^{di=t#OR-tyZBf?g@yn`ajk;9@=+yV~miLi0_7R;?1r=y&e;4I4I@V87Zhtt7n z#+|be9C_zZTjkEsT#^)kwIVz_z5uN8>~NS^R)9TQ50E1@rMM|PBR(J6xc0Dc<`mA( zOydKo%xOmPw9t(BysxKP8L5xgbImDNO!u47!!v7c6BxzgOJ~IEto(U0EK{G;+{Gmr zx@)ccZ3AGYzD?jRE=E&pto-whik#*y9v7Yzr~MJ(xuRFP%$*PE?sFFx1sB9=mxR1T zr7wZ*u8wt0nRT#B6umecSrn%&67nWAr7Pe!U<{%Vfmsll7pKh<@^X+f6WwbXJ2MNk z3BU?Q>f*D&k{7Ef9E;T02~Ged&CFBMx`r`ITGs%UKT;W=0an>`?zG$?&tL2Vum4Y+3Dt6hFb$TBggPzolot4)cak8`$`%#Tk6X(GR)m?E1IUN&nR z(N=;sC5uL%DPt5yBBCuTsgKkC2zwRr{W2D-AKSFXIhUd=+81H3B1mIZkwipWSaNWj z_D9U-wN}wG>+5KYA}s~VqNZeVoVH9%Znk=qHTFp-Y7tsWyC>`|#aGvuJZzI2=L~=( zHc!~jAU@8(JbWvU!GZ*w*MZV# zXNA3G4VXF@iv|%`YrvxI6&bAFF*}haAHZ6Ho~Ioa_A`u$h_Q;=M4W?5yuLp>FIC@h z_zv_f^3}p?UX^dWZ=5fH9sd9Ie&+qi`;PZ@c+h*s`?&WZ@7-8yzsdV!?+?9~c`rir zzXaCYPk>Lo?O1g`%Dcha?rrfd^X~7RkJa~S-ih9bH|+Idj^IDWKaBT7pNBpUy&HNX z^rz6Xh&K4!&^@6$LN|wQ2wfez93BVH3nfFRhfWNQgm#3sgt|kAh7Jj>3N?n7h8Dmk zVR~p%s4P?%@`beE7r}o9KY*8lSA#DE{}6mM_(1U2uu}MW@OtC>#&;2k@GRq-#wl3o z-)Zz4n~cMaE@Q2+!Z^rSY}6UEjLAmSC^mwI+i-Y3$LjyPo;N&y@;vK#!t-0tJ)S$@ z!QckZ)vyG(*mIsI={enVqG!aj!?VTHjkx89cvg8D5e0YwyZ}!3O!Aa@ux}F<0$;fQ z>Hfg|Hmn3*aR0&mDE34A+Wian&)wH!7UWWR2Rz#ygU!Gm_i^rH+`aB2-0R$}?q>JF z?j`Pe_iXnRcZIve9ddizPS?L&pSa$0y$PQQe{?_)uGGGxU7(F>XKE*FyR|`Wo7STprgds-v?lF9_*JOYW@=U1cx{{(fTh5H z)z8$A)OTF>x_;%l#q|@{HLfdMm$=S%rC_OW65=xsxVE~EhP^_EYqe{+>j2k6R}DNB zR=UbvMJ~Tf*T2+1)j!n#ioG2#>QC#B=@06^f%n22Va0Hj{yqId{Tw~6pQi8ChxB9h z&H9n>X4nRQh7J0D@bxf9pQ=yLOZ5WX&=t)7{2l%c-_rgJ|BX-i9`W4=dyiXvKlNSf zyVCa^cySzswZ>h>ZN|@x>wIVWPR6d2LEkoC54<{d`qucGfuuEA7%arEe!NDcL`rz!~lwd`$Bp3>Mg3iFd0-prl3%nV4Iq=88lYxf=_Xd6i zi1S$jN@JZLXum0EkFT$ebG5>@9-}rC${|G)RzvsWue~v#6+m^llA^)-d&Hf`1E2GW7(%<0U z&p*#U$3GPoE~WkgzX26VA#%ZEW;B(g5hw6!x%O)9LlhPVLih-hAxIqh7N{92qIcLLmNXY z!&-(l467MdF|;tOWN2ns!O+C8oS~6n8AAiZ!3+m69LR70!%~L*8TMmX!myZO5yL`; z1q|~U<}uVW)G^dD)G$;t%w?FvFq>f(!%T)54AU8=F-&Ec!Z4YkilLHW62nA>2@Dks zQHJphA2EE$@Bzd741Z&I zkKtX0cNqT4@HWF=7~W!dli>}9*BM@8c$MK5hCegB%&hFckKVYr#$CWadse$MbShMzM0gy9B;A2a-j;d+Ma z7_KE4r(VNwHNy`Xu44EBL76_CVH(3!hA9k_2};y68O~rho#7h{rxAqJxeRj{W;4uU zn8`4ML6jF(MR{1C;zUtiSQX`k)hbS`WSGPtMuxB|MuxB|MuxB|MuxB|Mur0QRMIR^ zPhmKj;UtC=8BSo>%dm&xc!u2!yBJ0oh8cz!j$_!#Fvu{#u!CVc!?6sR*P=O^kVbTm;fW*Em%#8Ai(CYYcX zFoYO_3;_l|gO9<>U@&+X+zc)Tok3$z859O5gF}G!UxqIkzF_zd!@n8+#qhbqp|+K4 zpV3jd_6Ec246iY~%J2%qpBY|e_!GlR3@a_u=j5`$d1CI-23O$>77ni%BD zH8IGQYhsWq*Pdd+lMGKVJkIbK!=ntpV|aw&VTRu_JjC!I!vhTWGu+2;FF~2Uj-iX8 zlc9s*5QcV!HilM)wG3+*Rx_+(Xkl2%(9E!cp^0HRLnFg7h6aX%84hANkl_G^r40Ks z?8mT#VKKuZhJ_3Z80Is~W2h$>r+%N|N`@;KE@!xm;d>01GJKceI}DdFT+DD0!-Wjr zX80Dv1q|mioX2o3!#NCRGn~aR%8+76G9(z{3^9gp5)`ST>xxv-bw#S^x*}C{U6Crf zu1FPKSEP!rD^f+*6{(`@id4~cMXKn!B2{!8R9R7KYns&!Osp<2sO z!%$7@|E-QY9HFQ1C4O?KDHIOA7(73?F*p_8`fm=L8|Vqlg9X5!{kPx?XT87LulZiV z7hB5L0V{x)y*GG=yvx0X#%spUjXlO1V;Xz{-0g{ZHX;h(Gwy`@X!mqj#@_)S`0HI^ z{rCE<`nmcReW_lky{6rw#qh;CRsC4~rFx3msCt!W;KhEg(ymN(e(b!*d6sj7bAsao zR4(tYK0!0k@aQ0xQ1*-r_1KsD$wFG})@w>j+>s-Ka}qTFEO)q*r8JDZ6_u8_BZn5(Curtb zlCU6^8Ob+IvLx=vhG2Dq=9;m~pQ_k3xHE4jnCb4wx?pXBW|-lQgb1{ZmzR+ixFcP` z83~$SM%WmlkSw*_`!m=WANb!_}m`7&M7p63;TO)0u`UK4! zVsi9~v2wYo4tGsl>;PnWc@oeWRM zps`SotWp;zXy$loi;YOmNSl_A#bl`-X#thyj_p)9muT(k*f<7NO7%!Hs!OxS_Uf)| zYg;{Lp)AxRE7aNq%^zcyFx^gg8y=%PNc2b(`je)P?fprv!N=f`NRKqCGZQp-Tv@~A zq%ZUwmKJFU&Q8#r@pz7<+0L6Vq@p~kmS{w3y|WWETm1F3XL;u)XqH&|yAsP|Ed!?S z6f<)(*%z4*oSvZh;Zk0jwJ)b-DElIXq3H>l6PB9x+rrcoX}(B7cv^yHfr}}?oD(5N z(+)6AMK(8zgvL!y(8TX}vNnRtv3wojj|2+J6ExAAZ#ggG@hwewA+)>|*@AJ(F6FJ5 zBYo9a3ARbGFpV(m%M#=(#q*<3T-(2JdC z6;vn4Qwm0AT7`st0gQZ2bEkBDWik=I0Rs6+k%Tt3)y^(LCKF+(Y)L`~L4+YyoEaA2 zxipv^nC9U|vGb^sg$WH@>Aa|GTc2q(lg+e=+~|oT%BCh%5QT%EF@rW2I}a;el~ABp z!y9tRl*2SHv0s5X>D4(YsO?(ss)X}@E3=i}`3VOyE921EVw;O?O(C}(7zh@T85mhGq*Fy$6Ciy{-K zr{rIB(SF|9@sq$SB`$4d~S$fqX8TDISI5~bIHD(@b=VlH|Kuneh{-E;VK= z#;QxPa{=nT7rMBhsC?XqbaRnED=Tm8dL0?0ThtVx-ZjCR_#W`Y<6g8^Xl0Yo29XZN zRPWsQ@nDEo9x&KHd=7z=(Td4sHSyiH5~PRl9D+;-qpD0r96h>{yj)ct3kdcs! zot5Jj#Ydnm-l@pkz%sthF2gQEITMR&;=@+Wa)TRlNoG126N>8MLtuz^9mR?FCf-1i zT~Jy8PDSAX@#DY|(WKE|nQpzanOS1+#}_V$?*w0-SvsXTk*K+%HW7H`g*EX(t9A0y zvE6A*GSk6`jIWFjfDxi6EIgTH*R35orRA0J9hT1OY@OB6DTz#vZ->2}2{k9%yg2w6QtHR$smuG0ccW zXuHFe@m^?`P3I04C7UNh927hC(7gC2(xLZFoCM*f-qgv85LL}mj519ifLp7lisk^&vI*T<~hFtS%1* z1J4F74{Q$1#p>tt{u})#`&;~zegD9!?fF=Xo$URG_a4{)bb2RZb^jjY5~I(UhajF0 zVcq<2&m{MY?rYuK+^gM{h=g}9cElg%8n3?q@BdwT2s_&^){elJ|9k4M)KT?dHK@Fz zT&HYN>YeX9Z*!jRT;nWsyo5^0-+}~MSgsm!R>{ z^zLB>)3DBmq^&U}#PXLcO3;WYy;F3;Yke<5GSFK=+K;2;*<{3Ymds1gI4a8%UeBna zIlQz4EXUtV>Jnm1JxILxQWG*g+1lDh0^+<=wje>{tLzc32R2mO3}!N_NFw4rUDlAG zVOIJ8A!jbM$*rpoPF{P`PKxQ}K?F4uu6*nYl*hfLbqN}ME4aR$_I&-5C8r#2Dp`=A;W^!6@?5fYdB5pg+Nv`yZYd((^`)~DG+5)o zLZ204zhF*PMJj23zqBSH2J7_RgfTi*_%tR)taN392J8joiwHABLw)E+v;Ntkf@QDf zQ$k+5OXntNTpugEfMm;E<3{QH;_3vA=)!@H)7h}@P>Pe3(>R%~=%w|Mg$WwQ#g&b( zP{bgT!IpAJHkn&5t*M%yps`$ZJ`*`8Q(hj6P~P0g;sg!l!b1wv%wSDTOxrV@u`D!mfZU$|DCR=s_UvIja^j zhFRVms1j0+49X%)6C03$a8hGs!12z;neC6U_1I*`QR zVwIVfL$w8^I5I2I1&X-CaR6$c0-xMgN;nL}e4r<0+ zBG3mW--p>0r8E>SPaFcxe6up8F3ifbLnvouFtH2cd~8#197HHeD=)k^Vpb+oYUmN? ztb)2k8`Xj)Z58M8T|0J)SLbYIT3|$+lS9iAt>DO+oV3V%qZpHGDp0{n;o`(vWFq~S zw+!@?PY=vr4cWr4aINh!P#ym$s86inI*S<{Q1jNActSv=7YgPlR)d5&a3VGA?8jW) z5N5BlYimh}_WOdxiB(oL(SfwzK5ub$8Bre#S0`FPH7B0(7bj~$gog@h5-UNlKEXx% zvnz-zMWh=M$F<(tL^Cs}QKn=}1`7GUcUocvC`B}5h<<3#2}zA4Hx#cJSC?plqP#NF zo=CDYPYc`;$9F2HCzgXFKltc6%vPr~XkJ`imuR$dAM=V$3&6Q3yd<#<968TMKJC)t z>|!#6;9eN6Ni={f`<8g*JtUiEri1bA!n(x4Rt+0W{}0)ev;drM70yl^1dcgjVPBas zPfj(Ryj{b-h~t9D+{A&h5?|@PIhT>B3v?6XrY7b?*P7O#lb>CU2wwK)C+0zKHqTPv zQlSgcjF)TG+McRL9A}m;O4NfknHPwfw-0XW5zB#Q3AU7K+kYc+qIW@}4$Mkkld{5K z%d%|B*qvj>$aY8ej$4qZwed_x3FhZ-1}`miNA}kjD%_vbEsOpWGPoH(sM56+F^BC z;ENoCCCk~Mm`j$!I9ak4X?5)3+|}cY^o8amWp~hiXF+cmRAq_-yc=;0>_1 zP6dZyW4!{_)pLT;pg-_g;4OImyEAZY;Nn0$a6BxhHw2mk3j&h^<1kn7h5t?ebN)yC zclv+s|Dpe4f69Lf?4q~$5A(0}AMCI5&-9P?2YmnaedK%H_l)l$-|evdzSuYFJJolb zZ!^3LG+`&gOkdO&@_ym{i}!i&W0+^S)q9oqTi&?$c<(XZBjMj~p|{Fg;?<1LjQ3z6 z|1=^H-emm1_zrCUPlMh6(MG$m(m2pqV9YV9;N{Qj`4?gnKJB?*srTFpKYy2aMm?u^ zj)R}SqdcviWuEz-sh(1g$New&JFr@K(0z;h`|k7Hr@4pRn_;WJ!oA2n6E^wqo9jF{g2wYuL33HuH_Hd9Eq05|>B+On*;*MSoPkQ@=sK9JUUp=!39^?}RP< zQoRm#@a1|?`$Bt9dqI0tyBih|*Jc7WK#KrRv%0sp@fRui6P)i3REmwG0*$UnuV(YT}d1{mLzvLAg|kE5phrt45WCt}C0lX-M^?%Jex z$(kU@>h3=Hk<&X(X-D5qy~AW;b5HL!{SfnT&EWCKsNGb>jH=#7&Nrx#=3!*pDy!4o zyhAWoo5w2#hmfL+u=k`*_0?CHTzVnbr%Zf5&ZtLt)Nlz;LE_0rQO8`X zIA1&n^`CR&#YDIICiy9W+R%vUr{nWzpPbW7VODn{!eSD~oOR=1V)3%5@AU75AH7_UAk6V~q9KGIM5 zJuc3G2;0iOqm;LDQZ~!_kPU|VN85qp_p&xE10&k+WS5ACz51N28+)EmAC-sv9;3XS zdALPVg>zu#{*0q0iaL%~;UPabgjR2mEifHms87gdTRvdar(_e-UNzJwWr6IlLVbw* zIw4c?%{H`GcGf%Myfk%5pHvRv2MLZ1g;OfWsK|kjmhEwzEh;Gw9Z8$8VUOcno3OzV z7o8+j9p98?;Pz>3Ti)b2gKh;>q+a{AxUKs}v`4sucZgwsk^Nwv{h)@My`u-dOnXJ= zxF&FB+qXEL;^xvUGVUwa8ouJ_kmhT(W4QSllg!#y?pRL5i=VbbuzGt2tqTWImREmu50zp& z9?Uw%&{C$b2T5m$Y5-j^Sha{Ua0%bSjNx7I?>5x4QxX2TFpGg>v6`)1PA%gE(NW5G zMV>-KxyttcGTVOmG4HgAB-!sY$FBhD4vAS^EQ_9-{m59V{Dc4E3*w05Z|u&KSNq01R$*$#LY#@QWq zP37wGF&x+oJFemCQHpZC?SDQ0-$srZ|3Me2`N5%8bNy)M3Trv0KjKQxxp!~x_CEHs z_Xbx|q-d|p0~9l)2xn#;eZAr)b{)>Sx10k6!BiTtkgG|MQ}*_W6fN} zn}cu;Mmf=uI>jziCfSdi7iS!aA%S@G5YV=nGCEQ##Ra}h7cS7!9)Q#bMB93f$4%a% z++#mz5KR*jlwZr7#KFN*3kS;Gw*SjS1$&Mcu2Phz zGmbhq0}<&0`HT2i? zZ{0RxuKz2q=1=aXOPumR5B6=v9rr?Z!l7o<_%X|`DzD^AJc>>@<;9w0Kt*O3&fl8- zkWRVD)Z|GzN+*9u%AdwaKisUmoYZ4yOv=molaDaVlU+QlH=2!-u7i~4vJ=+Rqeqw) z=s!#URbRq)+@bA5a92CDm);D8&(r@c|9>5h8y(n>e@>`1R1*9gUjMHP?hURC7Qw&& zj{~~{4FSLZkNzL{ci`*2*!Pa_H@1{jemt}Cw7-l*8dF;_&>&%@ge#Y__=>XyA-?E57Y|P z7u1{8i_~rEd{t2%R=%zDC^MWNIDhFp)p>|>yyGvZB>mc1EuqlG)s(WEt-O-WcseiQ<5nn z)~%(plQdggoc4%UpO1l8BGUd@>7pdf6=Q;r%AhK*8`zlZUL}5`sgv5r;e5o%#%Q*DPtS4WdKk6u{xfGARbv#o21!e z(eqfP7J)Zg^Asl~plm3qPtsJfXc|`%mVo&JV_JH`IZvLYrZK-nofo>DqS;X;A_iOd-YmFk2)@{SdbKR$Lz7h63YUu1O&u&u?%i$spJ%)M0+B0k~BqJ#yeZugzxw zcqApn2QY0`!~re$;ha)3@?53ONmgd5cce>~u?1MY1L`eMpOmG(F2DLZsIP?j#4L4l zn8~V4E7Y5{8OaGypE%d5yKQwc%|J7o3hI*;P=(VtF{re6n~w0)wV_+C8s6+pfgW9^ zRwtvBKVOuPae#yz3McE)gVoyPco5)ZPL|The)Dq}GF^`z2ugVdMTR!Wp~!SSx>T)C zmSwcX49<|lF$H>bKae6hq(*Bu6<_Pr0YoB!9$kXUm1a~qQ^>V< zK8kSp9bJHKE(XQwX8!!nVQ{h@orkuJ%WR7bFOfs(k^((iug*#qfh4SiaiMbzgB$`k zybi4>%xHy-Zjqxe)AeW#@(*X^Poli~dbC=dmMnm>Fm4u=S<{rGx~55w&VgbmQ!zKs zHC=jiHWY&yicN>)8LDu(pQB1{_@fh{s%5AmCQ6Pf z()8#AsHz#N2)U7?iZnf1fy+>Vs&$!DXp|gXO4Os{aU(gQY>kR$Oq3jgDbS;3AUQHf z7@0&Ml^l{O(4(c;v3P1WNkjn1M-l=(S_0B3*(4GFBp*o#^k^|iCufj2XiAJ2*Q*<7Zh>%}jkNVYFiQQ1Qt}}|5 zlcP2x44 zSnxW#OAbg3fhXhoWkv-XgKN%O6MrLY&yNFN+Me4Yh~*{I>M2EH2eT9Q(L1dg!=k;T z@3>w4L*~o4Rbxv;yagp>|KIL-+!1;`bSFIUtqhe0KMdX%yeK#rT!tM0Zw7u5NCu7! z%*Lwz6aFjwTm8$hcK-ra><4@`-hYYj|Bc>h#z)32#u-?1FZR6PxzKY2zWrZwU+o^i z%DESw?0)Dv)-@mT?;h8$(2vpU-~sNB+U@XNcPJv+xzsDr1suVpvi)V|1y4H4^kHW6Coz--x zD-$B>j1)aF$MZWsQf;qfQct{+C=*K6IVpN#PGq<1q$*-GnVrg+%15y>p+udMqNipl zzZ^q7Jp#&n@qVF9D25t6F>Pw*W7t&dg4#HBT1q@E`CA9MSc#Zim(;_nmomYR zmo$0`TKQS;M^cYoj+6;LJn-qsXI&QP3v+apnv?=nuR0}3&pWH=X7h7UDmLR|5KDEn zN%4f^Sp=LwJkdoMoy_aUOa;Y*R|$H)Rq&T9D0%cn5|rI)G)d33qDpzSn>OF5ghpRhmFqH?V1N*T80J(URWdBj#tSGlYg-uFMH7Oww};+dGMj z5KTf6(VeUtlBqTk5tVR#lAd5NVk071e_;7;#2lE+8KLU503_!}_*@oGGU`SOD^5#W z*#&VbslQP$BS{Z681{1xa|P>FITX8$N_iqQ zKS@tHSg6TTWH7WmWl0IqeuJJ94>#F!B8HlX9+sacL`1wkRGXw{oAf3iOy;phkj*mF ziE;%fgEk6W|H2D&_DpPbqf95tMWI>A0Z?EuNUb7u%*FQOywK)CKBXd&dhe{N`Nn|*=?4`oPHsUaww(*+S;^tU2Fa8Wb#Xy$vJX^w z!I@#$vT0^IQ6`2LCpTNAVVyX=rkqW)%ZM5(s805RDmNfV@fa*3xC-`5ZURAG4vjs% z+xo~#7t7i<6KB3+GlX>IYGw7w9+2fQl$K|gmlhC7jnpQO21#~^*;m;dGaZ$5yzi|| zc3TuPGFmppOjkg8uedsS6ezMIAfm`>c^H&Tgm;VgOCAY=>mJe@s^dV8FznJMndA+DUxd9Z}CF!bX7n2qc z>9wM&;XsU=*~)83>6LK{lIy54yeFb@aOd6?LxVfAb%hN^wJ9~q9nTfaO?H7- z%w9xjFKT`cN!;ZK#x*78CxxZ%{OS-u`x$6=SlW4>;anjIp#5~XCV2?7OW9>d z-r=70g$Rs4gk~n&iLnUNvx-v)^VSDF^c3pS23@%)1Ew^16lW`QD*EMzq1nk+OFP>K zfP7jB&j7x1$N9l&$+ggyPPy{+BBdGSdqQ=|HBb~60DOb>55QyvP8YK4krv=i--PGp zYO^XL&{UphGg*fWpn&$!l;kQXi`^SSIXi1;8s*K%v&G62&lQ+OWNUJ&QNFZbR&r&A za-Ir6SyW(7!IWgPRRJXD$<`>3U`$>CHQaABvu+M-*}7)BQ6BOhm}~+8pLs;cj%S)p z%$B>$1Grt6BLj3jWsr8ikj+dB+~xkFDal5vB)d>EE0e`2_l3%n%b=F;UAWxsT-TXw@%3p;q{~G-h{Q>=(dW#;`p4YC1 zrTYT-qkmXEAGYjsmCq5A{(R+dWhTD&?{dbS$6)vWRL2*NXBR0I%l}t&|P-=ejY#T}kSD|8I(nBFtDubot zQ#5=QRZ{Jo5Xn=4e@dl4Ql6r5GT&*abo=I|Xnd5e18}vo{knB7kwiufX^Ekish5=0 zq-b;$JHTm=(-4`t=j9-s7^#v)DHFg8@s?r4k$!sq*^1O;v(pE|r zq-Z!b9UV};u!*48_SGjTqRK)9p7I&$MkA}N8*^Y&kyE#{gjg?uMFXwXqC<8Kj`VHL zVWEC3A=dq76Gz^|cF$+kl>3 z3a;!~Szy;7#YwciUCBEtQ%w8?xIgv>U)~=GbOqZxgi6jSI4vR846ydIvCN3kxhzvc ztTME7iPcWg^~-v;_YCyr*3>Q}u7YuWF}UWqE;g75rJOQ(JBpBj>G-s?F|`Ox;qgL5 zf9u`0Y^bm2Sc*D}u*5lhF50F+xx9oCVIgvn=T_+KgDynGd#JQ7wE#Rh3bza&y1ajD zzwMn&o*7d>oa?}uZ*fFkxMFfDY6^&RPRT*3c~rlRcyo}g%$Y?O4_HxkA)PYM(6|i>TIK1TFBvy!X>F%t8^*L zX>u+d+|$P`O4Wc{c8I8Xr`Tq-FDh$*`3;m>ZIz02+O72!R8j%=w8GldTyTrXZ6x0G zhtl5EXsIK+t08umojPuQY7Qu+Ir;PrDjm|_{$*QYl)o% zxx4K6(1O%-a3(j2`q|_;6|~9pvRy`PY8rUbeG0m)8&eed-_l5cTVr!cZE9*Jg|;H* zltX!u0F?EhOv$9sK7+gz5`Y5h%+zGjAbK-~U)yv5@*I{;2I7Gw2d1h(lwNEaG471? zrN4o4$XRk^P+vMXRf!DnW=MURW8Nt*E7Q2MEK*#bngo3@;)^do*2pO;eMzE_B5!SK zB1mSx%T0?poK7il>t*4pS*Z!2NVhdB)-*Kdz7>j8MK3Fe%t}>Q%4@otI?Y9wbTz6) zDwIR$vM7{oj(;$f*4WVAwXUNnw+!;0WRoLO~{ z<}IC`ihyCc=gEJ%lrj&#ze=H*@B6Dv@ztkFARN!evg_6?@7uI%t1MTn8CT0R6AgW0 zp?7|&m}*PwNc7F$kP#}GR-H}lYEuYW0S2FOOcRY9+$wf$g4npXj7@R&cRRmU% zoRLTe!py842=0l2=`&J=)S3mtxxzkLGtnpf|Ft-7aD<)?T@uaU`bw}b|4Q#k-Zt-e<9*{d#yN5$u=$6{5>6ayc;raIU^VpQ!ys`-z6_$?AWwv;88qTdh()Q0`Qc zN~==pe8qVqy#K9rMjfxCN;$vzqcrZwb*J^+Yx;%})Y=}pkssWa#L%m>l7fY!V(j5{ zC-R@rHiSJ^U8Yf&xFBh%-zFlWx1f5I#vVBzy*|H(X_*Xy`tO4JQ5tLH{3&I(3{E-n zmLmj2`k-LWC=EE6_@hZeBIRdv!K}MV{S(w_sFCVe?yOH6JEj}Lsigi$c>X92GwD7v zojcj@DQf%rZc{?Edkf}|(tu;5@t&Z3G?ozU#)8G8H1xLZ6P8hH6Zran=i*@AO=1Boa2NWzCrO~N~-o>5RJ)7|;qmra<)4=Zjp}_&F zO*OQ9Rg1!lM#FZdX}_300eP9rd{y<~1)~LEhBwGEvn!aFXjIJwFJ$9=tpZWr4Df{DOQ68zet0ooA8}(Tw zng)3L>e1Eis)=R$k9xr>JyMj28?D#2^vL&Jp1KM>ch!XA#!&<8xHjb!LlaJMQyW6tcsMDkGi0i?`@%~ z$X7e6LkMF>vE&6aJp22?x`E9Yp{mI`Pb3@qBxfrgLK-Mj8`2chd5SFB#xf;D+#f@# z3Ze*HPi6@{n=zaXBPwy)bi~F?i-@Y?`K5pg6HBw2Hs9VEEbPtECpkVwC7qd-H1|X1 zR??IZ@#S$#M;#!}W{Vp3>M}esw9EcNWGfK6!%QL3pD(RXoeDaPRLzRgdUl`r6=Gv@ zI*}eJs85}eNy>Oc*+}LCYLerD!uhF_L4pOcS(4m`ncF}qpt9~pStn(dh1X0>vgEQj zok+jJcj<{B*{%}$8Zu{8Z1oe#M7gc7I&}glwlik?vdUr*;l_eFsl6b;EY@s~wfJSz zr?oGr-w>LW+5>eMVEcpZ7ew#-JPRjVO!PjbY<^HW1q>JmJm%zjEMR8lY|Ey5JXb}+~D zvu7N?*XZP#sWcU?{j6faC|rDjmHl>ZOSn1q$! z)D{r)J=7){zJ;ki2xqeCL>IQ2Z`jrklR#`oHeV;iYG;PPsC2v%sZMPMvC@o(FeDvT z$&MfrZUdPJ!Yz@SR4)jV$&Dhp!y7s@FT+eVDo=^jrZzEyI*TqA=?BABhAkC~vB#Co zO7(yutw~8p4mYy&DGADbP(IpHHfNh{%4QOjHwQp+=S*K;Fn~5Ma zVZ!<-5T^3JzLtUAJ=^;;3@fOM?8!#ufmjSU5}dj0QxV>7#c~RsWKDQKPd`Iw(K}0o zdX>yf9l@=k{xubB)iaZf%IXqt;2P(5)r%beE78zz{QnaVeXMx!`J%wX`@kY!ExZI) z`NsRk`2s$d_rLBxxF2;t;QqDy7w(_CuXq2zeX0A~?z7!7_o?nZ?&I9YxO?44z$&5D z-RwTty~JJbp6#9juYM)&klW*Sy8h+*#Py!*P1noVukfVnVZmFpJQPh8i)Z^0$5 z^Ia*|8LpEsmoebl>N?uB5nlgRyOz5Sa4mGzxMsL2UFEJKm*1u9U+SOgAL@VAU(;XI zpVlAKAJl)N->%=N|46?||DJxKevTg3Pt*76L;A7$X7~nNueZTFV1vG&K2M(m4}lZ( zQoTSobVd6&_DTFrdrSMX_MG+<{3P6`-KpKG{ZzYFyHfj(b^-QJoT;6x?S}V+ZCVc^ zDRydWv?h2`SftfzGqoyhyf#h?V1LDb)z9Ed@E!Ga^(FNg^>Otf^=?F5ya_%9f2dxj zUKIK~^l|9j&>NvYg`N#P0Y4D;gzgC4jA)Qohb|9Y96ArXLQW5z7#a!f2yF>2|NuDxKp~vUZ++Vo=>Hfg|w)<803&FR8uLfTT{xkT2 zO9bYuaEZX26)q8&v%)0;b5>x^3*j~^aCrz2fjKK&A~0tKyhVyc5ty^WRmVpnFlPm> zCe`8K6cK;5!X@IbR^Vb2BoTkL!X@IbR=7kE(F&IcB3j`RK}0KDB8X@Ou1!G@K}0M5 zZ`GCBSj`2^WthV-n_(8iOokZ@(;22QOl6qDFqxr>p^{+|!$gJ&3>6GfhVcyL3}p-v zhEj$ShGK?s3`Gou3}J=>h7d!LA;92g@G*E93F&{F&iphCea9#PA}+3k=UQJjd`yhG!X`VR)M14-CI& zc#7dkh9?*vXLyX^QHI|!Ji_oW!*3ZLVtA0@0fze-?qj%@;U0#&8Ggg?YlgcR?qv8C z!yOF2WVoH-7Yw&C+{$nZ!_5pgG2F=TbB3QW{FLD*3^y?Rn4n7k5ySNi*D+kna1F!N z3_oPJis1(g-)Fdz;R=S!87^b^9>b*!-(~m?!zBzCGhD=QA;Y&BzQu3>!}$#7F`UbA z4#U|DXEBU2q!^M635GaBj9`-fO@=cW&R{s5;TsI6F`UY93d6|^Co!DJa00_#hCK|& zGwf#A#W2D!%rL}o9K%kAL52Z_9SqwUj%7H8p`T$J!&ZhZ1eJOp!)AtFhD{7T3`a9` zGaSWmB*PI5hcg_;u#w?Vh7Ans3I5-TCQmJjYU1XKYU1XKYU1XKYU1XKYU1XKYU1XK zYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XK zYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XK zYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XK zYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XKYU1XK zYU1XKYU1XKYU1XKYU1XKYU1V^uiZoEZ@hLl!*3XV&2SgPoeaNXxP#%B47W4e`olF;bVr67(Qh9fZ=_HzcIYW@GiqU41Z;Ko8d1E zZ#f*!`Q_T1eDnsx>kO|kyvpzj!=D*mX804sOAIeEyuk20!*dLOWO$b08HT4B{=o2i zhNl>wWO#z%afZhj9%c9)!y^n2GyIm}A%+JT9$>hi;Xa0Y3Ci?!3|$PJ3>^%IFtjtY zF|-m)fy+4ogA4-%Q(Ze4wi8sqLS4Wy4E+q-7`8Hqk+#Cs$48qPdKoq`^e`OF(9LiZ z!;uU}FdWWs7{f+}Lm4(OtY;97u5gJ)SGYu@EAZhdsw)~@;S!CmaEV4&xJ08XTx(fn z4Z~`NRSYc*D;b)}{(rsWw-o>HyijLoQt+?v_-Zd%&GV}s6*K2F$D&|KsehzvXqP!91EWn5 zaMVn8S2)fK&L5?j^T~2&k#MnYx8^oEym%lapq&$*GD=8ULKi$Z2ruOESOs%XwAO`6Ne>6Xo=(RQ{rBv4O=W{lFbd5A1Q;4?6{ z0wU`!s3t;lMrrn3L`tVPteZ)cpWv^+wD+`8nk7e=a?07}`pv2d{JvE<&J0c)rTKBG zxEkiuS(#E26i+XlJW4a-<7bK}pfa0G-3rHPp_!vJ^F5wJuD7WVLdX=DI}?Ow6069saN$?Psqz2|6^REp;qUKW1KCdc}$A)KQwbE~OKR)x(z7 zb*60;Yl#%S;skZ#D9uxsP8E7WX0Mr6u_riZlxC!*CzIB;Wi7VqV{Y%=Aq6Xtiazt;Jd_TWZZ{ zwFR~rjkd97G-J(ZBwG!lr~A%KTRq+FUL=jY(RO(6!E{Ji5=>s$9^eol#DRbzCgi~3 z+so{utDJM^99w;>>aY6mU(2of>;J!BKt);L zCPXm-HxWrgLZsal5;8F#L^;BIh@3|u(&~yrCfM8;8wRJNj!iSZx`5ynGg424KHD+-zT4x$j@J48k?e$S$iz^~z1 zmhSaMlA&Ew_oB=?t{@&h-c#tw0Pb28!%Snd5(;7?t2y$r)zPVYKqT-QDF+DK^+}M? z967W4rl~U^U?I)vre4-sLlYTZeaqBos+()|hb`E3f-ovlwaB1%>(nqxU&E*TaJPvJ zXOyKhEppP^IdzIy;5LE7ClB}bcXu5$hM`g1$j~BpV{#9HhOJL-_pk{$W|StxvB-dT z$J8LoMYv{un4wD;hKfd6k*r1fz1yZvqWl`V>Oj3J`jSzaBQHfxpzPgBS>jqka~Wk> zq891%?wlGx*>&8wZ}>$23HCNtDMyWTEz%45^@Bpn@A!#R(#*`LoYJ(&aSWytD7lO; zCd1Og!z`vn?gFoU3a>{HaYL>IMmd(KMS9S3uhR0+$x}5&DNTzULoXahN!bf0dTQPu zNm}G6YP?ISak#%nE_g=cl%_?FcyFBQLCLk-nEXYqRZ70dp-}JCF_h}mSt(`{L8b`V zJbo7QS!q;Wn*rBjVVPi*ZI0a0^5UtZsBQzl>BD}2Eaeb6E({OA}C9|hcgJwoIqq3Yyj^Bk?^#o z4oMWvWze88G6Ip#aL3dgCdrXhzEC`xElOZqgT%-PL^{H|rfxS`V>!L?5yPXwO2cvj zk)7e_)QdqR+>Rx@w~&@WBGUtr=!#8KFCqf&0xU~Z5k$6!cT62XF<}G`n?c18hzxnS z#g<5Kj%-=eIdvP#!w8<_YLpQ58qZPVS99csmfcggf(9-?jD}>y0xi@M8CikI^`XsE z`$4sWe+TZ$NjDLr<|xtvk+q@SQ~S)?X{Zgw^J9klwprZF3Pi38-8i)uRLf{X>vkIv z76Xx5^ zV>M-u1tKdqZky^v8Mp)xx4rr$!*<5xf~5u`%iFh2b(m#U8#c2nOASPpt=KlT(=5xN z-(OSuF%gy z_lJgB-{1P?&^KHE5E1)wp1ds3p^K z4tKsUY3XR$+;Uw@5cjk{Z2o%lKQw=``Gd{xYJMa92q=1AqInodf(H=0?}p~~W>3@4 zn!eNYk4?|u=JtKKwf#ff*cO_SO+!tGnszsB#Qm%%@Tw_f!_-h z13K>d596MHXJB(+RY3Fq!v9_W3;t*QANN0r8~xY$Um1FvKOcJ1KkC01H>@50E&jFs zcHH0pyY@rv8`_t&PiudRTl;ruZ_<8WD{Cb!g}eH@wZqzN+74}lwn}S89KWCVz70f! z=X{?Cf86(%p`)Si`QCwh`A2;haU*|^?=IZM@A9qpg`nB^32xtC@P5JjtoQG{f8~9L z_qE|?ypM)|?9F@Ddq=#z-aEXvgum)t>kWE-?fI$ayPmIlJ`Y@kkA|M}yf3`P^VaZx z4<8SAg&zt1HryI6dRF3QUJrMMUI@QFd=Kv5-|hJ$&#ObP^^`p&&wbFC3;{p!c28$W zPwDC8aZi-uNZdoeJ?}Js?x3G%`Y4Fb`^}&G5MYI3tPJzL=|50-3S~TL@1jgr*Kv>f zd#-JGPUm4=ly`lD;vB*3PAd=(r;qjY9(J#wkV~h><3+EJLXL=-X}m~hI)G4%Sj%mGT4`=S$wOlO!@sv z<@YO;-v^c7yOrN8_93s|yVgwi{8IT1fJTU%y|qW--?Lmv_nW`nKT>`_tNc!wzg_>K z{C}Lwr@Q168}$#+Xrx-0cb)q^Gz94} z$wQXjQuVxz)+5UI{2$|2553Y5XX@Roe6gp%BQJVCBA~Y4ljnPuCl+y2*5bZR&2#UyJat;0ShP}u?xt361ibOq$J7TFt8gf5 z#Nj%}YssRO|LXZS%M*((HTb)Jkyin zMbGOQ8qDtP)<^bbU=x7luBRoM&xeEN&vm?SF(Y-v=sM&1LDlnpyiSqt`JwgkJb#q2 zuYPQO%&;lNJQ}sPGD!f;^*>nKEPMzH^~bS*wE!;*D4m0vNBkzOub&N06K>Y`8#d4h z{!=27@rNVCZ zcH_DXc;pWclMf)!3tewvY~ztUGQAHmrtrkV*0|ovdJ$of zcz`M2-?GAZrqEW{-O}=iCmt)x_q5EVuu{H{$tQ}$p%JK+MKEBrBnQvHpPqET* z?$+#nFI(Ic^lh!3iHE0XVS3%c$xIPADHI>o{c`FO5r*~?;SahmDaPX(K3z@_>MIb0 znm+bi`Emr?GyP&Vf8NhRT=EUV8Go8}TWNGObxBV`d+29-v3uAO=f9Ua7;t1r&-+i& zUVx3!aXrJ-3jTvMGU0iU)@jK5UqoZ?6uBKC_+2*d-%Z)rf9Rv6fb(x>!%2*4|Fu*% zRC%<;)P76zX}GAtWFzbu(tb{(gI(WgKcKaR77n&$HSR~W7Z^Fe6w&^PJ%~^{UnXL9 zNum8;V#vIO(7r?yj&2w<7JyRTA!uKqp~`Ovw9gaMruP1MRvS~#e~vMET>C65%~kBr zv23P8f0k8FTJq1ZM5YFR2DjfqrrXh;Br+~`?Y;bXB2^7gifHfQNs5j^`!mMAp;pkI zp!@$m*B4#k=fZy)zJOEa23R(KF7!^|{~r!r*Y=aPkF`DCmT9}QZDs4XTR+_TQ0t-A zNbtwOr-H8t_6M)WDgUoq9&0(%vbp)YIKw~O+}#{%`lqJHo8nD32fiQpaNx1PKwy>s zoBlud7h$X1s(o2|LMv!dpa6WpSN09~wt9czecJn|x8Hlc=bt?v_xu5(*YEcD+@E&; zsXOJ~=hnd5od2Q~QrHVGI;juiVv6ES0oXu8bJ?s#eC_Sg3RBT@M@b@3u=y1NN(F)U zx9uGjrkIxwpow^zI>g!p(|%Gik$eXvq>eYd0YO3y)ghr|B6*?x<_f9dg|}YMXl)Zb zjS7FN{niSp+=ZX0WlmY!uw)VGW8v);Qn?E!Lg2O4HY5_M`2FqME2MNci_@0c+6IbK zA{8ITTadb4yajTw8L26aG%9>M>Lx|IS@*$gQu^x2j>zUIk&55YzNJD+b{4{ntUhv` z)|x4W3a$+As*qw`c$fmYPy`;f7B|yDH1wT))@pk7(P?Wj@~M(j;f@Na?!_1}nrgrSk=(I7S|JU->@T|ZfK^Ei z1xqD@oy&GrNR2N&s&#}fS9STKBYKT=B3cH?l0IJ$9mW31dXD~TJr zTFR+ndZf(D*vIZn9 z45?_(Dh$Q~)xHZ~fNN1yEN-+tsjXb562VOviPwNYj6}9X9f9`P0A&^oDH%kz8ttq$ z+v$s^GPN5pnMwprcvw2lrP&6d%GFZHRJ7sx7re^~^Ihm# zo+>OE)+JK7W(JXc9joDTkcrh0=)COywg|0`Rmy4(5&q-Kn=8veD0XAKb}I=_qr%Sz zH&xnE7{+QeXrN)YmPA4T#Xh@gUnQ(C11;qRoh@%w>k;9j$s8hlZtcEG$Rr%lF&;Bx zbyjCJhX|ityS>r|La|Nc_8Ya0(Yi*(KXcvoN~>ACyOgi(6p={9pSk9yN)W}x*j4Z0 zMQ`v+cohBgitUvavt}U8;J_&DNJU|hh;0bqPPbN?dCg>C%L-UU%95HRuBWftP-#L* zfsMhdvJ{QDK8htSfHKSu0o`+K5CG_@F^P&{JV%XRsQ7~|TPl7KF@p=XWfrv>g#f>l zgX!*Ht+=V8p&+~62e0PszFCsr?z^5`wYB0SM(BEf8b%_n_k(4x$uf5R7TX&(Xqct8 zkpoWN8@{RHF*)f?W#k|?%TpqXz9+n?;zm(s@Byaf@yaYn1|P0J$Li!VYg7(6cuLC zB3o1`o+7Td!y4#8lw#J2SVOHrGtf({PMM6peLc*S9w1)1WjI;8ABm?8Fepi3q=S>! zhUomiE$}TDJip%t5AOrO|9?L8#!xbJOWTjzo`&^*qHPai|9!Ic_ghC=_qO_i|2tTL z?SHi8EAZ+rwe$i3@H_C_eh}W-Elpo)dZOun;BI~otpC3?=VQA=;7GucfFl7%0*(Y6 z2`r)n)>U#XE_Wot>`J{SO6hcbB(2MTgPZ)?EtM=vY~yzIUP1v)C2&?IGoga@DY!|~ zc2qJbeakJpzN)*Rs>k3apSGbgfo;heasqR^87{xj)1Ha)r_J8wYb$A#S-TdIdz*zV ziijS4rfqX@d*wXka+o^;R>x+>vK?k<>qx}8CGZD0A>W7M^6ZbZ6TgYKQqWaL=A`9c)bo1Sy@SMPfT1``CI*9x~$5}QBBB{#7twdLTtm>3S z2PsM=f~TM)PJlotiEB0YLT&GVE42J0C@8uUhnrfJuSleNFXN@-C@x+as)+(akIYsn zK$Q$48*U${yc}eAo@J+3VUe)wNIDC&uFTj#HkBzV0DJt1g<-@D8)}PDl}B+BIfp96 z$?yp2v8{q;K+E(MMjnW@U!kMVf>?Ak97yVLDpQHzYq-)O-!q{^;1|1A4tW|C{u0hwbYUFn&q{h^47}>b~tiA@ZWD)6yFtEr8 zO$;nJiS(7y#nef|t3ZqiC4|pIo${Su|?w`#Ko1zJckHdFctbiXsmOYv9yj;u9Z(7mj=lo@%;vE zoiN)n^2~r%qAfLt2*0snPo)opqD%YY`SW#`aV3MuUI2@|3X6I?pBS%YQ6>|~^H{x) znD6srX(@$ZTmsn7u)`(?d@%^YRk2qfmOiPw$|34w|>3#?_2+}^-Zm>Y%R22AADc%V9RS^ z50Gy9Ueha@S^|F&*yDc=cJ|HM8?+U^5Bs`+KX(@1{oU~DKZB+h;jbLVJ+RyDdUP3( zGCZ5Q55%Al9fNtw`XjI;Da4Z5Vn#2D|>O_435f^SB#@W`e+;r z7&+=mE)uxFCMIrMBqm5mU8Q1{zpH%JFz&n;LHPTlyP~&tbnICS;p0ku5rjVnj_L^? z*Yk@Ye1nO)!hZx8`P9h$bL!z#|KN-RUX+<>pch~mKn&coWDL|1?O7NZP@~%x*l2x` z!XRM*A~pJ}b`6=WNMYcx0FlmufqEi^fy4qtYBX9`q&mzdsPfzA)L&hhWImfp(nyV- z#+`ZgVj;GBceEpV+um6HW?)#cNX_g)GkbT{Z|34o-b{Sjw<%z)ycMR{EV-;xuD zhuHM19U&rzCLKN|r(s)(^GZ@K=VxKmF>@cO4V&LO)Z7iPb&}=5QYM+!lf!zxfa_mb zc@f4RRQcJZd#gIbZVc8V)N0q#wJJWyE*PCqONII^8IoE*oGQR~bp2qlluTt~=)PUF zn;3=PB%~Ej$GWo<6WPrESkIxu;`iZ8MIGJ`kfph~h@B|G7J~m@d?+u&f`vF3TPO#8 zg9l5gbh4(g&i&C2GZ8oh;6Q$)x4;SpjX!$lVl|E{(>#tFF|qGa+T{Y`4U6o9`X~mU zQik)!X?dn(Gz!}rVzmG2V3eH+2h#B(USNWvI>tv*Y1mEZa^8%?;D>s(yFR~S>#0sk z%t2+KMCEFLs7 zPvvpiQ23hlEO|3a9*U14MBsQfNwus~Y7vJr)N+GTOMi|ufdv#^6Jg2NRDdy9H!ycC z3cH;stiGOQ-Dt_8hS#!m-Y`g@P!t5$Sqa!_j|kRS2?ox?5tFrWt(Bm^z|*g}#!A3_ zf>6`7t69cY$r4m0~S;7!>-MOlF7IZ9ZQ!~bpGGq8g+%A2;UX@ zW+>72{kD*(XGceD!Z@x&1W~M`(TR8>TZnb; zk>^FZP3jZ0QL(S`Jpg?wHJe(jX5n+qv;{GIX~ki+VdDj8WU2A#4@P*OS-o?L-gxFl zOVH#lo}dxxnl|9E-C{S~@LeaN52j}InFPIfJ7U?#m!MsyrV~rkwAiv5A7$lpdWYL^u(-)x2r>4&>jp*ss`F2=*R%E-UaWz2g;^RGy zf)lIBOfw8E(5cpt<#}8pP{ln9typlX?(uQV73X%jxo^hp16q4jTVQLlUf95$FJ^Of zREF{-Ef^35qo)UsNM5|S&Y(A+UPC*xNE`7o2(_|4A#xZe2tbO! zL`09IaT7$19$(YnfG z4Q5OE1a{mRtW>GuNGWk1+p?pnVr;~!lZZAdC^>1y%@%Po@3lZ_pzAVh=HdR9EzHD< zwWQ!>61Qg53-kVJXZm^^z@wcVo%L@8?uDB(wSz|L z`0qp%yOqAjfy$Qf{Iw_Oegn|>F{&5vcL@#)B(w&nH$yQwqf%a~#HCgm4!*JYL~`FA zWj}f*K9M%|z2$2!v!)+yAk(=wZBWGc4T88pxWKgXqz__yzd}mY{i?|ZYo$pplm?5V z(axd>g;q4NP;I%yCDLG~%)ecOQtFrG@~P_om5w^07f-O5n&KEJE(ipbue|*tXSBf< z&1i1U0x~FP&nQY_=TU;s=Y-yX-7Occ61jHga?#;#=tK*hyE>prynu5^T$vKhCC+Gr z9ho7WIm@-)Y!v$eF=54Jq%j9B7a1#ycULyu!ccYAF0UwXIjpI_+|FGN28DHLfWk69 zrYrY&ut;JlQJmu7$~Qz~${6*_^PH;&Cq<);S@(`XF%wtf1W}KvW%qNYRxOsO)P6dd zEu<$i%EBPULvt=_9XY0Utn4OpcYIVzSDq)Mvs`3Q4;~hL+g$I%RwEbDK};+L3(aJu z-}roG^!}{Ji`q5S-&V;1zZ9;X&1DZf07x7cm!eCmd6A=}>a%ef9tOn2*p=Wx$U}C< zMffjJ+wuBsFZ7ttZqxfmVaJ=%yW@#*bJduHCj>P-@00EHC!WLE^pI6stjt3f94e^o z26JGcFD*X0JxN$0q()PEzE)9P_Q5@aSa@J2xzFknCSJ&;V8uY&>5d&axJ0M)i_y;L zuHAe0;%X+=@Oq@|gQLgduyIkC1VwR8pN$rwwn~fx${aWP}37}9{rYa*Y@!3<}1l5oMbWl33>Sqfe_%Mc4Qs-Nd2g@mxqp|LvMkZ6S` z4!C$UxZnw5^hMRkoPm?m@j}Yn;{@R8L+s3`ot(W;=Eja(u#4~=qTZR&8g52LaDfml zUYOnWZ4T~5)au}ZdxKh?h?i1qGVX7@CeZo+de;-K@Lz=2g+3bE()PBtKG8%GrSg!k*-$2|Y(d7WpS`>pORAiN@f50$Usf>|mZ5~O7@ zP9&ANo;1egh4O0N{!;1As@s>t@S*amC3|tYiNNvW5YX@dsF_JjLfw^3mk1Kbc=23$ zSFg`cDrk2OsRhVuofjc7g0Mc6aRVyiF-GsOK-F5;~#%Do1)(xt&+uU=y~ur+~UV zoG*tt3k|NA=gtBYdGS0HeBxhbAZ~Q&igJiG_voUX-sQQ+V6?t=i1n($Q`M+0Ut4bD zY%R6E@w7g|LL)@G_-@tYx+=#QfaROZt(>=`as=X9RB@j&s+jXp(V(18WM-ji4!M5N zI$g>)l!Khxo%VApG=5bat}nN64tLwkp=xDa#p9-OGw1O|cJo-J?5*PS=5o{3F*c!; zuA}R%;&xp*z`5;QEU6lkLs{zSOwKPj>voV#ZVd0YQ$uC zv6wWvDkhAI4(3zIG1ZI1l3umM`^qWA-RoPV*{?ZL}AG05E_2mxyTf`E%pwn8Df`=#+XY?IMfFTMjyT&{a9j zR^bcZolfz67hfkXmASWcBfGSPc3b}lG_86O7R$o5#+)#jGWUO8DvR)LVBZvu;+{XmSzX=$OemKvmqOOxGa2`v$O8Ls^gnj_!=xvctJgn@4jIiDlN1m1DDIf zxw(Ngz(RXiGH^7V9f_wolA`hUm&=>@MsA542MAZK2UDqhBX4|(mLzT^r00d`jh8Mr zl{fOebb}N9LPdTkRUlkTcv@$Y@qE%ym)H9=G?zDUUK*IX&CH8p=RHq12ssqX!SZ^} zOoKzloS3otH`Hv@6t=A;jedHdypE5L)O@F=(#EWvA*3)KDBrNCtI%N~7hOQ8r74_7F6&%8v{OLPV{$IcPq4j%(gW8oo(wEZn4dtUk9Y~A^^4`T zy!Cn8DskQ8?0qw&^o!-|c*`?hy3c=~th~2uHdkK5n_a@~dDVS#*$C>0Y?Ik1RM!C5^yBoNWhVR zBY~?*0^?;4Iz9*3P13k<8;csPm}yXD7BUnfqh*06-oP)qj!wv|Wp+*RTZjA00x|s5 z+>`>`%1_n0(DjUHxqhbca_H1MW3jwG8k0zY%H^VPVguG-Y~#l5Z7u8Zw{a&5b3CvE zv5i35uY%f_So;EOU#U&px7LA->`LV7y@|5RDv1a5$2)YeAvVSFg|wg zic)|cC=oB=h5l?0`HCBQp2d0u;9FVDwO>M(s#tyO5dLga( zZEK&H7}OEzQ^wY?PZYMuAQd0WWDCVqg6)2ac?t<(j|db_IBvh)@;GF0#IN&h7Yjw1 z6PPy)E!u7Y!F@Ay9zelJjmC#RZB%o^u-a7*RBC@B0d2xX#ac@J6|b=EmDmoD1O&wAKsJ@J z@3SyS*ljlU0&psU7y<|JBn}yM06nGSXAWKm6Vw>iM!i>$bI1IyOTLz^f z0>(p6uRvz8%b=*5q2AQkc=4i6|F=UxIR76cYkWCqZNB7CIO)@iaX|OQ?U0Hp5u3NX zibTjB&-VT)u<*YHNQibHHg%541pmb&KH1F;H!ZP8Bq9JI-4H^5oEN+FLiALo5FfQi zuPra~Yk1<0J>9kn%9ih;=p?)6uwdgDaI);WYLH{22d*voY|a?2c6LiOFL%W+#0Oba zDO*QsHCsY-cB`V49z-Y(_~_Yl=#XsmX6^eNiTQNG&cm0K17;HQgR#$IzCI`1unCjh z-eF=Dk8QgB`ZBV6rzysx9_qo`PH$6&#oL@bgqn?gM-vlPJ+d7u5OHw^F>`S-W0R>S<6t6vHSi$2!=}#> zlf*#0IBv_w&}`kN@gSB#f*Y$AKvEwmjoo76tFq?k1SYu$6|Hqc=((H zK;+EF^OI(M7vuR1-ZG!h<`tGo#nD^QOs-TkOC}KkFF%pW0EQ)%Py~>UXU1^!DZoVU zKxb#P!=#XrKNE;InHrn+9c2KvWZxhU?wd@(C>1`*AdKqlf!ETo_G!^=DKd`{g(${i z(^;WzqezRzB*TT6fa8tvMnz5`RY>a>^z^y?=aTwpyp%3R$5_BPQA$DGl{HQOt)3-Y zBJ@!#7L8hXG~+{A0=fzuV3_}R$q2C3gV;{?7S2}=5Jl)B^Yt5I70dT5?BuY|I}?SS zCYi9+h$^NdcMbAr?P5G;YYqdl#_2nDu{rGJ)Ap+5jbjisw$r^55)->uQ#W_DF;z!p z*Jy|xoJ1f@eiM)=7|R_lvkQgJsG0)hbl#dUF#+#KrO2VI<*780Q=fZ#^-GrLQoL)R zr#hu{34^aHk-m#{Qd7m+L_}`Q)~0e`I)zhw=vZ29Q7GeU6OSC}sgp=39@aXKlz8-r#6*4CsdL57itR*oFA)A1dv*>njLg&ZNVYtrEF!ArBxN}2edTBYF0`@ zhlEeJnlcn0gC+KOHmN3_>aCIYsZ6qJG|5$Bb`>%BM@n=}s=VrS3`k0b*rCwuR5mxa95`{Rb6>~a?SuCW_Vyg? z=;-X+ND%oiWkC5Gapy#yC@|mVVEKiO2iBhzd3+ZlU`>&}kx7%!%#DD48qL7e zRA%OF+(y2`p)Hr%3{Sn3(6K|zW>8zEluoy`Jj7aiuq!j!J%C69uEU53oE@~yUcyjcVjQw)0}k51gZ8g{ z(o_I>^EcPQRjZz_%pg@@?=g<1DlO|fyL~g{mY43B@6}2 z+z$0z6*msrzk~K4#h6e=rGxfw=q9a#anSy0q&R5*8Qr45hD;o^e|GhB#jVD1{y!=| zv#fEueE=B~wz@Jg4ji<9!%%GJ6;ZGewzPxxpL5Xu9khSB9@CU?(Ec5?e+TW~LHl>m z{@MPRmPB~AN{oF6?cYKBchLUD%??b>C5pQpYEh+m2kl>O;i`pVGupq3YtJt@aQ;6A z=Ky)lWe|7 zmLhP_{>5@4x}_RcUvb&CbF@^mCA!Z+`{&;R(RmKqe+Hl*`c(k2BbOJ6F2myvIB5T> ze@=ZF*^Db)pDDu0v19o&P_7-ce=?3W#9=`qchLS74}tn3a?t+k%f$eouAbaD|My%8 zC!hLkIcWb?mN50jc#c!IJQCxldWv6}>FuEX(}&vvDes{D>uT%+n-w9J zu5r-*9khROZDwM1+p%z(tvhJ{CZdHY6%K80Z_hYr|JBeDO8+=$|4~I64%$DvOm@)z zudwy>EYbdJk^XW1cOeLLEXLt%7YYU7p#5Lrjwgk!gZ9rZhZx5D)qu2rHSi$sV;r=9 zJEA|#g!Zoh<0lECf9`1i3S7Q{-hWa@fPjKN2fY6piu`{C#Qz$uWqbk$^B;b<$r>bk z9*V%h{0D5)yf!)#Z{ETDpU*aNcGA1r;PqKN&Z~_n2lL+yUm)@QRY-T4R)uqqWC!z~ zpy>fJWk2SB( Func f, int n, T def ); - int L_OptInt( int narg, int def ); - string L_OptString( int narg, string def ); - bool L_CallMeta( int obj, string name ); - void L_Traceback( ILuaState otherLua, string msg, int level ); - int L_Len( int index ); - - ThreadStatus L_LoadBuffer( string s, string name ); - ThreadStatus L_LoadBufferX( string s, string name, string mode ); - ThreadStatus L_LoadFile( string filename ); - ThreadStatus L_LoadFileX( string filename, string mode ); - - ThreadStatus L_LoadString( string s ); - ThreadStatus L_LoadBytes( byte[] bytes, string name ); - ThreadStatus L_DoString( string s ); - ThreadStatus L_DoFile( string filename ); - - - string L_Gsub( string src, string pattern, string rep ); - - // reference system - int L_Ref( int t ); - void L_Unref( int t, int reference ); - } - - class StringLoadInfo : ILoadInfo - { - public StringLoadInfo(string s ) - { - Str = s; - Pos = 0; - } - - public int ReadByte() - { - if( Pos >= Str.Length ) - return -1; - else - return Str[Pos++]; - } - - public int PeekByte() - { - if( Pos >= Str.Length ) - return -1; - else - return Str[Pos]; - } - - private string Str; - private int Pos; - } - - class BytesLoadInfo : ILoadInfo - { - public BytesLoadInfo( byte[] bytes ) - { - Bytes = bytes; - Pos = 0; - } - - public int ReadByte() - { - if( Pos >= Bytes.Length ) - return -1; - else - return Bytes[Pos++]; - } - - public int PeekByte() - { - if( Pos >= Bytes.Length ) - return -1; - else - return Bytes[Pos]; - } - - private byte[] Bytes; - private int Pos; - } - - public partial class LuaState - { - private const int LEVELS1 = 12; // size of the first part of the stack - private const int LEVELS2 = 10; // size of the second part of the stack - - public void L_Where( int level ) - { - LuaDebug ar = new LuaDebug(); - if( API.GetStack( level, ar ) ) // check function at level - { - GetInfo( "Sl", ar ); // get info about it - if( ar.CurrentLine > 0 ) // is there info? - { - API.PushString( string.Format( "{0}:{1}: ", ar.ShortSrc, ar.CurrentLine ) ); - return; - } - } - API.PushString( "" ); // else, no information available... - } - - public int L_Error( string fmt, params object[] args ) - { - L_Where( 1 ); - API.PushString( string.Format( fmt, args ) ); - API.Concat( 2 ); - return API.Error(); - } - - public void L_CheckStack( int size, string msg ) - { - // keep some extra space to run error routines, if needed - if(!API.CheckStack(size + LuaDef.LUA_MINSTACK)) { - if(msg != null) - { L_Error(string.Format("stack overflow ({0})", msg)); } - else - { L_Error("stack overflow"); } - } - } - - public void L_CheckAny( int narg ) - { - if( API.Type( narg ) == LuaType.LUA_TNONE ) - L_ArgError( narg, "value expected" ); - } - - public double L_CheckNumber( int narg ) - { - bool isnum; - double d = API.ToNumberX( narg, out isnum ); - if( !isnum ) - TagError( narg, LuaType.LUA_TNUMBER ); - return d; - } - - public UInt64 L_CheckUInt64( int narg ) - { - bool isnum; - UInt64 v = API.ToUInt64X( narg, out isnum ); - if( !isnum ) - TagError( narg, LuaType.LUA_TUINT64 ); - return v; - } - - public int L_CheckInteger( int narg ) - { - bool isnum; - int d = API.ToIntegerX( narg, out isnum ); - if( !isnum ) - TagError( narg, LuaType.LUA_TNUMBER ); - return d; - } - - public string L_CheckString( int narg ) - { - string s = API.ToString( narg ); - if( s == null ) TagError( narg, LuaType.LUA_TSTRING ); - return s; - } - - public uint L_CheckUnsigned( int narg ) - { - bool isnum; - uint d = API.ToUnsignedX( narg, out isnum ); - if( !isnum ) - TagError( narg, LuaType.LUA_TNUMBER ); - return d; - } - - public T L_Opt( Func f, int n, T def ) - { - LuaType t = API.Type( n ); - if( t == LuaType.LUA_TNONE || - t == LuaType.LUA_TNIL ) - { - return def; - } - else - { - return f( n ); - } - } - - public int L_OptInt( int narg, int def ) - { - LuaType t = API.Type( narg ); - if( t == LuaType.LUA_TNONE || - t == LuaType.LUA_TNIL ) - { - return def; - } - else - { - return L_CheckInteger( narg ); - } - } - - public string L_OptString( int narg, string def ) - { - LuaType t = API.Type( narg ); - if( t == LuaType.LUA_TNONE || - t == LuaType.LUA_TNIL ) - { - return def; - } - else - { - return L_CheckString( narg ); - } - } - - private int TypeError( int index, string typeName ) - { - string msg = string.Format( "{0} expected, got {1}", - typeName, L_TypeName( index ) ); - API.PushString( msg ); - return L_ArgError( index, msg ); - } - - private void TagError( int index, LuaType t ) - { - TypeError( index, API.TypeName( t ) ); - } - - public void L_CheckType( int index, LuaType t ) - { - if( API.Type( index ) != t ) - TagError( index, t ); - } - - public void L_ArgCheck( bool cond, int narg, string extraMsg ) - { - if( !cond ) - L_ArgError( narg, extraMsg ); - } - - public int L_ArgError( int narg, string extraMsg ) - { - - LuaDebug ar = new LuaDebug(); - if( !API.GetStack( 0, ar ) ) // no stack frame ? - return L_Error( "bad argument {0} ({1})", narg, extraMsg ); - - GetInfo( "n", ar ); - if( ar.NameWhat == "method" ) - { - narg--; // do not count 'self' - if( narg == 0 ) // error is in the self argument itself? - return L_Error( "calling '{0}' on bad self", ar.Name ); - } - if( ar.Name == null ) - ar.Name = PushGlobalFuncName( ar ) ? API.ToString(-1) : "?"; - return L_Error( "bad argument {0} to '{1}' ({2})", - narg, ar.Name, extraMsg ); - } - - public string L_TypeName( int index ) - { - return API.TypeName( API.Type( index ) ); - } - - public bool L_GetMetaField( int obj, string name ) - { - if( !API.GetMetaTable(obj) ) // no metatable? - return false; - API.PushString( name ); - API.RawGet( -2 ); - if( API.IsNil( -1 ) ) - { - API.Pop( 2 ); - return false; - } - else - { - API.Remove( -2 ); - return true; - } - } - - public bool L_CallMeta( int obj, string name ) - { - obj = API.AbsIndex( obj ); - if( !L_GetMetaField( obj, name ) ) // no metafield? - return false; - - API.PushValue( obj ); - API.Call( 1, 1 ); - return true; - } - - private void PushFuncName( LuaDebug ar ) - { - if( ar.NameWhat.Length > 0 && ar.NameWhat[0] != '\0' ) // is there a name? - API.PushString( string.Format( "function '{0}'", ar.Name ) ); - else if( ar.What.Length > 0 && ar.What[0] == 'm' ) // main? - API.PushString( "main chunk" ); - else if( ar.What.Length > 0 && ar.What[0] == 'C' ) - { - if( PushGlobalFuncName( ar ) ) - { - API.PushString( string.Format( "function '{0}'", API.ToString(-1) ) ); - API.Remove( -2 ); //remove name - } - else - API.PushString( "?" ); - } - else - API.PushString( string.Format( "function <{0}:{1}>", ar.ShortSrc, ar.LineDefined ) ); - } - - private int CountLevels() - { - LuaDebug ar = new LuaDebug(); - int li = 1; - int le = 1; - // find an upper bound - while( API.GetStack(le, ar) ) - { - li = le; - le *= 2; - } - // do a binary search - while(li < le) - { - int m = (li + le)/2; - if( API.GetStack( m, ar ) ) - li = m + 1; - else - le = m; - } - return le - 1; - } - - public void L_Traceback( ILuaState otherLua, string msg, int level ) - { - LuaState oLua = otherLua as LuaState; - LuaDebug ar = new LuaDebug(); - int top = API.GetTop(); - int numLevels = oLua.CountLevels(); - int mark = (numLevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; - if( msg != null ) - API.PushString( string.Format( "{0}\n", msg ) ); - API.PushString( "stack traceback:" ); - while( otherLua.GetStack( level++, ar ) ) - { - if( level == mark ) // too many levels? - { - API.PushString( "\n\t..." ); - level = numLevels - LEVELS2; // and skip to last ones - } - else - { - oLua.GetInfo( "Slnt", ar ); - API.PushString( string.Format( "\n\t{0}:", ar.ShortSrc ) ); - if( ar.CurrentLine > 0 ) - API.PushString( string.Format( "{0}:", ar.CurrentLine ) ); - API.PushString(" in "); - PushFuncName( ar ); - if( ar.IsTailCall ) - API.PushString( "\n\t(...tail calls...)" ); - API.Concat( API.GetTop() - top ); - } - } - API.Concat( API.GetTop() - top ); - } - - public int L_Len( int index ) - { - API.Len( index ); - - bool isnum; - int l = (int)API.ToIntegerX( -1, out isnum ); - if( !isnum ) - L_Error( "object length is not a number" ); - API.Pop( 1 ); - return l; - } - - public ThreadStatus L_LoadBuffer( string s, string name ) - { - return L_LoadBufferX( s, name, null ); - } - - public ThreadStatus L_LoadBufferX( string s, string name, string mode ) - { - var loadinfo = new StringLoadInfo( s ); - return API.Load( loadinfo, name, mode ); - } - - public ThreadStatus L_LoadBytes( byte[] bytes, string name ) - { - var loadinfo = new BytesLoadInfo( bytes ); - return API.Load( loadinfo, name, null ); - } - - private ThreadStatus ErrFile( string what, int fnameindex ) - { - return ThreadStatus.LUA_ERRFILE; - } - - public ThreadStatus L_LoadFile( string filename ) - { - return L_LoadFileX( filename, null ); - } - - public ThreadStatus L_LoadFileX( string filename, string mode ) - { - var status = ThreadStatus.LUA_OK; - if( filename == null ) - { - // 暂不实现从 stdin 输入 - throw new System.NotImplementedException(); - } - - int fnameindex = API.GetTop() + 1; - API.PushString( "@" + filename ); - try - { - using( var loadinfo = LuaFile.OpenFile( filename ) ) - { - loadinfo.SkipComment(); - status = API.Load( loadinfo, API.ToString(-1), mode ); - } - } - catch( LuaRuntimeException e ) - { - API.PushString( string.Format( "cannot open {0}: {1}", - filename, e.Message ) ); - return ThreadStatus.LUA_ERRFILE; - } - - API.Remove( fnameindex ); - return status; - } - - public ThreadStatus L_LoadString( string s ) - { - return L_LoadBuffer( s, s ); - } - - public ThreadStatus L_DoString( string s ) - { - var status = L_LoadString( s ); - if( status != ThreadStatus.LUA_OK ) - return status; - return API.PCall( 0, LuaDef.LUA_MULTRET, 0 ); - } - - public ThreadStatus L_DoFile( string filename ) - { - var status = L_LoadFile( filename ); - if( status != ThreadStatus.LUA_OK ) - return status; - return API.PCall( 0, LuaDef.LUA_MULTRET, 0 ); - } - - public string L_Gsub( string src, string pattern, string rep ) - { - string res = src.Replace(pattern, rep); - API.PushString( res ); - return res; - } - - public string L_ToString( int index ) - { - if( !L_CallMeta( index, "__tostring" ) ) // no metafield? // TODO L_CallMeta - { - switch( API.Type(index) ) - { - case LuaType.LUA_TNUMBER: - case LuaType.LUA_TSTRING: - API.PushValue( index ); - break; - - case LuaType.LUA_TBOOLEAN: - API.PushString( API.ToBoolean( index ) ? "true" : "false" ); - break; - - case LuaType.LUA_TNIL: - API.PushString( "nil" ); - break; - - default: - API.PushString( string.Format("{0}: {1:X}" - , L_TypeName( index ) - , API.ToObject( index ).GetHashCode() - ) ); - break; - } - } - return API.ToString( -1 ); - } - - // private static class LibLoadInfo - // { - // public static List Items; - - // static LibLoadInfo() - // { - // Items = new List(); - // Add( "_G", LuaState.LuaOpen_Base ); - // } - - // private static void Add( string name, CSharpFunctionDelegate loadFunc ) - // { - // Items.Add( new NameFuncPair { Name=name, LoadFunc=loadFunc } ); - // } - // } - - public void L_OpenLibs() - { - NameFuncPair[] define = new NameFuncPair[] - { - new NameFuncPair( "_G", LuaBaseLib.OpenLib ), - new NameFuncPair( LuaPkgLib.LIB_NAME, LuaPkgLib.OpenLib ), - new NameFuncPair( LuaCoroLib.LIB_NAME, LuaCoroLib.OpenLib ), - new NameFuncPair( LuaTableLib.LIB_NAME, LuaTableLib.OpenLib ), - new NameFuncPair( LuaIOLib.LIB_NAME, LuaIOLib.OpenLib ), - new NameFuncPair( LuaOSLib.LIB_NAME, LuaOSLib.OpenLib ), + using System; + using System.IO; + using System.Collections.Generic; + + public struct NameFuncPair + { + public string Name; + public CSharpFunctionDelegate Func; + + public NameFuncPair(string name, CSharpFunctionDelegate func) + { + Name = name; + Func = func; + } + } + + public interface ILuaAuxLib + { + void L_Where(int level); + int L_Error(string fmt, params object[] args); + void L_CheckStack(int size, string msg); + void L_CheckAny(int narg); + void L_CheckType(int index, LuaType t); + double L_CheckNumber(int narg); + UInt64 L_CheckUInt64(int narg); + int L_CheckInteger(int narg); + string L_CheckString(int narg); + uint L_CheckUnsigned(int narg); + void L_ArgCheck(bool cond, int narg, string extraMsg); + int L_ArgError(int narg, string extraMsg); + string L_TypeName(int index); + + string L_ToString(int index); + bool L_GetMetaField(int index, string method); + int L_GetSubTable(int index, string fname); + + void L_RequireF(string moduleName, CSharpFunctionDelegate openFunc, bool global); + void L_OpenLibs(); + void L_NewLibTable(NameFuncPair[] define); + void L_NewLib(NameFuncPair[] define); + void L_SetFuncs(NameFuncPair[] define, int nup); + + T L_Opt(Func f, int n, T def); + int L_OptInt(int narg, int def); + string L_OptString(int narg, string def); + bool L_CallMeta(int obj, string name); + void L_Traceback(ILuaState otherLua, string msg, int level); + int L_Len(int index); + + ThreadStatus L_LoadBuffer(string s, string name); + ThreadStatus L_LoadBufferX(string s, string name, string mode); + ThreadStatus L_LoadFile(string filename); + ThreadStatus L_LoadFileX(string filename, string mode); + + ThreadStatus L_LoadString(string s); + ThreadStatus L_LoadBytes(byte[] bytes, string name); + ThreadStatus L_DoString(string s); + ThreadStatus L_DoFile(string filename); + + + string L_Gsub(string src, string pattern, string rep); + + // reference system + int L_Ref(int t); + void L_Unref(int t, int reference); + } + + class StringLoadInfo : ILoadInfo + { + public StringLoadInfo(string s) + { + Str = s; + Pos = 0; + } + + public int ReadByte() + { + if (Pos >= Str.Length) + return -1; + else + return Str[Pos++]; + } + + public int PeekByte() + { + if (Pos >= Str.Length) + return -1; + else + return Str[Pos]; + } + + private string Str; + private int Pos; + } + + class BytesLoadInfo : ILoadInfo + { + public BytesLoadInfo(byte[] bytes) + { + Bytes = bytes; + Pos = 0; + } + + public int ReadByte() + { + if (Pos >= Bytes.Length) + return -1; + else + return Bytes[Pos++]; + } + + public int PeekByte() + { + if (Pos >= Bytes.Length) + return -1; + else + return Bytes[Pos]; + } + + private byte[] Bytes; + private int Pos; + } + + public partial class LuaState + { + private const int LEVELS1 = 12; // size of the first part of the stack + private const int LEVELS2 = 10; // size of the second part of the stack + + public void L_Where(int level) + { + LuaDebug ar = new LuaDebug(); + if (API.GetStack(level, ar)) // check function at level + { + GetInfo("Sl", ar); // get info about it + if (ar.CurrentLine > 0) // is there info? + { + API.PushString(string.Format("{0}:{1}: ", ar.ShortSrc, ar.CurrentLine)); + return; + } + } + API.PushString(""); // else, no information available... + } + + public int L_Error(string fmt, params object[] args) + { + L_Where(1); + API.PushString(string.Format(fmt, args)); + API.Concat(2); + return API.Error(); + } + + public void L_CheckStack(int size, string msg) + { + // keep some extra space to run error routines, if needed + if (!API.CheckStack(size + LuaDef.LUA_MINSTACK)) + { + if (msg != null) + { L_Error(string.Format("stack overflow ({0})", msg)); } + else + { L_Error("stack overflow"); } + } + } + + public void L_CheckAny(int narg) + { + if (API.Type(narg) == LuaType.LUA_TNONE) + L_ArgError(narg, "value expected"); + } + + public double L_CheckNumber(int narg) + { + bool isnum; + double d = API.ToNumberX(narg, out isnum); + if (!isnum) + TagError(narg, LuaType.LUA_TNUMBER); + return d; + } + + public UInt64 L_CheckUInt64(int narg) + { + bool isnum; + UInt64 v = API.ToUInt64X(narg, out isnum); + if (!isnum) + TagError(narg, LuaType.LUA_TUINT64); + return v; + } + + public int L_CheckInteger(int narg) + { + bool isnum; + int d = API.ToIntegerX(narg, out isnum); + if (!isnum) + TagError(narg, LuaType.LUA_TNUMBER); + return d; + } + + public string L_CheckString(int narg) + { + string s = API.ToString(narg); + if (s == null) TagError(narg, LuaType.LUA_TSTRING); + return s; + } + + public uint L_CheckUnsigned(int narg) + { + bool isnum; + uint d = API.ToUnsignedX(narg, out isnum); + if (!isnum) + TagError(narg, LuaType.LUA_TNUMBER); + return d; + } + + public T L_Opt(Func f, int n, T def) + { + LuaType t = API.Type(n); + if (t == LuaType.LUA_TNONE || + t == LuaType.LUA_TNIL) + { + return def; + } + else + { + return f(n); + } + } + + public int L_OptInt(int narg, int def) + { + LuaType t = API.Type(narg); + if (t == LuaType.LUA_TNONE || + t == LuaType.LUA_TNIL) + { + return def; + } + else + { + return L_CheckInteger(narg); + } + } + + public string L_OptString(int narg, string def) + { + LuaType t = API.Type(narg); + if (t == LuaType.LUA_TNONE || + t == LuaType.LUA_TNIL) + { + return def; + } + else + { + return L_CheckString(narg); + } + } + + private int TypeError(int index, string typeName) + { + string msg = string.Format("{0} expected, got {1}", + typeName, L_TypeName(index)); + API.PushString(msg); + return L_ArgError(index, msg); + } + + private void TagError(int index, LuaType t) + { + TypeError(index, API.TypeName(t)); + } + + public void L_CheckType(int index, LuaType t) + { + if (API.Type(index) != t) + TagError(index, t); + } + + public void L_ArgCheck(bool cond, int narg, string extraMsg) + { + if (!cond) + L_ArgError(narg, extraMsg); + } + + public int L_ArgError(int narg, string extraMsg) + { + + LuaDebug ar = new LuaDebug(); + if (!API.GetStack(0, ar)) // no stack frame ? + return L_Error("bad argument {0} ({1})", narg, extraMsg); + + GetInfo("n", ar); + if (ar.NameWhat == "method") + { + narg--; // do not count 'self' + if (narg == 0) // error is in the self argument itself? + return L_Error("calling '{0}' on bad self", ar.Name); + } + if (ar.Name == null) + ar.Name = PushGlobalFuncName(ar) ? API.ToString(-1) : "?"; + return L_Error("bad argument {0} to '{1}' ({2})", + narg, ar.Name, extraMsg); + } + + public string L_TypeName(int index) + { + return API.TypeName(API.Type(index)); + } + + public bool L_GetMetaField(int obj, string name) + { + if (!API.GetMetaTable(obj)) // no metatable? + return false; + API.PushString(name); + API.RawGet(-2); + if (API.IsNil(-1)) + { + API.Pop(2); + return false; + } + else + { + API.Remove(-2); + return true; + } + } + + public bool L_CallMeta(int obj, string name) + { + obj = API.AbsIndex(obj); + if (!L_GetMetaField(obj, name)) // no metafield? + return false; + + API.PushValue(obj); + API.Call(1, 1); + return true; + } + + private void PushFuncName(LuaDebug ar) + { + if (ar.NameWhat.Length > 0 && ar.NameWhat[0] != '\0') // is there a name? + API.PushString(string.Format("function '{0}'", ar.Name)); + else if (ar.What.Length > 0 && ar.What[0] == 'm') // main? + API.PushString("main chunk"); + else if (ar.What.Length > 0 && ar.What[0] == 'C') + { + if (PushGlobalFuncName(ar)) + { + API.PushString(string.Format("function '{0}'", API.ToString(-1))); + API.Remove(-2); //remove name + } + else + API.PushString("?"); + } + else + API.PushString(string.Format("function <{0}:{1}>", ar.ShortSrc, ar.LineDefined)); + } + + private int CountLevels() + { + LuaDebug ar = new LuaDebug(); + int li = 1; + int le = 1; + // find an upper bound + while (API.GetStack(le, ar)) + { + li = le; + le *= 2; + } + // do a binary search + while (li < le) + { + int m = (li + le) / 2; + if (API.GetStack(m, ar)) + li = m + 1; + else + le = m; + } + return le - 1; + } + + public void L_Traceback(ILuaState otherLua, string msg, int level) + { + LuaState oLua = otherLua as LuaState; + LuaDebug ar = new LuaDebug(); + int top = API.GetTop(); + int numLevels = oLua.CountLevels(); + int mark = (numLevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; + if (msg != null) + API.PushString(string.Format("{0}\n", msg)); + API.PushString("stack traceback:"); + while (otherLua.GetStack(level++, ar)) + { + if (level == mark) // too many levels? + { + API.PushString("\n\t..."); + level = numLevels - LEVELS2; // and skip to last ones + } + else + { + oLua.GetInfo("Slnt", ar); + API.PushString(string.Format("\n\t{0}:", ar.ShortSrc)); + if (ar.CurrentLine > 0) + API.PushString(string.Format("{0}:", ar.CurrentLine)); + API.PushString(" in "); + PushFuncName(ar); + if (ar.IsTailCall) + API.PushString("\n\t(...tail calls...)"); + API.Concat(API.GetTop() - top); + } + } + API.Concat(API.GetTop() - top); + } + + public int L_Len(int index) + { + API.Len(index); + + bool isnum; + int l = (int)API.ToIntegerX(-1, out isnum); + if (!isnum) + L_Error("object length is not a number"); + API.Pop(1); + return l; + } + + public ThreadStatus L_LoadBuffer(string s, string name) + { + return L_LoadBufferX(s, name, null); + } + + public ThreadStatus L_LoadBufferX(string s, string name, string mode) + { + var loadinfo = new StringLoadInfo(s); + return API.Load(loadinfo, name, mode); + } + + public ThreadStatus L_LoadBytes(byte[] bytes, string name) + { + var loadinfo = new BytesLoadInfo(bytes); + return API.Load(loadinfo, name, null); + } + + private ThreadStatus ErrFile(string what, int fnameindex) + { + return ThreadStatus.LUA_ERRFILE; + } + + public ThreadStatus L_LoadFile(string filename) + { + return L_LoadFileX(filename, null); + } + + public ThreadStatus L_LoadFileX(string filename, string mode) + { + var status = ThreadStatus.LUA_OK; + if (filename == null) + { + // 暂不实现从 stdin 输入 + throw new System.NotImplementedException(); + } + + int fnameindex = API.GetTop() + 1; + API.PushString("@" + filename); + try + { + using (var loadinfo = LuaFile.OpenFile(filename)) + { + loadinfo.SkipComment(); + status = API.Load(loadinfo, API.ToString(-1), mode); + } + } + catch (LuaRuntimeException e) + { + API.PushString(string.Format("cannot open {0}: {1}", + filename, e.Message)); + return ThreadStatus.LUA_ERRFILE; + } + + API.Remove(fnameindex); + return status; + } + + public ThreadStatus L_LoadString(string s) + { + return L_LoadBuffer(s, s); + } + + public ThreadStatus L_DoString(string s) + { + var status = L_LoadString(s); + if (status != ThreadStatus.LUA_OK) + return status; + return API.PCall(0, LuaDef.LUA_MULTRET, 0); + } + + public ThreadStatus L_DoFile(string filename) + { + var status = L_LoadFile(filename); + if (status != ThreadStatus.LUA_OK) + return status; + return API.PCall(0, LuaDef.LUA_MULTRET, 0); + } + + public string L_Gsub(string src, string pattern, string rep) + { + string res = src.Replace(pattern, rep); + API.PushString(res); + return res; + } + + public string L_ToString(int index) + { + if (!L_CallMeta(index, "__tostring")) // no metafield? // TODO L_CallMeta + { + switch (API.Type(index)) + { + case LuaType.LUA_TNUMBER: + case LuaType.LUA_TSTRING: + API.PushValue(index); + break; + + case LuaType.LUA_TBOOLEAN: + API.PushString(API.ToBoolean(index) ? "true" : "false"); + break; + + case LuaType.LUA_TNIL: + API.PushString("nil"); + break; + + default: + API.PushString(string.Format("{0}: {1:X}" + , L_TypeName(index) + , API.ToObject(index).GetHashCode() + )); + break; + } + } + return API.ToString(-1); + } + + // private static class LibLoadInfo + // { + // public static List Items; + + // static LibLoadInfo() + // { + // Items = new List(); + // Add( "_G", LuaState.LuaOpen_Base ); + // } + + // private static void Add( string name, CSharpFunctionDelegate loadFunc ) + // { + // Items.Add( new NameFuncPair { Name=name, LoadFunc=loadFunc } ); + // } + // } + + public void L_OpenLibs() + { + NameFuncPair[] define = new NameFuncPair[] + { + new NameFuncPair( "_G", LuaBaseLib.OpenLib ), + new NameFuncPair( LuaPkgLib.LIB_NAME, LuaPkgLib.OpenLib ), + //取消协程 ,项目不需要 + //new NameFuncPair( LuaCoroLib.LIB_NAME, LuaCoroLib.OpenLib ), + new NameFuncPair( LuaTableLib.LIB_NAME, LuaTableLib.OpenLib ), + new NameFuncPair( LuaIOLib.LIB_NAME, LuaIOLib.OpenLib ), + new NameFuncPair( LuaOSLib.LIB_NAME, LuaOSLib.OpenLib ), // {LUA_OSLIBNAME, luaopen_os}, - new NameFuncPair( LuaStrLib.LIB_NAME, LuaStrLib.OpenLib ), - new NameFuncPair( LuaBitLib.LIB_NAME, LuaBitLib.OpenLib ), - new NameFuncPair( LuaMathLib.LIB_NAME, LuaMathLib.OpenLib ), - new NameFuncPair( LuaDebugLib.LIB_NAME, LuaDebugLib.OpenLib ), - new NameFuncPair( LuaFFILib.LIB_NAME, LuaFFILib.OpenLib ), - new NameFuncPair( LuaEncLib.LIB_NAME, LuaEncLib.OpenLib ), - }; - - for( var i=0; i= 0 ) - { - t = API.AbsIndex(t); - API.RawGetI(t, FreeList); - API.RawSetI(t, reference); // t[ref] = t[freelist] - API.PushInteger(reference); - API.RawSetI(t, FreeList); // t[freelist] = ref - } - } + new NameFuncPair( LuaStrLib.LIB_NAME, LuaStrLib.OpenLib ), + new NameFuncPair( LuaBitLib.LIB_NAME, LuaBitLib.OpenLib ), + new NameFuncPair( LuaMathLib.LIB_NAME, LuaMathLib.OpenLib ), + new NameFuncPair( LuaDebugLib.LIB_NAME, LuaDebugLib.OpenLib ), + new NameFuncPair( LuaFFILib.LIB_NAME, LuaFFILib.OpenLib ), + new NameFuncPair( LuaEncLib.LIB_NAME, LuaEncLib.OpenLib ), + }; + + for (var i = 0; i < define.Length; ++i) + { + L_RequireF(define[i].Name, define[i].Func, true); + API.Pop(1); + } + + // LuaBaseLib.LuaOpen_Base( this ); + } + + public void L_RequireF(string moduleName, CSharpFunctionDelegate openFunc, bool global) + { + API.PushCSharpFunction(openFunc); + API.PushString(moduleName); + API.Call(1, 1); + L_GetSubTable(LuaDef.LUA_REGISTRYINDEX, "_LOADED"); + API.PushValue(-2); + API.SetField(-2, moduleName); + API.Pop(1); + if (global) + { + API.PushValue(-1); + API.SetGlobal(moduleName); + } + } + + public int L_GetSubTable(int index, string fname) + { + API.GetField(index, fname); + if (API.IsTable(-1)) + return 1; + else + { + API.Pop(1); + index = API.AbsIndex(index); + API.NewTable(); + API.PushValue(-1); + API.SetField(index, fname); + return 0; + } + } + + public void L_NewLibTable(NameFuncPair[] define) + { + API.CreateTable(0, define.Length); + } + + public void L_NewLib(NameFuncPair[] define) + { + L_NewLibTable(define); + L_SetFuncs(define, 0); + } + + public void L_SetFuncs(NameFuncPair[] define, int nup) + { + // TODO: Check Version + L_CheckStack(nup, "too many upvalues"); + for (var j = 0; j < define.Length; ++j) + { + for (int i = 0; i < nup; ++i) + API.PushValue(-nup); + API.PushCSharpClosure(define[j].Func, nup); + API.SetField(-(nup + 2), define[j].Name); + } + API.Pop(nup); + } + + private bool FindField(int objIndex, int level) + { + if (level == 0 || !API.IsTable(-1)) + return false; // not found + + API.PushNil(); // start 'next' loop + while (API.Next(-2)) // for each pair in table + { + if (API.Type(-2) == LuaType.LUA_TSTRING) // ignore non-string keys + { + if (API.RawEqual(objIndex, -1)) // found object? + { + API.Pop(1); // remove value (but keep name) + return true; + } + else if (FindField(objIndex, level - 1)) // try recursively + { + API.Remove(-2); // remove table (but keep name) + API.PushString("."); + API.Insert(-2); // place '.' between the two names + API.Concat(3); + return true; + } + } + API.Pop(1); // remove value + } + return false; // not found + } + + private bool PushGlobalFuncName(LuaDebug ar) + { + int top = API.GetTop(); + GetInfo("f", ar); + API.PushGlobalTable(); + if (FindField(top + 1, 2)) + { + API.Copy(-1, top + 1); + API.Pop(2); + return true; + } + else + { + API.SetTop(top); // remove function and global table + return false; + } + } + + private const int FreeList = 0; + + public int L_Ref(int t) + { + if (API.IsNil(-1)) + { + API.Pop(1); // remove from stack + return LuaConstants.LUA_REFNIL; // `nil' has a unique fixed reference + } + + t = API.AbsIndex(t); + API.RawGetI(t, FreeList); // get first free element + int reference = API.ToInteger(-1); // ref = t[freelist] + API.Pop(1); // remove it from stack + if (reference != 0) // any free element? + { + API.RawGetI(t, reference); // remove it from list + API.RawSetI(t, FreeList); // t[freelist] = t[ref] + } + else // no free elements + reference = API.RawLen(t) + 1; // get a new reference + API.RawSetI(t, reference); + return reference; + } + + public void L_Unref(int t, int reference) + { + if (reference >= 0) + { + t = API.AbsIndex(t); + API.RawGetI(t, FreeList); + API.RawSetI(t, reference); // t[ref] = t[freelist] + API.PushInteger(reference); + API.RawSetI(t, FreeList); // t[freelist] = ref + } + } #if UNITY_IPHONE public void FEED_AOT_FOR_IOS(LuaState lua) @@ -728,7 +730,7 @@ public void FEED_AOT_FOR_IOS(LuaState lua) } #endif - } + } } diff --git a/Assets/UniLua/LuaAuxLib.cs.meta b/Assets/UniLua/LuaAuxLib.cs.meta deleted file mode 100644 index ff43ba6..0000000 --- a/Assets/UniLua/LuaAuxLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 86e3d38c3ec5564498927f6501ca8f4c -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaBaseLib.cs.meta b/Assets/UniLua/LuaBaseLib.cs.meta deleted file mode 100644 index f545a7b..0000000 --- a/Assets/UniLua/LuaBaseLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7cc8418b4b85dc14487471530afa6bbe -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaBitLib.cs.meta b/Assets/UniLua/LuaBitLib.cs.meta deleted file mode 100644 index de4e9f0..0000000 --- a/Assets/UniLua/LuaBitLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 215359d6c496b9847950e267f6ed7c5b -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaCoroLib.cs.meta b/Assets/UniLua/LuaCoroLib.cs.meta deleted file mode 100644 index 161b30f..0000000 --- a/Assets/UniLua/LuaCoroLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7f5c3b7ec847e854193d6255b700d550 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaDebug.cs.meta b/Assets/UniLua/LuaDebug.cs.meta deleted file mode 100644 index 6aed2cc..0000000 --- a/Assets/UniLua/LuaDebug.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7f7fe687cc1d69b4f9408695db6faa4d -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaDebugLib.cs.meta b/Assets/UniLua/LuaDebugLib.cs.meta deleted file mode 100644 index fd68cbe..0000000 --- a/Assets/UniLua/LuaDebugLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2d8bd4859485e144a9691e1b2e938c73 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaEncLib.cs.meta b/Assets/UniLua/LuaEncLib.cs.meta deleted file mode 100644 index ef86e57..0000000 --- a/Assets/UniLua/LuaEncLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9443b021a85a2a149b8606356d3e21f5 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaFFILib.cs.meta b/Assets/UniLua/LuaFFILib.cs.meta deleted file mode 100644 index 338c092..0000000 --- a/Assets/UniLua/LuaFFILib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 62efbce053b703f41af3d6cea2a6d4de -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaFile.cs b/Assets/UniLua/LuaFile.cs index ddb29b4..c2f999c 100644 --- a/Assets/UniLua/LuaFile.cs +++ b/Assets/UniLua/LuaFile.cs @@ -2,92 +2,98 @@ using System.IO; using System.Collections.Generic; -using UnityEngine; + namespace UniLua { - public delegate string PathHook(string filename); - public class LuaFile - { - //private static readonly string LUA_ROOT = System.IO.Path.Combine(Application.streamingAssetsPath, "LuaRoot"); - private static PathHook pathhook = (s) => Path.Combine(Path.Combine(Application.streamingAssetsPath, "LuaRoot"), s); - public static void SetPathHook(PathHook hook) { - pathhook = hook; - } - - public static FileLoadInfo OpenFile( string filename ) - { - //var path = System.IO.Path.Combine(LUA_ROOT, filename); - var path = pathhook(filename); - return new FileLoadInfo( File.Open( path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) ); - } - - public static bool Readable( string filename ) - { - //var path = System.IO.Path.Combine(LUA_ROOT, filename); - var path = pathhook(filename); - try { - using( var stream = File.Open( path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) ) { - return true; - } - } - catch( Exception ) { - return false; - } - } - } - - public class FileLoadInfo : ILoadInfo, IDisposable - { - public FileLoadInfo( FileStream stream ) - { - Stream = stream; - Reader = new StreamReader(Stream, System.Text.Encoding.UTF8); - Buf = new Queue(); - } - - public int ReadByte() - { - if( Buf.Count > 0 ) - return (int)Buf.Dequeue(); - else - return Reader.Read(); - } - - public int PeekByte() - { - if( Buf.Count > 0 ) - return (int)Buf.Peek(); - else - { - var c = Reader.Read(); - if( c == -1 ) - return c; - Save( (char)c ); - return c; - } - } - - public void Dispose() - { - Reader.Dispose(); - Stream.Dispose(); - } - - private const string UTF8_BOM = "\u00EF\u00BB\u00BF"; - private FileStream Stream; - private StreamReader Reader; - private Queue Buf; - - private void Save( char b ) - { - Buf.Enqueue( b ); - } - - private void Clear() - { - Buf.Clear(); - } + public delegate string PathHook(string filename); + public class LuaFile + { + // private static readonly string LUA_ROOT = System.IO.Path.Combine(Application.streamingAssetsPath, "LuaRoot"); + // private static PathHook pathhook = (s) => Path.Combine(Path.Combine(Application.streamingAssetsPath, "LuaRoot"), s); + private static readonly string LUA_ROOT = ""; + private static PathHook pathhook; + public static void SetPathHook(PathHook hook) + { + pathhook = hook; + } + + public static FileLoadInfo OpenFile(string filename) + { + var path = System.IO.Path.Combine(LUA_ROOT, filename); + + return new FileLoadInfo(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); + } + + public static bool Readable(string filename) + { + var path = System.IO.Path.Combine(LUA_ROOT, filename); + // var path = pathhook(filename); + try + { + using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + return true; + } + } + catch (Exception) + { + return false; + } + } + } + + public class FileLoadInfo : ILoadInfo, IDisposable + { + public FileLoadInfo(FileStream stream) + { + Stream = stream; + Reader = new StreamReader(Stream, System.Text.Encoding.UTF8); + Buf = new Queue(); + } + + public int ReadByte() + { + if (Buf.Count > 0) + return (int)Buf.Dequeue(); + else + return Reader.Read(); + } + + public int PeekByte() + { + if (Buf.Count > 0) + return (int)Buf.Peek(); + else + { + var c = Reader.Read(); + if (c == -1) + return c; + Save((char)c); + return c; + } + } + + public void Dispose() + { + Reader.Dispose(); + Stream.Dispose(); + } + + private const string UTF8_BOM = "\u00EF\u00BB\u00BF"; + private FileStream Stream; + private StreamReader Reader; + private Queue Buf; + + private void Save(char b) + { + Buf.Enqueue(b); + } + + private void Clear() + { + Buf.Clear(); + } #if false private int SkipBOM() @@ -105,24 +111,25 @@ private int SkipBOM() } #endif - public void SkipComment() - { - var c = Reader.Read();//SkipBOM(); - - // first line is a comment (Unix exec. file)? - if( c == '#' ) - { - do { - c = Reader.Read(); - } while( c != -1 && c != '\n' ); - Save( (char)'\n' ); // fix line number - } - else if( c != -1 ) - { - Save( (char)c ); - } - } - } + public void SkipComment() + { + var c = Reader.Read();//SkipBOM(); + + // first line is a comment (Unix exec. file)? + if (c == '#') + { + do + { + c = Reader.Read(); + } while (c != -1 && c != '\n'); + Save((char)'\n'); // fix line number + } + else if (c != -1) + { + Save((char)c); + } + } + } } diff --git a/Assets/UniLua/LuaFile.cs.meta b/Assets/UniLua/LuaFile.cs.meta deleted file mode 100644 index 165e391..0000000 --- a/Assets/UniLua/LuaFile.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 94f4a97c688e9b64ca02f12e4355bd91 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaFunc.cs.meta b/Assets/UniLua/LuaFunc.cs.meta deleted file mode 100644 index ac8cee6..0000000 --- a/Assets/UniLua/LuaFunc.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f7f16d8b096a1514bbd721daf62df68c -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaIOLib.cs.meta b/Assets/UniLua/LuaIOLib.cs.meta deleted file mode 100644 index a6cd842..0000000 --- a/Assets/UniLua/LuaIOLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 16458140beb4e1e41810fcaf658f6fe6 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaMathLib.cs.meta b/Assets/UniLua/LuaMathLib.cs.meta deleted file mode 100644 index 4bd6978..0000000 --- a/Assets/UniLua/LuaMathLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a950cf5ed15c8b943b03296567b51781 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaObject.cs.meta b/Assets/UniLua/LuaObject.cs.meta deleted file mode 100644 index 4d8a640..0000000 --- a/Assets/UniLua/LuaObject.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: bf55010417da6c24ebaf30190f254d0f -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaOsLib.cs.meta b/Assets/UniLua/LuaOsLib.cs.meta deleted file mode 100644 index a3492e6..0000000 --- a/Assets/UniLua/LuaOsLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: bc4220d4d4551884aa891d61dac262f8 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaPkgLib.cs b/Assets/UniLua/LuaPkgLib.cs index 0809f92..933cbc7 100644 --- a/Assets/UniLua/LuaPkgLib.cs +++ b/Assets/UniLua/LuaPkgLib.cs @@ -5,140 +5,140 @@ namespace UniLua { - using Environment = System.Environment; - using StringBuilder = System.Text.StringBuilder; - using String = System.String; - using File = System.IO.File; - using FileMode = System.IO.FileMode; - using Exception = System.Exception; - - internal class LuaPkgLib - { - public const string LIB_NAME = "package"; - - private const string CLIBS = "_CLIBS"; - - private const string LUA_PATH = "LUA_PATH"; - private const string LUA_CPATH = "LUA_CPATH"; - private const string LUA_PATHSUFFIX = "_" + LuaDef.LUA_VERSION_MAJOR + - "_" + LuaDef.LUA_VERSION_MINOR; - private const string LUA_PATHVERSION = LUA_PATH + LUA_PATHSUFFIX; - private const string LUA_CPATHVERSION = LUA_CPATH + LUA_PATHSUFFIX; - - // private const string LUA_LDIR = "!\\lua\\"; - // private const string LUA_CDIR = "!\\"; - // private const string LUA_PATH_DEFAULT = LUA_LDIR + "?.lua;" + - // LUA_LDIR + "?\\init.lua;" + - // LUA_CDIR + "?.lua;" + - // LUA_CDIR + "?\\init.lua;" + - // ".\\?.lua"; - // private const string LUA_CPATH_DEFAULT = LUA_CDIR + "?.dll;" + - // LUA_CDIR + "loadall.dll;" + - // ".\\?.dll"; - - private const string LUA_PATH_DEFAULT = "?.lua;"; - private const string LUA_CPATH_DEFAULT = "?.dll;loadall.dll;"; - - private const string LUA_PATH_SEP = ";"; - private const string LUA_PATH_MARK = "?"; - private const string LUA_EXEC_DIR = "!"; - private const string LUA_IGMARK = "-"; - - private static readonly string LUA_LSUBSEP = LuaConf.LUA_DIRSEP; - - // auxiliary mark (for internal use) - private const string AUXMARK = "\u0001"; - - public static int OpenLib( ILuaState lua ) - { - // NameFuncPair[] define = new NameFuncPair[] - // { - // new NameFuncPair( "module", PKG_Module ), - // }; - - // lua.L_NewLib( define ); - - // // create table CLIBS to keep track of loaded C libraries - // lua.L_GetSubTable( LuaDef.LUA_REGISTRYINDEX, CLIBS ); - // lua.CreateTable( 0, 1 ); // metatable for CLIBS - // lua.PushCSharpFunction - - // create `package' table - NameFuncPair[] pkg_define = new NameFuncPair[] - { - new NameFuncPair( "loadlib", PKG_LoadLib ), - new NameFuncPair( "searchpath", PKG_SearchPath ), - new NameFuncPair( "seeall", PKG_SeeAll ), - }; - lua.L_NewLib( pkg_define ); - - CreateSearchersTable( lua ); + using Environment = System.Environment; + using StringBuilder = System.Text.StringBuilder; + using String = System.String; + using File = System.IO.File; + using FileMode = System.IO.FileMode; + using Exception = System.Exception; + + internal class LuaPkgLib + { + public const string LIB_NAME = "package"; + + private const string CLIBS = "_CLIBS"; + + private const string LUA_PATH = "LUA_PATH"; + private const string LUA_CPATH = "LUA_CPATH"; + private const string LUA_PATHSUFFIX = "_" + LuaDef.LUA_VERSION_MAJOR + + "_" + LuaDef.LUA_VERSION_MINOR; + private const string LUA_PATHVERSION = LUA_PATH + LUA_PATHSUFFIX; + private const string LUA_CPATHVERSION = LUA_CPATH + LUA_PATHSUFFIX; + + // private const string LUA_LDIR = "!\\lua\\"; + // private const string LUA_CDIR = "!\\"; + // private const string LUA_PATH_DEFAULT = LUA_LDIR + "?.lua;" + + // LUA_LDIR + "?\\init.lua;" + + // LUA_CDIR + "?.lua;" + + // LUA_CDIR + "?\\init.lua;" + + // ".\\?.lua"; + // private const string LUA_CPATH_DEFAULT = LUA_CDIR + "?.dll;" + + // LUA_CDIR + "loadall.dll;" + + // ".\\?.dll"; + + private const string LUA_PATH_DEFAULT = "?.lua;"; + private const string LUA_CPATH_DEFAULT = "?.dll;loadall.dll;"; + + private const string LUA_PATH_SEP = ";"; + private const string LUA_PATH_MARK = "?"; + private const string LUA_EXEC_DIR = "!"; + private const string LUA_IGMARK = "-"; + + private static readonly string LUA_LSUBSEP = LuaConf.LUA_DIRSEP; + + // auxiliary mark (for internal use) + private const string AUXMARK = "\u0001"; + + public static int OpenLib(ILuaState lua) + { + // NameFuncPair[] define = new NameFuncPair[] + // { + // new NameFuncPair( "module", PKG_Module ), + // }; + + // lua.L_NewLib( define ); + + // // create table CLIBS to keep track of loaded C libraries + // lua.L_GetSubTable( LuaDef.LUA_REGISTRYINDEX, CLIBS ); + // lua.CreateTable( 0, 1 ); // metatable for CLIBS + // lua.PushCSharpFunction + + // create `package' table + NameFuncPair[] pkg_define = new NameFuncPair[] + { + new NameFuncPair( "loadlib", PKG_LoadLib ), + new NameFuncPair( "searchpath", PKG_SearchPath ), + new NameFuncPair( "seeall", PKG_SeeAll ), + }; + lua.L_NewLib(pkg_define); + + CreateSearchersTable(lua); #if LUA_COMPAT_LOADERS - lua.PushValue( -1 ); // make a copy of `searchers' table - lua.SetField( -3, "loaders" ); // put it in field `loaders' + lua.PushValue(-1); // make a copy of `searchers' table + lua.SetField(-3, "loaders"); // put it in field `loaders' #endif - lua.SetField( -2, "searchers" ); // put it in field `searchers' - - // set field `path' - SetPath( lua, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT ); - // set field `cpath' - SetPath( lua, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT ); - - // store config information - lua.PushString( string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n", - LuaConf.LUA_DIRSEP, - LUA_PATH_SEP, - LUA_PATH_MARK, - LUA_EXEC_DIR, - LUA_IGMARK ) ); - lua.SetField( -2, "config" ); - - // set field `loaded' - lua.L_GetSubTable( LuaDef.LUA_REGISTRYINDEX, "_LOADED" ); - lua.SetField( -2, "loaded" ); - - // set field `preload' - lua.L_GetSubTable( LuaDef.LUA_REGISTRYINDEX, "_PRELOAD" ); - lua.SetField( -2, "preload" ); - - lua.PushGlobalTable(); - lua.PushValue( -2 ); // set `package' as upvalue for next lib - - NameFuncPair[] loadLibFuncs = new NameFuncPair[] - { - new NameFuncPair( "module", LL_Module ), - new NameFuncPair( "require", LL_Require ), - }; - lua.L_SetFuncs( loadLibFuncs, 1 ); // open lib into global table - lua.Pop( 1 ); // pop global table - - return 1; // return `package' table - } - - private static void CreateSearchersTable( ILuaState lua ) - { - CSharpFunctionDelegate[] searchers = new CSharpFunctionDelegate[] - { - SearcherPreload, - SearcherLua, - }; - lua.CreateTable( searchers.Length, 0 ); - for( int i=0; i= path.Length ) - return false; - int end = pos+1; - while( end < path.Length && path[end] != LUA_PATH_SEP[0]) - end++; - - var template = path.Substring( pos, end-pos); - lua.PushString( template ); - - pos = end; - return true; - } - - private static string SearchPath( ILuaState lua, - string name, string path, string sep, string dirsep ) - { - var sb = new StringBuilder(); // to build error message - if( !String.IsNullOrEmpty(sep) ) // non-empty separator? - name = name.Replace( sep, dirsep ); // replace it by `dirsep' - int pos = 0; - while(PushNextTemplate(lua, path, ref pos)) - { - var template = lua.ToString(-1); - string filename = template.Replace( LUA_PATH_MARK, name ); - lua.Remove( -1 ); // remove path template - if( Readable( filename ) ) // does file exist and is readable? - return filename; // return that file name - lua.PushString( string.Format( "\n\tno file '{0}'", filename) ); - lua.Remove( -2 ); // remove file name - sb.Append( lua.ToString(-1) ); // concatenate error msg. entry - } - lua.PushString( sb.ToString() ); // create error message - return null; // not found - } - - private static string FindFile( ILuaState lua, - string name, string pname, string dirsep ) - { - lua.GetField( lua.UpvalueIndex(1), pname ); - string path = lua.ToString( -1 ); - if( path == null ) - lua.L_Error( "'package.{0}' must be a string", pname ); - return SearchPath( lua, name, path, ".", dirsep ); - } - - private static int CheckLoad( ILuaState lua, - bool stat, string filename ) - { - if( stat ) // module loaded successfully? - { - lua.PushString( filename ); // will be 2nd arg to module - return 2; // return open function and file name - } - else return lua.L_Error( - "error loading module '{0}' from file '{1}':\n\t{2}", - lua.ToString(1), filename, lua.ToString(-1) ); - } - - private static int SearcherLua( ILuaState lua ) - { - string name = lua.L_CheckString( 1 ); - string filename = FindFile( lua, name, "path", LUA_LSUBSEP ); - if( filename == null ) - return 1; - return CheckLoad( lua, - (lua.L_LoadFile(filename) == ThreadStatus.LUA_OK), - filename ); - } - - private static int LL_Module( ILuaState lua ) - { - // TODO - return 0; - } - - private static void FindLoader( ILuaState lua, string name ) - { - // will be at index 3 - lua.GetField( lua.UpvalueIndex(1), "searchers" ); - if( ! lua.IsTable(3) ) - lua.L_Error("'package.searchers' must be a table"); - - var sb = new StringBuilder(); - // iterator over available searchers to find a loader - for( int i=1; ; ++i ) - { - lua.RawGetI( 3, i ); // get a searcher - if( lua.IsNil( -1 ) ) // no more searchers? - { - lua.Pop( 1 ); // remove nil - lua.PushString( sb.ToString() ); - lua.L_Error( "module '{0}' not found:{1}", - name, lua.ToString(-1)); - return; - } - - lua.PushString( name ); - lua.Call( 1, 2 ); // call it - if( lua.IsFunction(-2) ) // did it find a loader - return; // module loader found - else if( lua.IsString(-2) ) // searcher returned error message? - { - lua.Pop( 1 ); // return extra return - sb.Append( lua.ToString(-1) ); - } - else - lua.Pop( 2 ); // remove both returns - } - } - - private static int LL_Require( ILuaState lua ) - { - string name = lua.L_CheckString( 1 ); - lua.SetTop( 1 ); - // _LOADED table will be at index 2 - lua.GetField( LuaDef.LUA_REGISTRYINDEX, "_LOADED" ); - // _LOADED[name] - lua.GetField( 2, name ); - // is it there? - if( lua.ToBoolean( -1 ) ) - return 1; // package is already loaded - // else must load package - // remove `GetField' result - lua.Pop( 1 ); - FindLoader( lua, name ); - lua.PushString( name ); // pass name as arg to module loader - lua.Insert( -2 ); // name is 1st arg (before search data) - lua.Call( 2, 1 ); // run loader to load module - if( !lua.IsNil( -1 ) ) // non-nil return? - lua.SetField( 2, name ); // _LOADED[name] = returned value - lua.GetField( 2, name ); - if( lua.IsNil( -1 ) ) // module did not set a value? - { - lua.PushBoolean( true ); // use true as result - lua.PushValue( -1 ); // extra copy to be returned - lua.SetField( 2, name ); // _LOADED[name] = true - } - return 1; - } - - private static int PKG_LoadLib( ILuaState lua ) - { - // TODO - return 0; - } - - private static int PKG_SearchPath( ILuaState lua ) - { - // TODO - return 0; - } - - private static int PKG_SeeAll( ILuaState lua ) - { - // TODO - return 0; - } - } + SetProgDir(lua); + lua.SetField(-2, fieldName); + } + + private static bool noEnv(ILuaState lua) + { + lua.GetField(LuaDef.LUA_REGISTRYINDEX, "LUA_NOENV"); + bool res = lua.ToBoolean(-1); + lua.Pop(1); + return res; + } + + private static void SetProgDir(ILuaState lua) + { + // TODO: unity 读本地文件? + // + // 下面的代码在编辑器中可以运行, 但是 build 后运行时会 crash + // var pgs = System.Diagnostics.Process.GetCurrentProcess(); + // ULDebug.Log( pgs.MainModule.FileName ); + } + + private static int SearcherPreload(ILuaState lua) + { + string name = lua.L_CheckString(1); + lua.GetField(LuaDef.LUA_REGISTRYINDEX, "_PRELOAD"); + lua.GetField(-1, name); + if (lua.IsNil(-1)) // not found? + lua.PushString(string.Format( + "\n\tno field package.preload['{0}']", name)); + return 1; + } + + private static bool Readable(string filename) + { + return LuaFile.Readable(filename); + } + + private static bool PushNextTemplate(ILuaState lua, + string path, ref int pos) + { + while (pos < path.Length && path[pos] == LUA_PATH_SEP[0]) + pos++; // skip separators + if (pos >= path.Length) + return false; + int end = pos + 1; + while (end < path.Length && path[end] != LUA_PATH_SEP[0]) + end++; + + var template = path.Substring(pos, end - pos); + lua.PushString(template); + + pos = end; + return true; + } + + private static string SearchPath(ILuaState lua, + string name, string path, string sep, string dirsep) + { + var sb = new StringBuilder(); // to build error message + if (!String.IsNullOrEmpty(sep)) // non-empty separator? + name = name.Replace(sep, dirsep); // replace it by `dirsep' + int pos = 0; + while (PushNextTemplate(lua, path, ref pos)) + { + var template = lua.ToString(-1); + string filename = template.Replace(LUA_PATH_MARK, name); + lua.Remove(-1); // remove path template + if (Readable(filename)) // does file exist and is readable? + return filename; // return that file name + lua.PushString(string.Format("\n\tno file '{0}'", filename)); + lua.Remove(-2); // remove file name + sb.Append(lua.ToString(-1)); // concatenate error msg. entry + } + lua.PushString(sb.ToString()); // create error message + return null; // not found + } + + private static string FindFile(ILuaState lua, + string name, string pname, string dirsep) + { + lua.GetField(lua.UpvalueIndex(1), pname); + string path = lua.ToString(-1); + if (path == null) + lua.L_Error("'package.{0}' must be a string", pname); + return SearchPath(lua, name, path, ".", dirsep); + } + + private static int CheckLoad(ILuaState lua, + bool stat, string filename) + { + if (stat) // module loaded successfully? + { + lua.PushString(filename); // will be 2nd arg to module + return 2; // return open function and file name + } + else return lua.L_Error( + "error loading module '{0}' from file '{1}':\n\t{2}", + lua.ToString(1), filename, lua.ToString(-1)); + } + + private static int SearcherLua(ILuaState lua) + { + string name = lua.L_CheckString(1); + string filename = FindFile(lua, name, "path", LUA_LSUBSEP); + if (filename == null) + return 1; + return CheckLoad(lua, + (lua.L_LoadFile(filename) == ThreadStatus.LUA_OK), + filename); + } + + private static int LL_Module(ILuaState lua) + { + // TODO + return 0; + } + + private static void FindLoader(ILuaState lua, string name) + { + // will be at index 3 + lua.GetField(lua.UpvalueIndex(1), "searchers"); + if (!lua.IsTable(3)) + lua.L_Error("'package.searchers' must be a table"); + + var sb = new StringBuilder(); + // iterator over available searchers to find a loader + for (int i = 1; ; ++i) + { + lua.RawGetI(3, i); // get a searcher + if (lua.IsNil(-1)) // no more searchers? + { + lua.Pop(1); // remove nil + lua.PushString(sb.ToString()); + lua.L_Error("module '{0}' not found:{1}", + name, lua.ToString(-1)); + return; + } + + lua.PushString(name); + lua.Call(1, 2); // call it + if (lua.IsFunction(-2)) // did it find a loader + return; // module loader found + else if (lua.IsString(-2)) // searcher returned error message? + { + lua.Pop(1); // return extra return + sb.Append(lua.ToString(-1)); + } + else + lua.Pop(2); // remove both returns + } + } + + private static int LL_Require(ILuaState lua) + { + string name = lua.L_CheckString(1); + lua.SetTop(1); + // _LOADED table will be at index 2 + lua.GetField(LuaDef.LUA_REGISTRYINDEX, "_LOADED"); + // _LOADED[name] + lua.GetField(2, name); + // is it there? + if (lua.ToBoolean(-1)) + return 1; // package is already loaded + // else must load package + // remove `GetField' result + lua.Pop(1); + FindLoader(lua, name); + lua.PushString(name); // pass name as arg to module loader + lua.Insert(-2); // name is 1st arg (before search data) + lua.Call(2, 1); // run loader to load module + if (!lua.IsNil(-1)) // non-nil return? + lua.SetField(2, name); // _LOADED[name] = returned value + lua.GetField(2, name); + if (lua.IsNil(-1)) // module did not set a value? + { + lua.PushBoolean(true); // use true as result + lua.PushValue(-1); // extra copy to be returned + lua.SetField(2, name); // _LOADED[name] = true + } + return 1; + } + + private static int PKG_LoadLib(ILuaState lua) + { + // TODO + return 0; + } + + private static int PKG_SearchPath(ILuaState lua) + { + // TODO + return 0; + } + + private static int PKG_SeeAll(ILuaState lua) + { + // TODO + return 0; + } + } } diff --git a/Assets/UniLua/LuaPkgLib.cs.meta b/Assets/UniLua/LuaPkgLib.cs.meta deleted file mode 100644 index 7fee2ba..0000000 --- a/Assets/UniLua/LuaPkgLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d9f1755cddbf50e48ad22b296c264120 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaState.cs.meta b/Assets/UniLua/LuaState.cs.meta deleted file mode 100644 index ca866aa..0000000 --- a/Assets/UniLua/LuaState.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 1c63eb0eb050e4948888f3809ce53282 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaStrLib.cs.meta b/Assets/UniLua/LuaStrLib.cs.meta deleted file mode 100644 index 5468daf..0000000 --- a/Assets/UniLua/LuaStrLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9a860e99012fc6248a195d4bb3d21633 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaTable.cs.meta b/Assets/UniLua/LuaTable.cs.meta deleted file mode 100644 index 5e72431..0000000 --- a/Assets/UniLua/LuaTable.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b7b1a57e7e952fb46949f8d4f30a5f0a -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/LuaTableLib.cs.meta b/Assets/UniLua/LuaTableLib.cs.meta deleted file mode 100644 index 6bf2677..0000000 --- a/Assets/UniLua/LuaTableLib.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0b12a1a7066645d46ad25f806f46193f -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/OpCodes.cs.meta b/Assets/UniLua/OpCodes.cs.meta deleted file mode 100644 index 18923b0..0000000 --- a/Assets/UniLua/OpCodes.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3517c557a5fdcaf428f57095b160831f -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/Parser.cs.meta b/Assets/UniLua/Parser.cs.meta deleted file mode 100644 index 3e2bf66..0000000 --- a/Assets/UniLua/Parser.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4032eb37fa4604040bee1551ed64503e -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/TagMethod.cs.meta b/Assets/UniLua/TagMethod.cs.meta deleted file mode 100644 index c5c45c9..0000000 --- a/Assets/UniLua/TagMethod.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 863cac417f8859740be8c9e0bfc8b65d -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/ULDebug.cs b/Assets/UniLua/ULDebug.cs index 5bf0f9c..86e3bcd 100644 --- a/Assets/UniLua/ULDebug.cs +++ b/Assets/UniLua/ULDebug.cs @@ -1,27 +1,36 @@  -#define UNITY +using Serilog; namespace UniLua.Tools { - // using Logger = DebugAssist; - using Logger = UnityEngine.Debug; + // using Logger = DebugAssist; + // using Logger = UnityEngine.Debug; - // thanks to dharco - // refer to https://github.com/dharco/UniLua/commit/2854ddf2500ab2f943f01a6d3c9af767c092ce75 - public class ULDebug - { - public static System.Action Log = NoAction; - public static System.Action LogError = NoAction; + // thanks to dharco + // refer to https://github.com/dharco/UniLua/commit/2854ddf2500ab2f943f01a6d3c9af767c092ce75 + public class ULDebug + { + public static System.Action Log = NoAction; + public static System.Action LogError = NoAction; - private static void NoAction(object msg) { } + private static void NoAction(object msg) { } - static ULDebug() - { -#if UNITY - Log = Logger.Log; - LogError = Logger.LogError; -#endif - } - } + static ULDebug() + { + Serilog.Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Debug() + .CreateLogger(); + Log = (ob) => + { + Serilog.Log.Information("LUA:" + (String)ob); + }; + LogError = (ob) => + { + Serilog.Log.Error("LUA:" + (String)ob); + }; + + } + } } diff --git a/Assets/UniLua/ULDebug.cs.meta b/Assets/UniLua/ULDebug.cs.meta deleted file mode 100644 index 13e1878..0000000 --- a/Assets/UniLua/ULDebug.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 1821463dbab7c5b458d1c7ccbe39259a -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/Undump.cs.meta b/Assets/UniLua/Undump.cs.meta deleted file mode 100644 index 166f130..0000000 --- a/Assets/UniLua/Undump.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 889bfc952bfafdf4e9b02ca797df96e3 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/UniLuaX.csproj b/Assets/UniLua/UniLuaX.csproj new file mode 100644 index 0000000..dde8c03 --- /dev/null +++ b/Assets/UniLua/UniLuaX.csproj @@ -0,0 +1,17 @@ + + + + net7.0-windows + enable + enable + + + + + + + + + + + diff --git a/Assets/UniLua/Util.cs.meta b/Assets/UniLua/Util.cs.meta deleted file mode 100644 index 77be9fe..0000000 --- a/Assets/UniLua/Util.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e8e03e8ba75219a4b9ed5f669f6bc86b -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UniLua/VM.cs.meta b/Assets/UniLua/VM.cs.meta deleted file mode 100644 index 287ddc4..0000000 --- a/Assets/UniLua/VM.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e93ace87c0c51dd448bc307c176c8c33 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset deleted file mode 100644 index a12158747c95d064eb349ed8d76430c914b51b1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4124 zcmeH~&rZWI48}eFBQ87uhd#lCn07{tYJ$TwLm?nPk{3a063*g31BjwjxX&LzWcr((f*9$CYstWbfZ_;!Ax%uxFw5S ztYeC&`zB1TVEwXueZwl;)duHIuQqT%#cbr9*VcI*$p7qJT;pKdqcUr-oTPQKJ$mQ7 zwS}s*OWyrd{vF5LJW{oYW@(j=jTr{>9a#BnUMF+u+ty)M%ykufH<%B(O4>E6^tuwQ zjxH2*fPSa0g*WLoN2%pcPu=kIO7$>{)?%mXkK|=qtljx}pT99>=FcG#0zyCt2mv7= e1cZPP5CTF#2nYco@IM0EYXFMv*DdG#_x%IZE=1D+ diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset deleted file mode 100644 index 91f99d330d11e0638bfe4a947790007c5c1ccf2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4280 zcmeHK&2AGh5S~(gO8F_!6B36?oVZkosNzyZ>5tMzB4R~KPe|2t<0MAzy0V=p+Y_(R zz6O_G5f9NTFTs^CW3M4;bK%6rBYExde4lsxjeRh{;#YttmjG~|dg=gb>l^E@dmHd; zGMOxp|CU-dD6PzG8w>0U1KVf?PKViC~ayzqU;$QNms%{g509U=3z@~ut?*c(&%99mtvnS#(5m#rH}LP*lxzp zeEd!b&&0FLna!}-HacM>syd~$D|$FoE>6J`QSZ*sL%N-~^`=y!wd;R#Zwj}-M6y4) z4Beo@RUw~F#D(pg9Bu1ik&ASN|L6 zt)f3vXl6)UO}2TzXybSug$u_vmm-Ty6v7#FQWs5a$U{{n_$csZh_Y}ben+d3FfFQv z=k1Ud&hP2*9LllQiZ~yz%+Wf#FWrHWeLAz&ue>r%X#{8Fj~|iVVJXaxR!UmRkBV*N z*q`!nFT$pHW8Aik!Ls`DO?X<($2gzfs?1iN37_yYnq!L?9#^-eiw-?zl_$xjG1q;* zu6!%GB})n<1(E_ufuulEASsX(ND3qck^=vx!1tdozFlK9F3z9VUwvAs1N>+#U%lMq P2QR-$)~NA|=YQI7b}BLx diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset deleted file mode 100644 index 886ae3864c2a87d5da4c603e33fe29dfe2fca68a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4176 zcmeHK%TB{E5Zv&F6BllLLs|h6*S3h)0f7{8MozM{Mu}6|E>bz=NBI@PuH8T-`UmVv z@p|pq8E1SlK=KK2`~(1plqmsRq{DRhdI?`$*CkY+>;PPs+BbHx&{dhC_u5PyOq4?) zOc%On*y2eW^Ygv&=VwsAJmzm$_&Z(VO{J)d$beZnIQR2+LN%5evH}gdKpY5rOdGLd zYt<6s$l}}UJcQw%EQ&k*fkBToIeIOg2N@`pS3zo**C+y{jWl`FRDee16_#ORFF;nH zQ7oLd@G3kRVJ1;a zkiwmVNAf;1{{7h(18hA2oD2crkXmX0E`nard%c9OvMf6^{-6>j3ayJIqB7GAZbc@6 zmP__$+u~{kuuIMO-eCV6(wE1{n~ZU&5;@Rt2)JvbE1H{W=-3T^quQkTU2Yx)KXS5SPENHMm!S^5`m(c z<&&^AJ(NLG8A+#vR!f1Tab%M^<6iB)ITR0T|7SUgWSl#NMVRKg3JZ;xXqi-6_FE!1 zNZNvjHp8*g6_A5w@Mk*^y4lS!{sMB;$g{qe-$0IAJb0=Jh~E)E7cSmB0Z+ga@B};o zPrwuK1Uvyxz!UHU{uu%O`i&%t(}B`5`w@3W-5KKis@q*G7C~AhHWkVQu}!;aF%_u{ Lazmfmegg0f3=fJf diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset deleted file mode 100644 index 3c811f37f662ff9bb246d5abaa98560bb2f2aa11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4112 zcmeH~%}&EG497jbIk6|;5r!B$BBUWS=!r_z&QaDH8q{_uNrCcoJQ>AK8>t5#!Im87 z<8M3q|TkI15OQms}S zQ(^KDDxM6opo`kEYpqi4%Tagwk1p1adHe#*n?3Ha1}?%l3>MwKwK=-0wlTg_yVg|n pDhj{6)f1geg@6zc0zyCt2mv7=1cZPP5CTF#2uuj@Ka-vRr+>TY%4$){rG%-#@XNWFKLo_ovJ2|yAOTPz$!H8^M zkiV6%-4UxSWDOqE0!ui_!2!@HK+!(YF=;-ogkolzTHoGpZgWp8`*pq)utq{BKuI#(C20~7`(ZTzWosxa%SHESQkD{nlhsLB0ugPMq z2cGglsG?X>M5?FG6EF7L!te4!VP`EkVfBc;Ny5Kx8);|-P* zcu{*PHHYAy!L)smS zr(D|I5=18L!_lnWvm9K~?i*RK4rw)ur(D{D62w*zF+q)(b$!uOhtER`Md^0Zs5)nL z1$pFzBs^5h!jL^KL2gD-KuO5jD%($72tVxdSSZX>8zZNW;)jAnudNTvXSz>;jb;EC z&P$x8&mDm6sJGT>DaeZw2)fLYKz&>uxj0PBfr7rOR2ir;P-URXK$U?i162m94E(PQ z;MRmoqXg9=_z0=lw@*{-e-Iexle9*Dv$NZ(jWq-IcLubtsv5}A4cq{58yf!6k{Y9;@ zznFRHn&F%-3_!c$ly@NvWqgP}oNoqBRypMJS}JWBA0oT?kgs>0mdsREpgCzXk7r%7 z=H@`GRh5g+Ighf&uY-fv=(nF`=KrP4CD&*B8xE{79e>@6qafI5a&Dee&biRAxy)xF zd{5Z$L%D=%>rJ-9Ys05RhDUwlNn;%089ucfkC~fm?-Zt@nqPk|ydm0ui-wsG>Sg-` z{l#+VFN4G1XfSKIxG#`*c{xku2HdG_s&5}^H)Oo-HDfr7`=X39A9pxsac`7y=Ht3K N%l1bZUp}Ur?+n!5XT!)F`$Audw^L%xZ?<>TM!YDpaNpX;cgEW_U>?Z4?Rq4&N(aQoO8}O z=bZI-{|3+MF!KIVYj(C`RLur^(9F<+Qo8P3yX0zVWznp19h%d_Fg8@} zOR|dU(96@a>$+JaI?Fv-O||z_Yo^E`KwPLw-8EJ0DAnfmEw^V{51^qgj`GYza`lde6uFYO&JrS=kD*Lf6LDjM49z ze^$1kx!lEof_!ak3w1QBN281F?Bwc7dY8G_9uOD$E_MJY#fANx> z>;+JYix%^Ju{UIeT#RIl5X{9aKwRj%m<>>hiwVZX9LNf}Fh3=TGwZM0 zE$=T5cgKy7g4|ymL5v=`GaWbf7jyL#4J4S0d6uw?ak1BX&Ic&P#YE%cNXQDgSil&) zQtsj?n#PIZ+kxH_~Niu8)`VFLo zWPHmQNyc}?#AJLAbz~Vo2n3VyBOosHW&8wCk__8{{tRg$8NV<_lJP4sF&V!>9a+Zj z0>Nbb0f-BI8Gizl%g|H#3U$1ScJxnR{SwC@nw?VY%zDfE`9!^KE&4l{UbA~@O$)N} nvTRYA9(&c>Xv+LYi5b0J`e92!b9U6*2Ie7g|HoR!fA{bYiByYl diff --git a/ProjectSettings/NetworkManager.asset b/ProjectSettings/NetworkManager.asset deleted file mode 100644 index 5fcd9cee4634740301544f4fdb7e1b70f1bc6701..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4112 zcmeH_+e!m55J1OzzxUCvD7B?;B2-Fi!OKGJlSoOsvvqYZB}o+&2B7u{P_F~PF7?y_v>Tm9Gw8rqmSt-+|Dbk*`Zbl$*CG*flyD&w0&Qo^ zb1=uTL2W!tbh`!d5*UgRxi;)>R7iUFt~;#ME4uug6iG&V5%(@s@wNq|M4cUu0xUQsKKj zbBoqEiab1Ch){wrw15+uZSxXEL2#DAc-Vs=lu8@ZI|legO71w#ee=Q8NB_k{k%=d{ zVuPJpY|m0Z2Uf9`#rFTe+7>%lfq9;mX9E$V{jcYsaF!-Ma2F z!tpeh8&5o;A9L<_1;I0MdrGvEw31I~am@LvOqE|cHZ C(`r-z diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset deleted file mode 100644 index 6bd756baf3277a1c74d581249048d3d36da0a64e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4260 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 diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset deleted file mode 100644 index a5a166fe3cdf70056395c3b03d06add579ce9fb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4544 zcmeHK%W~5&6jgYX@}|7sls9Y&L#A73l1?czooQ$aEE(07TQRbgk>!%I>aq)dpse_m zen46AKZJWF*-<=hzQA|J(ZfgQ9v?}LMaa}&LS_yKA*Tts1O*|@x%s)*(LDJ#91a`M zeg)UZj0&!IdQ5AcY^J15Q%2za5C>qK#GhS4PC)VLL!z5+Nc?qm;~NX~G7s63pfCz= zA|nQtd7UR3(49;vmS~sCfR7od15VqFqC3R?A|_X1vI7Q_ z^sMBR|6nGuc^v3B7?*fF9|@_Z#)2uA(})GW8EB_kflnl%v9;-x!{j-!EbGEF*l(`o zYF#i%CJe^u3bv@SYOwcA1p@u;^8phpd~-{8WCm??;jD)xjt#Nt77gWhJ74D}V%AtH zMW(q-4B`2S;I5Lm9&+%7iQo=R0~#_b;$j6f5|ZXp7kR2_64<%3t9X3w@ToQgOTsS< zEwHROQ5a~O|M;2>bf%cU5HBMHq70=8Po-9}&x3V4%2Hpk@Cv-%Ms;0=3W8(lC_^*Xm9km0s z1GNLS1GNLS1GNLS17!#B%#3GPJfkkrR5SSO^JDa7)o+dJK7x>6`}=S69z50{Pu|9I zH12oHoRj^VuKwrnu;4&FJs$T3^T+!25f5_v(QG!~>8*1#7g+#U G5&r=kmS8Oa diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset deleted file mode 100644 index e9fd2c10e2fa9bf1a9f1e28e95fd3ebcc398861c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5416 zcmb`LYf~IW6owlWNsJPRVB$4P)R-#*8whya5G10YkxPi?BJDD4Hoy>P2NX03(Rlf3 z{wndDK08%s;61hT!LDk0ru*5qAG+AX)Hv7knRC5ooO6er>sg}FmHUVL%PVE~@7~^C z8{L0Jecsn*eC%sc;>LX=a>{BXOy(H3AdXXg-X8%XlS8{I-*y zobya`J!ANOZYoa8L#|QZiQIE^|15QGfjK1CjWnspHMi_jANFF7Tb9G){=M3p>%7+X zxpQc*=V^^wV48bX@A*V_;@OU{o+p|%unH{dSa;27*{KBLsHs%E$JL(do;E zGbzCb`lU!Y$S-46mE(25!32#?3BvEVs8Tiid_z3?t%8f#IbyhF9AD>)*m<6!rip`AW5Mcz zpnszTEOw@5^Kht3j#w0}8gZ28qdjMN4Z)6l`gITtMp+m4mfD1q9HNN?%d1 zrFDfE-YRtZ0D8?tOv=Fr`+wU)1 zQ$&Q5;<18H>kC@rmT`QYFA!hy6g5o%EvfO-!Uotntr-<&Y4Ni;H@#_I>uUjW1kjQq ze_g?r);DT9OKVo;uo}0#)|^bX(vm7auV71Sftc(REUgw7=|EvfQL3bwR7F}zji75q*7LFHhrDjS)TAKy5wp0$*`Uwy~ORD_O3bwSi3ux`A9IW*V zAb^%s`Ck=mX+12U^+@Glt;c{ks8yCKzpG$N>j^QuRp=F5w|-MOSnGE{04=HVPZexw z{XtACtv^)`*7^$&Je4K$^*_}4StNTN;W=(uVh3GML@R!CEp_}xX+H6BO%W5_uvYUvBXz5+-^g!OmxRV$V@dCmO z3^T+2^Vkn4Gyuy2P&3g4pxf%T+HMceBuNUUt{7kXTFyiuJbA!aMDi^qIY1(^vhme4 zh`Sx=^?b9F+j!zT(pJKY(#Kp#G0$BUiWs(kmQItlM6ukb;v$VSmI|v`o{4AT?CYa$ zj+6>d-)*H#`J+v*Y5rm>luQ@Uxn!RU@;bkch|vGZ*_Z$mU;<2l2`~XBzyz286JP>N TfC>CFf%@axzu#^H;4*vx5+X8D From 967e46d250de5f7c9210e8a6a41fe8310d6058b7 Mon Sep 17 00:00:00 2001 From: kmsmg Date: Sat, 22 Jun 2024 11:02:16 +0800 Subject: [PATCH 02/11] add editor --- .gitignore | 3 +- .vs/UniLuaX/v17/DocumentLayout.json | 90 ++++++++++--------- UniLuaEditor/App.xaml | 9 ++ UniLuaEditor/App.xaml.cs | 22 +++++ UniLuaEditor/UniLuaEditor.csproj | 10 +++ .../ViewModels/MainWindowViewModel.cs | 19 ++++ UniLuaEditor/Views/MainWindow.xaml | 10 +++ UniLuaEditor/Views/MainWindow.xaml.cs | 15 ++++ UniLuaX.sln | 31 +++++++ 9 files changed, 167 insertions(+), 42 deletions(-) create mode 100644 UniLuaEditor/App.xaml create mode 100644 UniLuaEditor/App.xaml.cs create mode 100644 UniLuaEditor/UniLuaEditor.csproj create mode 100644 UniLuaEditor/ViewModels/MainWindowViewModel.cs create mode 100644 UniLuaEditor/Views/MainWindow.xaml create mode 100644 UniLuaEditor/Views/MainWindow.xaml.cs create mode 100644 UniLuaX.sln diff --git a/.gitignore b/.gitignore index a169ee8..03d417a 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ x64/ *.vspscc *.vssscc .builds - +*.vs # Visual C++ cache files ipch/ *.aps @@ -115,6 +115,5 @@ UpgradeLog*.XML /Assembly-CSharp.pidb /Assembly-CSharp-Editor-vs.csproj /Assembly-CSharp-Editor.csproj -/*.sln /*.userprefs /Temp diff --git a/.vs/UniLuaX/v17/DocumentLayout.json b/.vs/UniLuaX/v17/DocumentLayout.json index f7bfeda..dceb7c5 100644 --- a/.vs/UniLuaX/v17/DocumentLayout.json +++ b/.vs/UniLuaX/v17/DocumentLayout.json @@ -2,6 +2,10 @@ "Version": 1, "WorkspaceRootPath": "H:\\project2\\UniLua\\", "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\uniluaeditor.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\uniluaeditor.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, { "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luaauxlib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luaauxlib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -19,16 +23,16 @@ "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\vm.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|solutionrelative:assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|solutionrelative:assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|UniLuaX.csproj|solutionrelative:assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" } ], "DocumentGroupContainers": [ @@ -38,7 +42,7 @@ "DocumentGroups": [ { "DockedWidth": 200, - "SelectedChildIndex": 11, + "SelectedChildIndex": 8, "Children": [ { "$type": "Bookmark", @@ -74,20 +78,32 @@ }, { "$type": "Document", - "DocumentIndex": 2, - "Title": "LuaAPI.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAPI.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", - "RelativeToolTip": "Assets\\UniLua\\LuaAPI.cs", - "ViewState": "AQIAAEYCAAAAAAAAAAAlwFQCAAAlAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T02:03:44.522Z", + "DocumentIndex": 0, + "Title": "UniLuaEditor", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\UniLuaEditor.csproj", + "RelativeDocumentMoniker": "UniLuaEditor\\UniLuaEditor.csproj", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\UniLuaEditor.csproj", + "RelativeToolTip": "UniLuaEditor\\UniLuaEditor.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-06-22T02:59:38.97Z", "EditorCaption": "" }, { "$type": "Document", "DocumentIndex": 1, + "Title": "LuaAuxLib.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAuxLib.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", + "RelativeToolTip": "Assets\\UniLua\\LuaAuxLib.cs", + "ViewState": "AQIAACsCAAAAAAAAAAAtwDECAAARAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T01:53:02.58Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, "Title": "LuaDebug.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaDebug.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\LuaDebug.cs", @@ -95,12 +111,23 @@ "RelativeToolTip": "Assets\\UniLua\\LuaDebug.cs", "ViewState": "AQIAANYBAAAAAAAAAAAlwOQBAAAPAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T02:03:35.091Z", - "EditorCaption": "" + "WhenOpened": "2024-06-22T02:03:35.091Z" }, { "$type": "Document", "DocumentIndex": 3, + "Title": "LuaAPI.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", + "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAPI.cs", + "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", + "RelativeToolTip": "Assets\\UniLua\\LuaAPI.cs", + "ViewState": "AQIAAEYCAAAAAAAAAAAlwFQCAAAlAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T02:03:44.522Z" + }, + { + "$type": "Document", + "DocumentIndex": 4, "Title": "VM.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\VM.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\VM.cs", @@ -108,21 +135,7 @@ "RelativeToolTip": "Assets\\UniLua\\VM.cs", "ViewState": "AQIAAJICAAAAAAAAAAAlwKACAAAHAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T02:03:09.098Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 0, - "Title": "LuaAuxLib.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAuxLib.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", - "RelativeToolTip": "Assets\\UniLua\\LuaAuxLib.cs", - "ViewState": "AQIAACsCAAAAAAAAAADgvzECAAARAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:53:02.58Z", - "EditorCaption": "" + "WhenOpened": "2024-06-22T02:03:09.098Z" }, { "$type": "Document", @@ -134,8 +147,7 @@ "RelativeToolTip": "Assets\\UniLua\\ULDebug.cs", "ViewState": "AQIAAAkAAAAAAAAAAAAAABYAAAAqAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:43:36.299Z", - "EditorCaption": "" + "WhenOpened": "2024-06-22T01:43:36.299Z" }, { "$type": "Document", @@ -147,12 +159,11 @@ "RelativeToolTip": "Assets\\UniLua\\LuaPkgLib.cs", "ViewState": "AQIAAK4AAAAAAAAAAIAywL8AAAAJAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:42:42.258Z", - "EditorCaption": "" + "WhenOpened": "2024-06-22T01:42:42.258Z" }, { "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 7, "Title": "LuaFile.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaFile.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\LuaFile.cs", @@ -160,8 +171,7 @@ "RelativeToolTip": "Assets\\UniLua\\LuaFile.cs", "ViewState": "AQIAAAAAAAAAAAAAAAAAAA0AAAA1AAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:40:33.009Z", - "EditorCaption": "" + "WhenOpened": "2024-06-22T01:40:33.009Z" } ] }, diff --git a/UniLuaEditor/App.xaml b/UniLuaEditor/App.xaml new file mode 100644 index 0000000..c46fc1a --- /dev/null +++ b/UniLuaEditor/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/UniLuaEditor/App.xaml.cs b/UniLuaEditor/App.xaml.cs new file mode 100644 index 0000000..837ca5a --- /dev/null +++ b/UniLuaEditor/App.xaml.cs @@ -0,0 +1,22 @@ +using Prism.Ioc; +using System.Windows; +using UniLuaEditor.Views; + +namespace UniLuaEditor +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App + { + protected override Window CreateShell() + { + return Container.Resolve(); + } + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + + } + } +} diff --git a/UniLuaEditor/UniLuaEditor.csproj b/UniLuaEditor/UniLuaEditor.csproj new file mode 100644 index 0000000..fcc569e --- /dev/null +++ b/UniLuaEditor/UniLuaEditor.csproj @@ -0,0 +1,10 @@ + + + WinExe + net7.0-windows7.0 + true + + + + + \ No newline at end of file diff --git a/UniLuaEditor/ViewModels/MainWindowViewModel.cs b/UniLuaEditor/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..9708f40 --- /dev/null +++ b/UniLuaEditor/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,19 @@ +using Prism.Mvvm; + +namespace UniLuaEditor.ViewModels +{ + public class MainWindowViewModel : BindableBase + { + private string _title = "Prism Application"; + public string Title + { + get { return _title; } + set { SetProperty(ref _title, value); } + } + + public MainWindowViewModel() + { + + } + } +} diff --git a/UniLuaEditor/Views/MainWindow.xaml b/UniLuaEditor/Views/MainWindow.xaml new file mode 100644 index 0000000..c8cf46b --- /dev/null +++ b/UniLuaEditor/Views/MainWindow.xaml @@ -0,0 +1,10 @@ + + + + + diff --git a/UniLuaEditor/Views/MainWindow.xaml.cs b/UniLuaEditor/Views/MainWindow.xaml.cs new file mode 100644 index 0000000..fc1738d --- /dev/null +++ b/UniLuaEditor/Views/MainWindow.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows; + +namespace UniLuaEditor.Views +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} diff --git a/UniLuaX.sln b/UniLuaX.sln new file mode 100644 index 0000000..7dbc96d --- /dev/null +++ b/UniLuaX.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34723.18 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniLuaX", "Assets\UniLua\UniLuaX.csproj", "{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniLuaEditor", "UniLuaEditor\UniLuaEditor.csproj", "{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Release|Any CPU.Build.0 = Release|Any CPU + {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {98377CCA-9177-45BB-AD4B-11980229EED9} + EndGlobalSection +EndGlobal From 5678c4f6dc2a7af720e619d13b92d22ed0b81487 Mon Sep 17 00:00:00 2001 From: kmshenyong <122504341+kmshenyong@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:10:44 +0800 Subject: [PATCH 03/11] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原因 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 8b945c8..ca0d90b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +# 不使用Unity3D # +在不使用Unity3D 的环境下对UniLua 的一些调整 + # UniLua # A pure C# implementation of Lua 5.2 focus on compatibility with Unity3D. From 5531a0e3f531a1fcba2cfce28089af493fbe5fba Mon Sep 17 00:00:00 2001 From: kmshenyong <122504341+kmshenyong@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:11:51 +0800 Subject: [PATCH 04/11] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ca0d90b..4b09e60 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # 不使用Unity3D # 在不使用Unity3D 的环境下对UniLua 的一些调整 +2024.6.22 # UniLua # From aff9c59df6b81611793afd8c58236f72f5909408 Mon Sep 17 00:00:00 2001 From: kmsmg Date: Sat, 22 Jun 2024 21:08:20 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=8F=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vs/UniLuaX/v17/DocumentLayout.json | 162 +++++-- Assets/UniLua/Class1.cs | 7 - UniLuaEditor/Lua.xshd | 157 +++++++ UniLuaEditor/UniLuaEditor.csproj | 11 + .../ViewModels/MainWindowViewModel.cs | 118 +++++- UniLuaEditor/Views/AvalonEditExtensions.cs | 46 ++ UniLuaEditor/Views/CustomCompletionWindow.cs | 68 +++ UniLuaEditor/Views/LuaCV.cs | 400 ++++++++++++++++++ UniLuaEditor/Views/LuaEditoe.xaml | 13 + UniLuaEditor/Views/LuaEditoe.xaml.cs | 28 ++ UniLuaEditor/Views/MainWindow.xaml | 38 +- UniLuaEditor/Views/MainWindow.xaml.cs | 22 +- UniLuaEditor/WpfExtensions.cs | 195 +++++++++ UniLuaX.sln | 8 +- luaEdiy/AssemblyInfo.cs | 10 + luaEdiy/CustomControl1.cs | 50 +++ luaEdiy/luaEdiy.csproj | 10 + 17 files changed, 1296 insertions(+), 47 deletions(-) delete mode 100644 Assets/UniLua/Class1.cs create mode 100644 UniLuaEditor/Lua.xshd create mode 100644 UniLuaEditor/Views/AvalonEditExtensions.cs create mode 100644 UniLuaEditor/Views/CustomCompletionWindow.cs create mode 100644 UniLuaEditor/Views/LuaCV.cs create mode 100644 UniLuaEditor/Views/LuaEditoe.xaml create mode 100644 UniLuaEditor/Views/LuaEditoe.xaml.cs create mode 100644 UniLuaEditor/WpfExtensions.cs create mode 100644 luaEdiy/AssemblyInfo.cs create mode 100644 luaEdiy/CustomControl1.cs create mode 100644 luaEdiy/luaEdiy.csproj diff --git a/.vs/UniLuaX/v17/DocumentLayout.json b/.vs/UniLuaX/v17/DocumentLayout.json index dceb7c5..03a99d8 100644 --- a/.vs/UniLuaX/v17/DocumentLayout.json +++ b/.vs/UniLuaX/v17/DocumentLayout.json @@ -2,6 +2,37 @@ "Version": 1, "WorkspaceRootPath": "H:\\project2\\UniLua\\", "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\viewmodels\\mainwindowviewmodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\viewmodels\\mainwindowviewmodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\luacv.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\luacv.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\luaeditoe.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\luaeditoe.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\wpfextensions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\wpfextensions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\customcompletionwindow.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\customcompletionwindow.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\kmsmg\\.nuget\\packages\\prism.wpf\\8.1.97\\readme.txt||{8B382828-6202-11D1-8870-0000F87579D2}" + }, { "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\uniluaeditor.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\uniluaeditor.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" @@ -41,56 +72,112 @@ "VerticalTabListWidth": 256, "DocumentGroups": [ { - "DockedWidth": 200, - "SelectedChildIndex": 8, + "DockedWidth": 75, + "SelectedChildIndex": 1, "Children": [ { "$type": "Bookmark", - "Name": "ST:0:0:{004be353-6879-467c-9d1e-9ac23cdf6d49}" + "Name": "ST:0:0:{cf577b8c-4134-11d2-83e5-00c04f9902c1}" }, { - "$type": "Bookmark", - "Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}" + "$type": "Document", + "DocumentIndex": 1, + "Title": "MainWindowViewModel.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\ViewModels\\MainWindowViewModel.cs", + "RelativeDocumentMoniker": "UniLuaEditor\\ViewModels\\MainWindowViewModel.cs", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\ViewModels\\MainWindowViewModel.cs", + "RelativeToolTip": "UniLuaEditor\\ViewModels\\MainWindowViewModel.cs", + "ViewState": "AQIAACYAAAAAAAAAAAAowFMAAAAKAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T12:36:40.126Z", + "EditorCaption": "" }, { - "$type": "Bookmark", - "Name": "ST:0:0:{34e76e81-ee4a-11d0-ae2e-00a0c90fffc3}" + "$type": "Document", + "DocumentIndex": 4, + "Title": "App.xaml.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\App.xaml.cs", + "RelativeDocumentMoniker": "UniLuaEditor\\App.xaml.cs", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\App.xaml.cs", + "RelativeToolTip": "UniLuaEditor\\App.xaml.cs", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T03:30:40.443Z", + "EditorCaption": "" }, { - "$type": "Bookmark", - "Name": "ST:9:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + "$type": "Document", + "DocumentIndex": 2, + "Title": "LuaCV.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaCV.cs", + "RelativeDocumentMoniker": "UniLuaEditor\\Views\\LuaCV.cs", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaCV.cs", + "RelativeToolTip": "UniLuaEditor\\Views\\LuaCV.cs", + "ViewState": "AQIAAAQAAAAAAAAAAAAwwBEAAAA4AAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T03:22:15.226Z", + "EditorCaption": "" }, { - "$type": "Bookmark", - "Name": "ST:10:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + "$type": "Document", + "DocumentIndex": 6, + "Title": "CustomCompletionWindow.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\CustomCompletionWindow.cs", + "RelativeDocumentMoniker": "UniLuaEditor\\Views\\CustomCompletionWindow.cs", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\CustomCompletionWindow.cs", + "RelativeToolTip": "UniLuaEditor\\Views\\CustomCompletionWindow.cs", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T03:29:53.686Z" }, { - "$type": "Bookmark", - "Name": "ST:0:0:{a80febb4-e7e0-4147-b476-21aaf2453969}" + "$type": "Document", + "DocumentIndex": 3, + "Title": "LuaEditoe.xaml", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaEditoe.xaml", + "RelativeDocumentMoniker": "UniLuaEditor\\Views\\LuaEditoe.xaml", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaEditoe.xaml", + "RelativeToolTip": "UniLuaEditor\\Views\\LuaEditoe.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2024-06-22T03:21:10.372Z", + "EditorCaption": "" }, { - "$type": "Bookmark", - "Name": "ST:1:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + "$type": "Document", + "DocumentIndex": 5, + "Title": "WpfExtensions.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\WpfExtensions.cs", + "RelativeDocumentMoniker": "UniLuaEditor\\WpfExtensions.cs", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\WpfExtensions.cs", + "RelativeToolTip": "UniLuaEditor\\WpfExtensions.cs", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-06-22T03:30:03.387Z" }, { - "$type": "Bookmark", - "Name": "ST:0:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + "$type": "Document", + "DocumentIndex": 7, + "Title": "readme.txt", + "DocumentMoniker": "C:\\Users\\kmsmg\\.nuget\\packages\\prism.wpf\\8.1.97\\readme.txt", + "ToolTip": "C:\\Users\\kmsmg\\.nuget\\packages\\prism.wpf\\8.1.97\\readme.txt", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|", + "WhenOpened": "2024-06-22T03:26:29.819Z" }, { "$type": "Document", - "DocumentIndex": 0, + "DocumentIndex": 8, "Title": "UniLuaEditor", "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\UniLuaEditor.csproj", "RelativeDocumentMoniker": "UniLuaEditor\\UniLuaEditor.csproj", "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\UniLuaEditor.csproj", "RelativeToolTip": "UniLuaEditor\\UniLuaEditor.csproj", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", - "WhenOpened": "2024-06-22T02:59:38.97Z", - "EditorCaption": "" + "WhenOpened": "2024-06-22T02:59:38.97Z" }, { "$type": "Document", - "DocumentIndex": 1, + "DocumentIndex": 9, "Title": "LuaAuxLib.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAuxLib.cs", @@ -98,12 +185,11 @@ "RelativeToolTip": "Assets\\UniLua\\LuaAuxLib.cs", "ViewState": "AQIAACsCAAAAAAAAAAAtwDECAAARAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:53:02.58Z", - "EditorCaption": "" + "WhenOpened": "2024-06-22T01:53:02.58Z" }, { "$type": "Document", - "DocumentIndex": 2, + "DocumentIndex": 10, "Title": "LuaDebug.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaDebug.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\LuaDebug.cs", @@ -115,7 +201,7 @@ }, { "$type": "Document", - "DocumentIndex": 3, + "DocumentIndex": 11, "Title": "LuaAPI.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAPI.cs", @@ -127,7 +213,7 @@ }, { "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 12, "Title": "VM.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\VM.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\VM.cs", @@ -139,19 +225,19 @@ }, { "$type": "Document", - "DocumentIndex": 5, + "DocumentIndex": 13, "Title": "ULDebug.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\ULDebug.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\ULDebug.cs", "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\ULDebug.cs", "RelativeToolTip": "Assets\\UniLua\\ULDebug.cs", - "ViewState": "AQIAAAkAAAAAAAAAAAAAABYAAAAqAAAA", + "ViewState": "AQIAAAYAAAAAAAAAAABOwBYAAAAqAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2024-06-22T01:43:36.299Z" }, { "$type": "Document", - "DocumentIndex": 6, + "DocumentIndex": 14, "Title": "LuaPkgLib.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaPkgLib.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\LuaPkgLib.cs", @@ -163,7 +249,7 @@ }, { "$type": "Document", - "DocumentIndex": 7, + "DocumentIndex": 15, "Title": "LuaFile.cs", "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaFile.cs", "RelativeDocumentMoniker": "Assets\\UniLua\\LuaFile.cs", @@ -176,12 +262,20 @@ ] }, { - "DockedWidth": 17, - "SelectedChildIndex": -1, + "DockedWidth": 142, + "SelectedChildIndex": 0, "Children": [ { - "$type": "Bookmark", - "Name": "ST:3:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" + "$type": "Document", + "DocumentIndex": 0, + "Title": "MainWindow.xaml", + "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\MainWindow.xaml", + "RelativeDocumentMoniker": "UniLuaEditor\\Views\\MainWindow.xaml", + "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\MainWindow.xaml", + "RelativeToolTip": "UniLuaEditor\\Views\\MainWindow.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2024-06-22T03:19:30.536Z", + "EditorCaption": "" } ] } diff --git a/Assets/UniLua/Class1.cs b/Assets/UniLua/Class1.cs deleted file mode 100644 index 43a8a1e..0000000 --- a/Assets/UniLua/Class1.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace UniLuaX -{ - public class Class1 - { - - } -} diff --git a/UniLuaEditor/Lua.xshd b/UniLuaEditor/Lua.xshd new file mode 100644 index 0000000..7b0e80b --- /dev/null +++ b/UniLuaEditor/Lua.xshd @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + TODO + FIXME + + + HACK + UNDONE + + + + + + + + --- + + + + + + + + + --\[[=]*\[ + \][=]*] + + + + + -- + + + + " + " + + + + + + + + ' + ' + + + + + + + + \[[=]*\[ + \][=]*] + + + + true + false + + + + and + break + do + else + elseif + end + false + for + function + if + in + local + + not + or + repeat + return + then + true + until + while + using + continue + + + + break + return + + + + local + + + + nil + + + + + \b + [\d\w_]+ # an identifier + (?=\s*\() # followed by ( + + + \b + [\d\w_]+ # an identifier + (?=\s*\") # followed by " + + + \b + [\d\w_]+ # an identifier + (?=\s*\') # followed by ' + + + \b + [\d\w_]+ # an identifier + (?=\s*\{) # followed by { + + + \b + [\d\w_]+ # an identifier + (?=\s*\[) # followed by [ + + + + + \b0[xX][0-9a-fA-F]+ # hex number + | + ( \b\d+(\.[0-9]+)? #number with optional floating point + | \.[0-9]+ #or just starting with floating point + ) + ([eE][+-]?[0-9]+)? # optional exponent + + + + [?,.;()\[\]{}+\-/%*<>^+~!|&]+ + + + + diff --git a/UniLuaEditor/UniLuaEditor.csproj b/UniLuaEditor/UniLuaEditor.csproj index fcc569e..103b4fa 100644 --- a/UniLuaEditor/UniLuaEditor.csproj +++ b/UniLuaEditor/UniLuaEditor.csproj @@ -5,6 +5,17 @@ true + + + + + + + + + + + \ No newline at end of file diff --git a/UniLuaEditor/ViewModels/MainWindowViewModel.cs b/UniLuaEditor/ViewModels/MainWindowViewModel.cs index 9708f40..7235812 100644 --- a/UniLuaEditor/ViewModels/MainWindowViewModel.cs +++ b/UniLuaEditor/ViewModels/MainWindowViewModel.cs @@ -1,19 +1,133 @@ -using Prism.Mvvm; +using ICSharpCode.AvalonEdit.Document; +using Microsoft.Win32; +using Prism.Commands; +using Prism.Mvvm; +using System; +using System.IO; +using System.Threading.Tasks; +using System.Threading; +using System.Windows.Input; +using UniLua; +using static System.Windows.Forms.AxHost; namespace UniLuaEditor.ViewModels { public class MainWindowViewModel : BindableBase { + ILuaState Lua; private string _title = "Prism Application"; public string Title { get { return _title; } set { SetProperty(ref _title, value); } } - + TextDocument code = new TextDocument(); + public TextDocument LuaCode + { + get { return code; } + set { SetProperty(ref code, value); } + } public MainWindowViewModel() { + Lua = new LuaState(); + Lua.L_OpenLibs(); + } + + + public ICommand StartCommand => (new DelegateCommand(() => + { + Lua.L_DoString(LuaCode.Text); + })); + + #region 文件相关命令处理 + public async Task SaveFileAsync(string content, string filePath, CancellationToken cancel = default) + { + // 打开文件 + await using var stream = File.Create(filePath); + await using var writer = new StreamWriter(stream); + await writer.WriteAsync(content); + await writer.FlushAsync(); } + + public async Task OpenFileAsync(string filePath, CancellationToken cancel = default) + { + if (filePath == null) + throw new ArgumentNullException(nameof(filePath)); + + if (!File.Exists(filePath)) + throw new FileNotFoundException(filePath); + + // 打开文件 + await using var stream = File.OpenRead(filePath); + using var reader = new StreamReader(stream); + return await reader.ReadToEndAsync(); + } + #region 保存文件 + /// + /// 保存文件 + /// + public ICommand SaveFileCommand => (new DelegateCommand(async () => + { // 读取默认文件 + var _saveFileDialog = new SaveFileDialog + { + AddExtension = true, + Title = "保存脚本 ", + Filter = "机器人控制命令(.lua)|*.lua", + DefaultExt = "lua", + FilterIndex = 0, + FileName = "新建命令", + }; + + // 让用户选择文件 + if (_saveFileDialog.ShowDialog() != true) return;// 用户放弃 + // 执行存储 + var filePath = _saveFileDialog.FileName; + await SaveFileAsync(LuaCode.Text, filePath); + })); + // }).ObservesCanExecute(() => CanExecuteSaveFileCommand)); + // public bool CanExecuteSaveFileCommand => State == DebugState.Stopped /* todo and file has changed*/; + #endregion + + #region 读取文件 + /// + /// 打开文件 + /// + public ICommand OpenFileCommand => new DelegateCommand(async () => + { + var _openFileDialog = new OpenFileDialog(); + _openFileDialog.DefaultExt = ""; + _openFileDialog.Filter = "机器人控制命令(.lua)|*.lua"; + _openFileDialog.Title = "打开命令"; + if (_openFileDialog.ShowDialog() != true) return; + string filePath = _openFileDialog.FileName; + if (!File.Exists(filePath)) + return; + LuaCode.Text = await OpenFileAsync(filePath); + LuaCode.FileName = filePath; + + }); + // }).ObservesCanExecute(() => CanExecuteOpenFileCommand)); + + // public bool CanExecuteOpenFileCommand => State == DebugState.Stopped; + + #endregion + + #region 新建文件 + + /// + /// 新建文件命令 + /// + public ICommand NewFileCommand => new DelegateCommand(() => + { + LuaCode.FileName = "Untitled"; + LuaCode.Text = ""; + // GCodeEditor.ScrollToHome(); + }); + // }).ObservesCanExecute(() => CanExecuteNewFileCommand)); + + // public bool CanExecuteNewFileCommand => State == DebugState.Stopped; + #endregion + #endregion } } diff --git a/UniLuaEditor/Views/AvalonEditExtensions.cs b/UniLuaEditor/Views/AvalonEditExtensions.cs new file mode 100644 index 0000000..899abca --- /dev/null +++ b/UniLuaEditor/Views/AvalonEditExtensions.cs @@ -0,0 +1,46 @@ +using ICSharpCode.AvalonEdit.CodeCompletion; +using ICSharpCode.AvalonEdit.Document; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace UniLuaEditor.Views +{ + public static class AvalonEditExtensions + { + public static bool IsOpen(this CompletionWindowBase window) => window?.IsVisible == true; + } + public static class CommonEvent + { + public static RoutedEvent Register(string name, RoutingStrategy routing) + where TEventArgs : RoutedEventArgs + { + return EventManager.RegisterRoutedEvent(name, routing, typeof(EventHandler), typeof(TOwner)); + } + } + + public sealed class ToolTipRequestEventArgs : RoutedEventArgs + { + public ToolTipRequestEventArgs() + { + RoutedEvent = CodeTextEditor.ToolTipRequestEvent; + } + + public bool InDocument { get; set; } + + public TextLocation LogicalPosition { get; set; } + + public int Position { get; set; } + + public object ContentToShow { get; set; } + + public void SetToolTip(object content) + { + Handled = true; + ContentToShow = content ?? throw new ArgumentNullException(nameof(content)); + } + } +} diff --git a/UniLuaEditor/Views/CustomCompletionWindow.cs b/UniLuaEditor/Views/CustomCompletionWindow.cs new file mode 100644 index 0000000..2a6ee3a --- /dev/null +++ b/UniLuaEditor/Views/CustomCompletionWindow.cs @@ -0,0 +1,68 @@ +using ICSharpCode.AvalonEdit.CodeCompletion; +using ICSharpCode.AvalonEdit.Editing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows; + +namespace UniLuaEditor.Views +{ + + internal class CustomCompletionWindow : CompletionWindow + { + private bool _isSoftSelectionActive; + private KeyEventArgs _keyDownArgs; + + public CustomCompletionWindow(TextArea textArea) : base(textArea) + { + _isSoftSelectionActive = true; + CompletionList.SelectionChanged += CompletionListOnSelectionChanged; + + Initialize(); + } + + void Initialize() + { + CompletionList.ListBox.BorderThickness = new Thickness(0); + CompletionList.ListBox.PreviewMouseDown += (o, e) => _isSoftSelectionActive = false; + } + + private void CompletionListOnSelectionChanged(object sender, SelectionChangedEventArgs args) + { + if (!UseHardSelection && + _isSoftSelectionActive && _keyDownArgs?.Handled != true + && args.AddedItems?.Count > 0) + { + CompletionList.SelectedItem = null; + } + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (e.Key == Key.Home || e.Key == Key.End) + return; + + _keyDownArgs = e; + + base.OnKeyDown(e); + + SetSoftSelection(e); + } + + private void SetSoftSelection(RoutedEventArgs e) + { + if (e.Handled) + { + _isSoftSelectionActive = false; + } + } + + // ReSharper disable once MemberCanBePrivate.Local + public bool UseHardSelection { get; set; } + } + +} diff --git a/UniLuaEditor/Views/LuaCV.cs b/UniLuaEditor/Views/LuaCV.cs new file mode 100644 index 0000000..3c5a4b8 --- /dev/null +++ b/UniLuaEditor/Views/LuaCV.cs @@ -0,0 +1,400 @@ +using ICSharpCode.AvalonEdit.CodeCompletion; +using ICSharpCode.AvalonEdit; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ICSharpCode.AvalonEdit.Highlighting; +using System.IO; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows; + +namespace UniLuaEditor.Views +{ public class CodeTextEditor : TextEditor + { + private CustomCompletionWindow _completionWindow; + private OverloadInsightWindow _insightWindow; + private ToolTip _toolTip; + + public CodeTextEditor() + { + Options = new TextEditorOptions + { + ConvertTabsToSpaces = true, + AllowScrollBelowDocument = true, + IndentationSize = 4, + EnableEmailHyperlinks = false, + }; + + TextArea.TextView.VisualLinesChanged += OnVisualLinesChanged; + TextArea.TextEntering += OnTextEntering; + TextArea.TextEntered += OnTextEntered; + + var commandBindings = TextArea.CommandBindings; + var deleteLineCommand = commandBindings.OfType().FirstOrDefault(x => + x.Command == AvalonEditCommands.DeleteLine); + if (deleteLineCommand != null) + { + commandBindings.Remove(deleteLineCommand); + } + + var contextMenu = new ContextMenu(); + + contextMenu.SetItems(new[] + { + new MenuItem {Command = ApplicationCommands.Cut}, + new MenuItem {Command = ApplicationCommands.Copy}, + new MenuItem {Command = ApplicationCommands.Paste} + }); + ContextMenu = contextMenu; + + Initialize(); + } + + + public static readonly StyledProperty CompletionBackgroundProperty = CommonProperty.Register( + nameof(CompletionBackground), CreateDefaultCompletionBackground()); + + public bool IsCompletionWindowOpen => _completionWindow?.IsVisible == true; + + public void CloseCompletionWindow() + { + if (_completionWindow != null) + { + _completionWindow.Close(); + _completionWindow = null; + } + } + + public bool IsInsightWindowOpen => _insightWindow?.IsVisible == true; + + public void CloseInsightWindow() + { + if (_insightWindow != null) + { + _insightWindow.Close(); + _insightWindow = null; + } + } + + private static Brush CreateDefaultCompletionBackground() + { + return new SolidColorBrush(Color.FromRgb(240, 240, 240)).AsFrozen(); + } + + public Brush CompletionBackground + { + get => this.GetValue(CompletionBackgroundProperty); + set => this.SetValue(CompletionBackgroundProperty, value); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + + if (e.Key == Key.Space && e.HasModifiers(ModifierKeys.Control)) + { + e.Handled = true; + var mode = e.HasModifiers(ModifierKeys.Shift) + ? TriggerMode.SignatureHelp + : TriggerMode.Completion; + // ReSharper disable once UnusedVariable + // var task = ShowCompletion(mode); + } + } + + private enum TriggerMode + { + Text, + Completion, + SignatureHelp + } + + public static readonly RoutedEvent ToolTipRequestEvent = CommonEvent.Register( + nameof(ToolTipRequest), RoutingStrategy.Bubble); + + public Func AsyncToolTipRequest { get; set; } + + public event EventHandler ToolTipRequest + { + add => AddHandler(ToolTipRequestEvent, value); + remove => RemoveHandler(ToolTipRequestEvent, value); + } + + private void OnVisualLinesChanged(object sender, EventArgs e) + { + _toolTip?.Close(this); + } + + private void OnMouseHoverStopped(object sender, MouseEventArgs e) + { + if (_toolTip != null) + { + _toolTip.Close(this); + e.Handled = true; + } + } + + private async void OnMouseHover(object sender, MouseEventArgs e) + { + TextViewPosition? position; + try + { + position = TextArea.TextView.GetPositionFloor(e.GetPosition(TextArea.TextView) + TextArea.TextView.ScrollOffset); + } + catch (ArgumentOutOfRangeException) + { + // TODO: check why this happens + e.Handled = true; + return; + } + + var args = new ToolTipRequestEventArgs { InDocument = position.HasValue }; + if (!position.HasValue || position.Value.Location.IsEmpty) + { + return; + } + + args.LogicalPosition = position.Value.Location; + args.Position = Document.GetOffset(position.Value.Line, position.Value.Column); + + RaiseEvent(args); + + if (args.ContentToShow == null) + { + var asyncRequest = AsyncToolTipRequest?.Invoke(args); + if (asyncRequest != null) + { + await asyncRequest.ConfigureAwait(true); + } + } + + if (args.ContentToShow == null) + { + return; + } + + if (_toolTip == null) + { + _toolTip = new ToolTip { MaxWidth = 400 }; + InitializeToolTip(); + } + + if (args.ContentToShow is string stringContent) + { + _toolTip.SetContent(this, new TextBlock + { + Text = stringContent, + TextWrapping = TextWrapping.Wrap + }); + } + else + { + _toolTip.SetContent(this, new ContentPresenter + { + Content = args.ContentToShow, + MaxWidth = 400 + }); + } + + e.Handled = true; + _toolTip.Open(this); + + //AfterToolTipOpen(); + } + + #region Open & Save File + + public void OpenFile(string fileName) + { + if (!File.Exists(fileName)) + { + throw new FileNotFoundException(fileName); + } + + _completionWindow?.Close(); + _insightWindow?.Close(); + + Load(fileName); + Document.FileName = fileName; + + SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(fileName)); + } + + public bool SaveFile() + { + if (string.IsNullOrEmpty(Document.FileName)) + { + return false; + } + + Save(Document.FileName); + return true; + } + + #endregion + + #region Code Completion + +// public ICodeEditorCompletionProvider CompletionProvider { get; set; } + + private void OnTextEntered(object sender, TextCompositionEventArgs e) + { + // ReSharper disable once UnusedVariable + // var task = ShowCompletion(TriggerMode.Text); + } + /* + private async Task ShowCompletion(TriggerMode triggerMode) + { + if (CompletionProvider == null) + { + return; + } + + var offset = TextArea.Caret.Offset; + var completionChar = triggerMode == TriggerMode.Text ? Document.GetCharAt(offset - 1) : (char?)null; + var results = await CompletionProvider.GetCompletionData(offset, completionChar, + triggerMode == TriggerMode.SignatureHelp).ConfigureAwait(true); + if (results.OverloadProvider != null) + { + results.OverloadProvider.Refresh(); + + if (_insightWindow != null && _insightWindow.IsOpen()) + { + _insightWindow.Provider = results.OverloadProvider; + } + else + { + _insightWindow = new OverloadInsightWindow(TextArea) + { + Provider = results.OverloadProvider, + //Background = CompletionBackground, + }; + + InitializeInsightWindow(); + + _insightWindow.Closed += (o, args) => _insightWindow = null; + _insightWindow.Show(); + } + + return; + } + + if (_completionWindow?.IsOpen() != true && results.CompletionData != null && results.CompletionData.Any()) + { + _insightWindow?.Close(); + + // Open code completion after the user has pressed dot: + _completionWindow = new CustomCompletionWindow(TextArea) + { + MinWidth = 300, + CloseWhenCaretAtBeginning = triggerMode == TriggerMode.Completion || triggerMode == TriggerMode.Text, + UseHardSelection = results.UseHardSelection, + }; + + InitializeCompletionWindow(); + + if (completionChar != null && char.IsLetterOrDigit(completionChar.Value)) + { + _completionWindow.StartOffset -= 1; + } + + var data = _completionWindow.CompletionList.CompletionData; + ICompletionDataEx selected = null; + foreach (var completion in results.CompletionData) + { + if (completion.IsSelected) + { + selected = completion; + } + + data.Add(completion); + } + + try + { + _completionWindow.CompletionList.SelectedItem = selected; + } + catch (Exception) + { + // TODO-AV: Fix this in AvaloniaEdit + } + + _completionWindow.Closed += (o, args) => + { + _completionWindow = null; + }; + _completionWindow.Show(); + } + } + */ + private void OnTextEntering(object sender, TextCompositionEventArgs args) + { + if (args.Text.Length > 0 && _completionWindow != null) + { + if (!IsCharIdentifier(args.Text[0])) + { + // Whenever no identifier letter is typed while the completion window is open, + // insert the currently selected element. + _completionWindow.CompletionList.RequestInsertion(args); + } + } + + // Do not set e.Handled=true. + // We still want to insert the character that was typed. + } + + /// + /// Checks if a provided char is a well-known identifier + /// + /// The charcater to check + /// true if is a well-known identifier. + private bool IsCharIdentifier(char c) + { + return char.IsLetterOrDigit(c) || c == '_'; + } + + #endregion + + #region Windows implement + + private void Initialize() + { + ShowLineNumbers = true; + + MouseHover += OnMouseHover; + MouseHoverStopped += OnMouseHoverStopped; + + ToolTipService.SetInitialShowDelay(this, 0); + //SearchReplacePanel.Install(this); // todo install it later + } + + private void InitializeToolTip() + { + if (_toolTip != null) + { + _toolTip.Closed += (o, a) => _toolTip = null; + ToolTipService.SetInitialShowDelay(_toolTip, 0); + _toolTip.PlacementTarget = this; // required for property inheritance + } + } + + private void InitializeInsightWindow() + { + if (_insightWindow != null) + _insightWindow.Style = TryFindResource(typeof(InsightWindow)) as Style; + } + + private void InitializeCompletionWindow() + { + if (_completionWindow != null) + _completionWindow.Background = CompletionBackground; + } + + #endregion + } +} + diff --git a/UniLuaEditor/Views/LuaEditoe.xaml b/UniLuaEditor/Views/LuaEditoe.xaml new file mode 100644 index 0000000..331c96f --- /dev/null +++ b/UniLuaEditor/Views/LuaEditoe.xaml @@ -0,0 +1,13 @@ + + + + + + diff --git a/UniLuaEditor/Views/LuaEditoe.xaml.cs b/UniLuaEditor/Views/LuaEditoe.xaml.cs new file mode 100644 index 0000000..e178b96 --- /dev/null +++ b/UniLuaEditor/Views/LuaEditoe.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace UniLuaEditor.Views +{ + /// + /// LuaEditor.xaml 的交互逻辑 + /// + public partial class LuaEditor : UserControl + { + public LuaEditor() + { + InitializeComponent(); + } + } +} diff --git a/UniLuaEditor/Views/MainWindow.xaml b/UniLuaEditor/Views/MainWindow.xaml index c8cf46b..01e9b39 100644 --- a/UniLuaEditor/Views/MainWindow.xaml +++ b/UniLuaEditor/Views/MainWindow.xaml @@ -1,10 +1,44 @@  + Title="{Binding Title}" Height="350" Width="525" + Loaded="Window_Loaded"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UniLuaEditor/Views/MainWindow.xaml.cs b/UniLuaEditor/Views/MainWindow.xaml.cs index fc1738d..ccf7b09 100644 --- a/UniLuaEditor/Views/MainWindow.xaml.cs +++ b/UniLuaEditor/Views/MainWindow.xaml.cs @@ -1,4 +1,7 @@ -using System.Windows; +using ICSharpCode.AvalonEdit.Highlighting.Xshd; +using ICSharpCode.AvalonEdit.Highlighting; +using System.Windows; +using System.Xml; namespace UniLuaEditor.Views { @@ -11,5 +14,22 @@ public MainWindow() { InitializeComponent(); } + private void Window_Loaded(object sender, RoutedEventArgs e) + { + + //设置语法规则 + string name = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Lua.xshd"; + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + using (System.IO.Stream s = assembly.GetManifestResourceStream(name)) + { + using (XmlTextReader reader = new XmlTextReader(s)) + { + var xshd = HighlightingLoader.LoadXshd(reader); + LuaEditor.SyntaxHighlighting = HighlightingLoader.Load(xshd, HighlightingManager.Instance); + } + } + + } + } } diff --git a/UniLuaEditor/WpfExtensions.cs b/UniLuaEditor/WpfExtensions.cs new file mode 100644 index 0000000..c1f3181 --- /dev/null +++ b/UniLuaEditor/WpfExtensions.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Threading; +using System.Windows; + +namespace UniLuaEditor +{ + public static class WpfExtensions + { + public static Window GetWindow(this UIElement o) => Window.GetWindow(o); + + public static Dispatcher GetDispatcher(this DispatcherObject o) => o.Dispatcher; + + public static Size GetRenderSize(this UIElement element) => element.RenderSize; + + public static void HookupLoadedUnloadedAction(this FrameworkElement element, Action action) + { + if (element.IsLoaded) + { + action(true); + } + + element.Loaded += (o, e) => action(true); + element.Unloaded += (o, e) => action(false); + } + + public static void HookupLoadedAction(this FrameworkElement element, Action action) + { + if (element.IsLoaded) + { + action(); + } + + element.Loaded += (o, e) => action(); + } + + public static void HookupUnloadedAction(this FrameworkElement element, Action action) + { + element.Unloaded += (o, e) => action(); + } + + + public static void AttachLocationChanged(this Window topLevel, EventHandler handler) + { + topLevel.LocationChanged += handler; + } + + public static void DetachLocationChanged(this Window topLevel, EventHandler handler) + { + topLevel.LocationChanged -= handler; + } + + public static T AsFrozen(this T freezable) where T : Freezable + { + freezable.Freeze(); + return freezable; + } + + public static void BeginFigure(this StreamGeometryContext context, Point point, bool isFilled) + { + context.BeginFigure(point, isFilled, isClosed: false); + } + + public static void SetBorderThickness(this Control control, double thickness) + { + control.BorderThickness = new Thickness(thickness); + } + + public static bool HasModifiers(this KeyEventArgs args, ModifierKeys modifier) => + (args.KeyboardDevice.Modifiers & modifier) == modifier; + + public static void Open(this ToolTip toolTip, FrameworkElement control) => toolTip.IsOpen = true; + public static void Close(this ToolTip toolTip, FrameworkElement control) => toolTip.IsOpen = false; + public static void SetContent(this ToolTip toolTip, Control control, object content) => toolTip.Content = content; + + public static void SetItems(this ItemsControl itemsControl, System.Collections.IEnumerable enumerable) => + itemsControl.ItemsSource = enumerable; + + public static void Open(this ContextMenu contextMenu, FrameworkElement element) + { + contextMenu.PlacementTarget = element; + contextMenu.IsOpen = true; + } + + public static void Open(this ContextMenu contextMenu) + { + contextMenu.IsOpen = true; + } + + public static void Close(this ContextMenu contextMenu) + { + contextMenu.IsOpen = false; + } + } + public sealed class StyledProperty + { + public DependencyProperty Property { get; } + + public StyledProperty(DependencyProperty property) + { + Property = property; + } + + public StyledProperty AddOwner() => + new StyledProperty(Property.AddOwner(typeof(TOwner))); + + public Type PropertyType => Property.PropertyType; + } + [Flags] + public enum PropertyOptions + { + None, + AffectsRender = 1, + AffectsArrange = 2, + AffectsMeasure = 4, + BindsTwoWay = 8, + Inherits = 16, + } + public class CommonPropertyChangedArgs + { + public T OldValue { get; } + + public T NewValue { get; } + + public CommonPropertyChangedArgs(T oldValue, T newValue) + { + OldValue = oldValue; + NewValue = newValue; + } + } + public static class PropertyExtensions + { + public static bool Has(this PropertyOptions options, PropertyOptions value) => + (options & value) == value; + } + public static class CommonProperty + { + public static StyledProperty Register(string name, + TValue defaultValue = default, PropertyOptions options = PropertyOptions.None, + Action> onChanged = null) + where TOwner : DependencyObject + { + var metadataOptions = FrameworkPropertyMetadataOptions.None; + + if (options.Has(PropertyOptions.AffectsRender)) + { + metadataOptions |= FrameworkPropertyMetadataOptions.AffectsRender; + } + + if (options.Has(PropertyOptions.AffectsArrange)) + { + metadataOptions |= FrameworkPropertyMetadataOptions.AffectsArrange; + } + + if (options.Has(PropertyOptions.AffectsMeasure)) + { + metadataOptions |= FrameworkPropertyMetadataOptions.AffectsMeasure; + } + + if (options.Has(PropertyOptions.Inherits)) + { + metadataOptions |= FrameworkPropertyMetadataOptions.Inherits; + } + + if (options.Has(PropertyOptions.BindsTwoWay)) + { + metadataOptions |= FrameworkPropertyMetadataOptions.BindsTwoWayByDefault; + } + + var changedCallback = onChanged != null + ? new PropertyChangedCallback((o, e) => onChanged((TOwner)o, new CommonPropertyChangedArgs((TValue)e.OldValue, (TValue)e.NewValue))) + : null; + var metadata = new FrameworkPropertyMetadata(defaultValue, metadataOptions, changedCallback); + var property = DependencyProperty.Register(name, typeof(TValue), typeof(TOwner), metadata); + + return new StyledProperty(property); + } + + public static TValue GetValue(this DependencyObject o, StyledProperty property) + { + return (TValue)o.GetValue(property.Property); + } + + public static void SetValue(this DependencyObject o, StyledProperty property, TValue value) + { + o.SetValue(property.Property, value); + } + } +} diff --git a/UniLuaX.sln b/UniLuaX.sln index 7dbc96d..7907d49 100644 --- a/UniLuaX.sln +++ b/UniLuaX.sln @@ -5,7 +5,9 @@ VisualStudioVersion = 17.9.34723.18 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniLuaX", "Assets\UniLua\UniLuaX.csproj", "{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniLuaEditor", "UniLuaEditor\UniLuaEditor.csproj", "{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniLuaEditor", "UniLuaEditor\UniLuaEditor.csproj", "{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "luaEdiy", "luaEdiy\luaEdiy.csproj", "{C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +23,10 @@ Global {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Debug|Any CPU.Build.0 = Debug|Any CPU {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Release|Any CPU.ActiveCfg = Release|Any CPU {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Release|Any CPU.Build.0 = Release|Any CPU + {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/luaEdiy/AssemblyInfo.cs b/luaEdiy/AssemblyInfo.cs new file mode 100644 index 0000000..b0ec827 --- /dev/null +++ b/luaEdiy/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/luaEdiy/CustomControl1.cs b/luaEdiy/CustomControl1.cs new file mode 100644 index 0000000..514254b --- /dev/null +++ b/luaEdiy/CustomControl1.cs @@ -0,0 +1,50 @@ +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace luaEdiy +{ + /// + /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file. + /// + /// Step 1a) Using this custom control in a XAML file that exists in the current project. + /// Add this XmlNamespace attribute to the root element of the markup file where it is + /// to be used: + /// + /// xmlns:MyNamespace="clr-namespace:luaEdiy" + /// + /// + /// Step 1b) Using this custom control in a XAML file that exists in a different project. + /// Add this XmlNamespace attribute to the root element of the markup file where it is + /// to be used: + /// + /// xmlns:MyNamespace="clr-namespace:luaEdiy;assembly=luaEdiy" + /// + /// You will also need to add a project reference from the project where the XAML file lives + /// to this project and Rebuild to avoid compilation errors: + /// + /// Right click on the target project in the Solution Explorer and + /// "Add Reference"->"Projects"->[Select this project] + /// + /// + /// Step 2) + /// Go ahead and use your control in the XAML file. + /// + /// + /// + /// + public class CustomControl1 : Control + { + static CustomControl1() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1))); + } + } +} \ No newline at end of file diff --git a/luaEdiy/luaEdiy.csproj b/luaEdiy/luaEdiy.csproj new file mode 100644 index 0000000..5b33f93 --- /dev/null +++ b/luaEdiy/luaEdiy.csproj @@ -0,0 +1,10 @@ + + + + net7.0-windows + enable + true + enable + + + From 10976a4cc1241f47d7792f0015eb4bdd4696152b Mon Sep 17 00:00:00 2001 From: kmsmg Date: Sat, 22 Jun 2024 21:27:38 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E4=B8=B4=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vs/ProjectEvaluation/uniluax.metadata.v7.bin | Bin 185161 -> 207892 bytes .vs/ProjectEvaluation/uniluax.projects.v7.bin | Bin 106238 -> 421656 bytes .vs/UniLuaX/v17/DocumentLayout.json | 130 +++++++++++++----- .../ViewModels/MainWindowViewModel.cs | 6 + UniLuaEditor/Views/MainWindow.xaml | 4 +- 5 files changed, 104 insertions(+), 36 deletions(-) diff --git a/.vs/ProjectEvaluation/uniluax.metadata.v7.bin b/.vs/ProjectEvaluation/uniluax.metadata.v7.bin index 80a2ddcefa3466cd92153f86abb8d3c3aed1048f..19a1996c9a3a3927da6d0676c4df5152f3d5755b 100644 GIT binary patch delta 12429 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 H%!gP3ZE_;! diff --git a/.vs/ProjectEvaluation/uniluax.projects.v7.bin b/.vs/ProjectEvaluation/uniluax.projects.v7.bin index 5f4a180e0f4a210bc6295faf84e29f45a1292963..b3b03028d3d44ff72099af5950e6d222f7736961 100644 GIT binary patch delta 13620 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 GwEqF*1q0{+ delta 11 TcmbPnPx9YhwuUW?|K OpenFileAsync(string filePath, CancellationToken cance })); // }).ObservesCanExecute(() => CanExecuteSaveFileCommand)); // public bool CanExecuteSaveFileCommand => State == DebugState.Stopped /* todo and file has changed*/; + + public ICommand ExitAppCommand =>(new DelegateCommand (()=> + { + App.Current.Shutdown(0); + Environment.Exit(0); + })); #endregion #region 读取文件 diff --git a/UniLuaEditor/Views/MainWindow.xaml b/UniLuaEditor/Views/MainWindow.xaml index 01e9b39..8fba4a9 100644 --- a/UniLuaEditor/Views/MainWindow.xaml +++ b/UniLuaEditor/Views/MainWindow.xaml @@ -22,7 +22,7 @@ - + - + From dc26d40d1f04ab35ebbdce02ee9a917bb3cc6c7c Mon Sep 17 00:00:00 2001 From: kmsmg Date: Fri, 20 Dec 2024 22:50:38 +0800 Subject: [PATCH 07/11] UI --- .vs/ProjectEvaluation/uniluax.metadata.v7.bin | Bin 207892 -> 0 bytes .vs/ProjectEvaluation/uniluax.projects.v7.bin | Bin 421656 -> 0 bytes .vs/UniLuaX/v17/DocumentLayout.json | 337 +++------ .../ConfigStream.Json.csproj.DotSettings | 2 + ...ration.Persistence.Json.csproj.DotSettings | 2 + .../Configuration.Store.Json.csproj | 40 ++ .../ConfigStream.Json/Documents/Readme.md | 9 + .../ConfigStream.Json/JsonConfigStore.cs | 248 +++++++ .../Properties/AssemblyInfo.cs | 12 + .../ConfigStream.JsonTests.csproj.DotSettings | 2 + ...n.Persistence.JsonTests.csproj.DotSettings | 2 + .../Configuration.Store.JsonTests.csproj | 138 ++++ ...uration.Store.JsonTests.csproj.DotSettings | 2 + .../JsonConfigStreamTests.cs | 50 ++ .../Properties/AssemblyInfo.cs | 36 + .../ConfigStream.JsonTests/packages.config | 5 + .../Config/Configuration/Config.cs | 653 ++++++++++++++++++ .../Config/Configuration/ConfigBase.cs | 284 ++++++++ .../Config/Configuration/ConfigData.cs | 169 +++++ .../Config/Configuration/ConfigDataVisitor.cs | 20 + .../Config/Configuration/ConfigPath.cs | 165 +++++ .../Config/Configuration/ConfigSection.cs | 199 ++++++ .../Config/Configuration/ConfigValue.cs | 119 ++++ .../Config/Configuration/Configuration.csproj | 29 + ...configuration-class-dependencies-graph.png | Bin 0 -> 51853 bytes .../Document/configuration-concept.png | Bin 0 -> 8648 bytes .../Configuration/Helper/AsyncEventHandler.cs | 10 + .../Helper/OneWaiterTaskQueue.cs | 82 +++ .../Config/Configuration/IConfigStore.cs | 47 ++ .../Configuration/IDefaultConfigWriter.cs | 14 + .../PersistencePropertyAttribute.cs | 17 + .../Config/Configuration/README.md | 303 ++++++++ .../Config/Configuration/SaveMethods.cs | 18 + .../Configuration/Store/JsonConfigStore.cs | 245 +++++++ .../Configuration/Store/JsonConfigStore.md | 9 + .../StreamProvider/FileStreamProvider.cs | 109 +++ .../StreamProvider/IStreamProvider.cs | 22 + .../IStreamProviderWithNotification.cs | 16 + .../StreamProvider/MemoryStreamProvider.cs | 57 ++ .../ConfigurationTests/ConfigDataTests.cs | 158 +++++ .../ConfigurationTests.csproj | 173 +++++ .../ConfigurationTests.csproj.DotSettings | 2 + .../OneWaiterTaskQueueTests.cs | 62 ++ .../ConfigurationTests/PermissionTest.cs | 97 +++ .../Properties/AssemblyInfo.cs | 36 + .../StrongNameConfigTest.cs | 35 + .../StrongNameConfigTestSample.cs | 38 + .../Config/ConfigurationTests/app.config | 15 + .../Config/ConfigurationTests/packages.config | 11 + GrinderApp.Core/GrinderApp.Core.csproj | 9 + GrinderApp.Core/Mvvm/RegionViewModelBase.cs | 35 + GrinderApp.Core/Mvvm/ViewModelBase.cs | 18 + GrinderApp.Core/RegionNames.cs | 7 + GrinderApp/GrinderApp.sln | 66 ++ GrinderApp/GrinderApp/App.xaml | 13 + GrinderApp/GrinderApp/App.xaml.cs | 31 + GrinderApp/GrinderApp/GrinderApp.csproj | 17 + .../ViewModels/MainWindowViewModel.cs | 39 ++ GrinderApp/GrinderApp/Views/MainWindow.xaml | 34 + .../GrinderApp/Views/MainWindow.xaml.cs | 164 +++++ .../GrinderApp.Modules.ModuleName.csproj | 20 + .../ModuleNameModule.cs | 28 + .../ViewModels/ViewAViewModel.cs | 27 + .../Views/ViewA.xaml | 13 + .../Views/ViewA.xaml.cs | 28 + .../GrinderApp.Services.Interfaces.csproj | 7 + .../IMessageService.cs | 7 + .../GrinderApp.Services.csproj | 12 + .../GrinderApp.Services/MessageService.cs | 12 + ...GrinderApp.Modules.ModuleName.Tests.csproj | 27 + .../ViewModels/ViewAViewModelFixture.cs | 41 ++ UniLuaX.sln | 26 +- 72 files changed, 4530 insertions(+), 250 deletions(-) delete mode 100644 .vs/ProjectEvaluation/uniluax.metadata.v7.bin delete mode 100644 .vs/ProjectEvaluation/uniluax.projects.v7.bin create mode 100644 Grinder.Infrastructure/Config/ConfigStream.Json/ConfigStream.Json.csproj.DotSettings create mode 100644 Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Persistence.Json.csproj.DotSettings create mode 100644 Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Store.Json.csproj create mode 100644 Grinder.Infrastructure/Config/ConfigStream.Json/Documents/Readme.md create mode 100644 Grinder.Infrastructure/Config/ConfigStream.Json/JsonConfigStore.cs create mode 100644 Grinder.Infrastructure/Config/ConfigStream.Json/Properties/AssemblyInfo.cs create mode 100644 Grinder.Infrastructure/Config/ConfigStream.JsonTests/ConfigStream.JsonTests.csproj.DotSettings create mode 100644 Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Persistence.JsonTests.csproj.DotSettings create mode 100644 Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj create mode 100644 Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj.DotSettings create mode 100644 Grinder.Infrastructure/Config/ConfigStream.JsonTests/JsonConfigStreamTests.cs create mode 100644 Grinder.Infrastructure/Config/ConfigStream.JsonTests/Properties/AssemblyInfo.cs create mode 100644 Grinder.Infrastructure/Config/ConfigStream.JsonTests/packages.config create mode 100644 Grinder.Infrastructure/Config/Configuration/Config.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/ConfigBase.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/ConfigData.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/ConfigPath.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/ConfigSection.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/ConfigValue.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/Configuration.csproj create mode 100644 Grinder.Infrastructure/Config/Configuration/Document/configuration-class-dependencies-graph.png create mode 100644 Grinder.Infrastructure/Config/Configuration/Document/configuration-concept.png create mode 100644 Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/IConfigStore.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/README.md create mode 100644 Grinder.Infrastructure/Config/Configuration/SaveMethods.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.md create mode 100644 Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs create mode 100644 Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/ConfigDataTests.cs create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj.DotSettings create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/OneWaiterTaskQueueTests.cs create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/PermissionTest.cs create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/Properties/AssemblyInfo.cs create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTest.cs create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTestSample.cs create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/app.config create mode 100644 Grinder.Infrastructure/Config/ConfigurationTests/packages.config create mode 100644 GrinderApp.Core/GrinderApp.Core.csproj create mode 100644 GrinderApp.Core/Mvvm/RegionViewModelBase.cs create mode 100644 GrinderApp.Core/Mvvm/ViewModelBase.cs create mode 100644 GrinderApp.Core/RegionNames.cs create mode 100644 GrinderApp/GrinderApp.sln create mode 100644 GrinderApp/GrinderApp/App.xaml create mode 100644 GrinderApp/GrinderApp/App.xaml.cs create mode 100644 GrinderApp/GrinderApp/GrinderApp.csproj create mode 100644 GrinderApp/GrinderApp/ViewModels/MainWindowViewModel.cs create mode 100644 GrinderApp/GrinderApp/Views/MainWindow.xaml create mode 100644 GrinderApp/GrinderApp/Views/MainWindow.xaml.cs create mode 100644 Modules/GrinderApp.Modules.ModuleName/GrinderApp.Modules.ModuleName.csproj create mode 100644 Modules/GrinderApp.Modules.ModuleName/ModuleNameModule.cs create mode 100644 Modules/GrinderApp.Modules.ModuleName/ViewModels/ViewAViewModel.cs create mode 100644 Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml create mode 100644 Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml.cs create mode 100644 Services/GrinderApp.Services.Interfaces/GrinderApp.Services.Interfaces.csproj create mode 100644 Services/GrinderApp.Services.Interfaces/IMessageService.cs create mode 100644 Services/GrinderApp.Services/GrinderApp.Services.csproj create mode 100644 Services/GrinderApp.Services/MessageService.cs create mode 100644 Tests/GrinderApp.Modules.ModuleName.Tests/GrinderApp.Modules.ModuleName.Tests.csproj create mode 100644 Tests/GrinderApp.Modules.ModuleName.Tests/ViewModels/ViewAViewModelFixture.cs diff --git a/.vs/ProjectEvaluation/uniluax.metadata.v7.bin b/.vs/ProjectEvaluation/uniluax.metadata.v7.bin deleted file mode 100644 index 19a1996c9a3a3927da6d0676c4df5152f3d5755b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207892 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 {}I_m~# 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 diff --git a/.vs/UniLuaX/v17/DocumentLayout.json b/.vs/UniLuaX/v17/DocumentLayout.json index b4d454c..8ca89ca 100644 --- a/.vs/UniLuaX/v17/DocumentLayout.json +++ b/.vs/UniLuaX/v17/DocumentLayout.json @@ -3,75 +3,39 @@ "WorkspaceRootPath": "H:\\project2\\UniLua\\", "Documents": [ { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\viewmodels\\mainwindowviewmodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\viewmodels\\mainwindowviewmodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\kmsmg\\AppData\\Local\\Temp\\.vsdbgsrc\\588fd4cd1320d504abfcbd7bb1f0e198f8b5eec657267f804bb540676e7671d3\\ElementUtil.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\mainwindow.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}|GrinderApp\\GrinderApp\\GrinderApp.csproj|h:\\project2\\unilua\\grinderapp\\grinderapp\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}|GrinderApp\\GrinderApp\\GrinderApp.csproj|solutionrelative:grinderapp\\grinderapp\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + "AbsoluteMoniker": "D:0:0:{F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}|GrinderApp\\GrinderApp\\GrinderApp.csproj|h:\\project2\\unilua\\grinderapp\\grinderapp\\grinderapp.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}|GrinderApp\\GrinderApp\\GrinderApp.csproj|solutionrelative:grinderapp\\grinderapp\\grinderapp.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + "AbsoluteMoniker": "D:0:0:{F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}|GrinderApp\\GrinderApp\\GrinderApp.csproj|h:\\project2\\unilua\\grinderapp\\grinderapp\\app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}|GrinderApp\\GrinderApp\\GrinderApp.csproj|solutionrelative:grinderapp\\grinderapp\\app.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\app.xaml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|H:\\project2\\UniLua\\GrinderApp\\Modules\\GrinderApp.Modules.ModuleName\\ModuleNameModule.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:GrinderApp\\Modules\\GrinderApp.Modules.ModuleName\\ModuleNameModule.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\luacv.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\luacv.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|H:\\project2\\UniLua\\GrinderApp\\Services\\GrinderApp.Services\\GrinderApp.Services.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:GrinderApp\\Services\\GrinderApp.Services\\GrinderApp.Services.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\luaeditoe.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\luaeditoe.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|H:\\project2\\UniLua\\GrinderApp\\Services\\GrinderApp.Services.Interfaces\\GrinderApp.Services.Interfaces.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:GrinderApp\\Services\\GrinderApp.Services.Interfaces\\GrinderApp.Services.Interfaces.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\wpfextensions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\wpfextensions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|H:\\project2\\UniLua\\GrinderApp\\Tests\\GrinderApp.Modules.ModuleName.Tests\\GrinderApp.Modules.ModuleName.Tests.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:GrinderApp\\Tests\\GrinderApp.Modules.ModuleName.Tests\\GrinderApp.Modules.ModuleName.Tests.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" }, { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\views\\customcompletionwindow.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\views\\customcompletionwindow.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\kmsmg\\.nuget\\packages\\prism.wpf\\8.1.97\\readme.txt||{8B382828-6202-11D1-8870-0000F87579D2}" - }, - { - "AbsoluteMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|h:\\project2\\unilua\\uniluaeditor\\uniluaeditor.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", - "RelativeMoniker": "D:0:0:{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}|UniLuaEditor\\UniLuaEditor.csproj|solutionrelative:uniluaeditor\\uniluaeditor.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" - }, - { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luaauxlib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luaauxlib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luadebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luadebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luaapi.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luaapi.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\vm.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\vm.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\uldebug.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luapkglib.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|h:\\project2\\unilua\\assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}|Assets\\UniLua\\UniLuaX.csproj|solutionrelative:assets\\unilua\\luafile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|H:\\project2\\UniLua\\GrinderApp\\GrinderApp.Core\\GrinderApp.Core.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:GrinderApp\\GrinderApp.Core\\GrinderApp.Core.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" } ], "DocumentGroupContainers": [ @@ -80,8 +44,8 @@ "VerticalTabListWidth": 256, "DocumentGroups": [ { - "DockedWidth": 211, - "SelectedChildIndex": 9, + "DockedWidth": 247, + "SelectedChildIndex": 8, "Children": [ { "$type": "Bookmark", @@ -103,10 +67,6 @@ "$type": "Bookmark", "Name": "ST:10:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" }, - { - "$type": "Bookmark", - "Name": "ST:0:0:{a80febb4-e7e0-4147-b476-21aaf2453969}" - }, { "$type": "Bookmark", "Name": "ST:1:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" @@ -116,228 +76,137 @@ "Name": "ST:0:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" }, { - "$type": "Document", - "DocumentIndex": 1, - "Title": "MainWindow.xaml.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\MainWindow.xaml.cs", - "RelativeDocumentMoniker": "UniLuaEditor\\Views\\MainWindow.xaml.cs", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\MainWindow.xaml.cs", - "RelativeToolTip": "UniLuaEditor\\Views\\MainWindow.xaml.cs", - "ViewState": "AQIAAAsAAAAAAAAAAAAYwB0AAAANAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T13:10:05.652Z", - "EditorCaption": "" + "$type": "Bookmark", + "Name": "ST:0:0:{cf577b8c-4134-11d2-83e5-00c04f9902c1}" }, { "$type": "Document", "DocumentIndex": 0, - "Title": "MainWindowViewModel.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\ViewModels\\MainWindowViewModel.cs", - "RelativeDocumentMoniker": "UniLuaEditor\\ViewModels\\MainWindowViewModel.cs", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\ViewModels\\MainWindowViewModel.cs*", - "RelativeToolTip": "UniLuaEditor\\ViewModels\\MainWindowViewModel.cs*", - "ViewState": "AQIAAEYAAAAAAAAAAAAowGAAAAAAAAAA", + "Title": "ElementUtil.cs", + "DocumentMoniker": "C:\\Users\\kmsmg\\AppData\\Local\\Temp\\.vsdbgsrc\\588fd4cd1320d504abfcbd7bb1f0e198f8b5eec657267f804bb540676e7671d3\\ElementUtil.cs", + "ToolTip": "C:\\Users\\kmsmg\\AppData\\Local\\Temp\\.vsdbgsrc\\588fd4cd1320d504abfcbd7bb1f0e198f8b5eec657267f804bb540676e7671d3\\ElementUtil.cs", + "ViewState": "AgIAAHQAAAAAAAAAAADgv5sAAAADAAAAAQAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T12:36:40.126Z", + "WhenOpened": "2024-12-19T09:05:27.556Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 3, - "Title": "App.xaml", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\App.xaml", - "RelativeDocumentMoniker": "UniLuaEditor\\App.xaml", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\App.xaml", - "RelativeToolTip": "UniLuaEditor\\App.xaml", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", - "WhenOpened": "2024-06-22T13:10:02.275Z", - "EditorCaption": "" + "DocumentIndex": 2, + "Title": "GrinderApp", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp\\GrinderApp.csproj", + "RelativeDocumentMoniker": "GrinderApp\\GrinderApp\\GrinderApp.csproj", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp\\GrinderApp.csproj", + "RelativeToolTip": "GrinderApp\\GrinderApp\\GrinderApp.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-12-19T08:46:24.809Z" }, { "$type": "Document", "DocumentIndex": 4, - "Title": "App.xaml.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\App.xaml.cs", - "RelativeDocumentMoniker": "UniLuaEditor\\App.xaml.cs", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\App.xaml.cs", - "RelativeToolTip": "UniLuaEditor\\App.xaml.cs", - "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T03:30:40.443Z" - }, - { - "$type": "Document", - "DocumentIndex": 5, - "Title": "LuaCV.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaCV.cs", - "RelativeDocumentMoniker": "UniLuaEditor\\Views\\LuaCV.cs", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaCV.cs", - "RelativeToolTip": "UniLuaEditor\\Views\\LuaCV.cs", - "ViewState": "AQIAAAQAAAAAAAAAAAAwwBEAAAA4AAAA", + "Title": "ModuleNameModule.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\Modules\\GrinderApp.Modules.ModuleName\\ModuleNameModule.cs", + "RelativeDocumentMoniker": "GrinderApp\\Modules\\GrinderApp.Modules.ModuleName\\ModuleNameModule.cs", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\Modules\\GrinderApp.Modules.ModuleName\\ModuleNameModule.cs", + "RelativeToolTip": "GrinderApp\\Modules\\GrinderApp.Modules.ModuleName\\ModuleNameModule.cs", + "ViewState": "AgIAAAYAAAAAAAAAAAAAAAgAAAAhAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T03:22:15.226Z" + "WhenOpened": "2024-12-19T08:39:04.636Z" }, { "$type": "Document", - "DocumentIndex": 8, - "Title": "CustomCompletionWindow.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\CustomCompletionWindow.cs", - "RelativeDocumentMoniker": "UniLuaEditor\\Views\\CustomCompletionWindow.cs", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\CustomCompletionWindow.cs", - "RelativeToolTip": "UniLuaEditor\\Views\\CustomCompletionWindow.cs", - "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "DocumentIndex": 1, + "Title": "App.xaml.cs", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp\\App.xaml.cs", + "RelativeDocumentMoniker": "GrinderApp\\GrinderApp\\App.xaml.cs", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp\\App.xaml.cs", + "RelativeToolTip": "GrinderApp\\GrinderApp\\App.xaml.cs", + "ViewState": "AgIAAA4AAAAAAAAAAAAUwBAAAAAJAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T03:29:53.686Z" + "WhenOpened": "2024-12-19T08:36:28.664Z" }, { "$type": "Document", - "DocumentIndex": 6, - "Title": "LuaEditoe.xaml", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaEditoe.xaml", - "RelativeDocumentMoniker": "UniLuaEditor\\Views\\LuaEditoe.xaml", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\LuaEditoe.xaml", - "RelativeToolTip": "UniLuaEditor\\Views\\LuaEditoe.xaml", + "DocumentIndex": 3, + "Title": "App.xaml", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp\\App.xaml", + "RelativeDocumentMoniker": "GrinderApp\\GrinderApp\\App.xaml", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp\\App.xaml", + "RelativeToolTip": "GrinderApp\\GrinderApp\\App.xaml", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", - "WhenOpened": "2024-06-22T03:21:10.372Z" + "WhenOpened": "2024-12-19T08:35:59.7Z" }, { "$type": "Document", - "DocumentIndex": 7, - "Title": "WpfExtensions.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\WpfExtensions.cs", - "RelativeDocumentMoniker": "UniLuaEditor\\WpfExtensions.cs", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\WpfExtensions.cs", - "RelativeToolTip": "UniLuaEditor\\WpfExtensions.cs", - "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T03:30:03.387Z" - }, - { - "$type": "Document", - "DocumentIndex": 9, - "Title": "readme.txt", - "DocumentMoniker": "C:\\Users\\kmsmg\\.nuget\\packages\\prism.wpf\\8.1.97\\readme.txt", - "ToolTip": "C:\\Users\\kmsmg\\.nuget\\packages\\prism.wpf\\8.1.97\\readme.txt", - "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|", - "WhenOpened": "2024-06-22T03:26:29.819Z" - }, - { - "$type": "Document", - "DocumentIndex": 10, - "Title": "UniLuaEditor", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\UniLuaEditor.csproj", - "RelativeDocumentMoniker": "UniLuaEditor\\UniLuaEditor.csproj", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\UniLuaEditor.csproj", - "RelativeToolTip": "UniLuaEditor\\UniLuaEditor.csproj", + "DocumentIndex": 5, + "Title": "GrinderApp.Services.csproj", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\Services\\GrinderApp.Services\\GrinderApp.Services.csproj", + "RelativeDocumentMoniker": "GrinderApp\\Services\\GrinderApp.Services\\GrinderApp.Services.csproj", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\Services\\GrinderApp.Services\\GrinderApp.Services.csproj", + "RelativeToolTip": "GrinderApp\\Services\\GrinderApp.Services\\GrinderApp.Services.csproj", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", - "WhenOpened": "2024-06-22T02:59:38.97Z" - }, - { - "$type": "Document", - "DocumentIndex": 11, - "Title": "LuaAuxLib.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAuxLib.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAuxLib.cs", - "RelativeToolTip": "Assets\\UniLua\\LuaAuxLib.cs", - "ViewState": "AQIAACsCAAAAAAAAAAAtwDECAAARAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:53:02.58Z" + "WhenOpened": "2024-12-19T08:29:00.689Z" }, { "$type": "Document", - "DocumentIndex": 12, - "Title": "LuaDebug.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaDebug.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\LuaDebug.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaDebug.cs", - "RelativeToolTip": "Assets\\UniLua\\LuaDebug.cs", - "ViewState": "AQIAANYBAAAAAAAAAAAlwOQBAAAPAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T02:03:35.091Z" + "DocumentIndex": 6, + "Title": "GrinderApp.Services.Interfaces.csproj", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\Services\\GrinderApp.Services.Interfaces\\GrinderApp.Services.Interfaces.csproj", + "RelativeDocumentMoniker": "GrinderApp\\Services\\GrinderApp.Services.Interfaces\\GrinderApp.Services.Interfaces.csproj", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\Services\\GrinderApp.Services.Interfaces\\GrinderApp.Services.Interfaces.csproj", + "RelativeToolTip": "GrinderApp\\Services\\GrinderApp.Services.Interfaces\\GrinderApp.Services.Interfaces.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-12-19T08:28:44.14Z" }, { "$type": "Document", - "DocumentIndex": 13, - "Title": "LuaAPI.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\LuaAPI.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaAPI.cs", - "RelativeToolTip": "Assets\\UniLua\\LuaAPI.cs", - "ViewState": "AQIAAEYCAAAAAAAAAAAlwFQCAAAlAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T02:03:44.522Z" + "DocumentIndex": 7, + "Title": "GrinderApp.Modules.ModuleName.Tests.csproj", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\Tests\\GrinderApp.Modules.ModuleName.Tests\\GrinderApp.Modules.ModuleName.Tests.csproj", + "RelativeDocumentMoniker": "GrinderApp\\Tests\\GrinderApp.Modules.ModuleName.Tests\\GrinderApp.Modules.ModuleName.Tests.csproj", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\Tests\\GrinderApp.Modules.ModuleName.Tests\\GrinderApp.Modules.ModuleName.Tests.csproj", + "RelativeToolTip": "GrinderApp\\Tests\\GrinderApp.Modules.ModuleName.Tests\\GrinderApp.Modules.ModuleName.Tests.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-12-19T08:28:24.338Z" }, { "$type": "Document", - "DocumentIndex": 14, - "Title": "VM.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\VM.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\VM.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\VM.cs", - "RelativeToolTip": "Assets\\UniLua\\VM.cs", - "ViewState": "AQIAAJICAAAAAAAAAAAlwKACAAAHAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T02:03:09.098Z" - }, + "DocumentIndex": 8, + "Title": "GrinderApp.Core.csproj", + "DocumentMoniker": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp.Core\\GrinderApp.Core.csproj", + "RelativeDocumentMoniker": "GrinderApp\\GrinderApp.Core\\GrinderApp.Core.csproj", + "ToolTip": "H:\\project2\\UniLua\\GrinderApp\\GrinderApp.Core\\GrinderApp.Core.csproj", + "RelativeToolTip": "GrinderApp\\GrinderApp.Core\\GrinderApp.Core.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-12-19T08:27:40.538Z" + } + ] + }, + { + "DockedWidth": 198, + "SelectedChildIndex": -1, + "Children": [ { - "$type": "Document", - "DocumentIndex": 15, - "Title": "ULDebug.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\ULDebug.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\ULDebug.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\ULDebug.cs", - "RelativeToolTip": "Assets\\UniLua\\ULDebug.cs", - "ViewState": "AQIAAAYAAAAAAAAAAABOwBYAAAAqAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:43:36.299Z" + "$type": "Bookmark", + "Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}" }, { - "$type": "Document", - "DocumentIndex": 16, - "Title": "LuaPkgLib.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaPkgLib.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\LuaPkgLib.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaPkgLib.cs", - "RelativeToolTip": "Assets\\UniLua\\LuaPkgLib.cs", - "ViewState": "AQIAAK4AAAAAAAAAAIAywL8AAAAJAAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:42:42.258Z" + "$type": "Bookmark", + "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}" }, { - "$type": "Document", - "DocumentIndex": 17, - "Title": "LuaFile.cs", - "DocumentMoniker": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaFile.cs", - "RelativeDocumentMoniker": "Assets\\UniLua\\LuaFile.cs", - "ToolTip": "H:\\project2\\UniLua\\Assets\\UniLua\\LuaFile.cs", - "RelativeToolTip": "Assets\\UniLua\\LuaFile.cs", - "ViewState": "AQIAAAAAAAAAAAAAAAAAAA0AAAA1AAAA", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-06-22T01:40:33.009Z" + "$type": "Bookmark", + "Name": "ST:3:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" } ] }, { - "DockedWidth": 6, - "SelectedChildIndex": 1, + "DockedWidth": 267, + "SelectedChildIndex": -1, "Children": [ { "$type": "Bookmark", - "Name": "ST:3:0:{57d563b6-44a5-47df-85be-f4199ad6b651}" - }, - { - "$type": "Document", - "DocumentIndex": 2, - "Title": "MainWindow.xaml", - "DocumentMoniker": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\MainWindow.xaml", - "RelativeDocumentMoniker": "UniLuaEditor\\Views\\MainWindow.xaml", - "ToolTip": "H:\\project2\\UniLua\\UniLuaEditor\\Views\\MainWindow.xaml", - "RelativeToolTip": "UniLuaEditor\\Views\\MainWindow.xaml", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", - "WhenOpened": "2024-06-22T03:19:30.536Z", - "EditorCaption": "" + "Name": "ST:0:0:{e1b7d1f8-9b3c-49b1-8f4f-bfc63a88835d}" } ] } diff --git a/Grinder.Infrastructure/Config/ConfigStream.Json/ConfigStream.Json.csproj.DotSettings b/Grinder.Infrastructure/Config/ConfigStream.Json/ConfigStream.Json.csproj.DotSettings new file mode 100644 index 0000000..73e9656 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.Json/ConfigStream.Json.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp60 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Persistence.Json.csproj.DotSettings b/Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Persistence.Json.csproj.DotSettings new file mode 100644 index 0000000..73e9656 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Persistence.Json.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp60 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Store.Json.csproj b/Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Store.Json.csproj new file mode 100644 index 0000000..81438d9 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.Json/Configuration.Store.Json.csproj @@ -0,0 +1,40 @@ + + + net6.0-windows + Library + FirstLineTamping.Configuration.Store.Json + ConfigStore.Json + false + latest + ConfigStream.Json + Oulida electric co., ltd. + Configuration json store module + Copyright %28c%29 Oulida 2020 + 1.0.0.0 + 1.0.0.0 + + + ..\bin\x86\Debug\ + latest + MinimumRecommendedRules.ruleset + + + ..\bin\x86\Release\ + MinimumRecommendedRules.ruleset + latest + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.Json/Documents/Readme.md b/Grinder.Infrastructure/Config/ConfigStream.Json/Documents/Readme.md new file mode 100644 index 0000000..b6cc1fc --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.Json/Documents/Readme.md @@ -0,0 +1,9 @@ +| Property | Value +|:-------------|:----------------------- +| Project Name | ConfigStream.Json +| Author | Liu Wan Li +| Create Time | 2019-04-09 + +# Summary +这个项目实现一个Json 文件格式的配置文件持久化版本。采用 Newtonsoft.Json 作为转换提供 +接口的定义在 TampingFoundation 项目的 Configs 中 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.Json/JsonConfigStore.cs b/Grinder.Infrastructure/Config/ConfigStream.Json/JsonConfigStore.cs new file mode 100644 index 0000000..d3cbd64 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.Json/JsonConfigStore.cs @@ -0,0 +1,248 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using tracedrive_one.Configuration.Helper; +using tracedrive_one.Configuration.StreamProvider; + +#pragma warning disable 162 + +namespace tracedrive_one.Configuration.Store.Json +{ + ///

+ /// JSON 配置文件转换流 + /// + public class JsonConfigStore : IConfigStore + { + /// + /// 配置文件读写流(这个设计到技术资源,例如磁盘, 单独抽出来为了更好的单元测试) + /// + private readonly IStreamProvider _configStream; + + public JsonConfigStore(IStreamProvider configStream) + { + if (configStream == null) + throw new ArgumentNullException(nameof(configStream)); + + _configStream = configStream; + } + + /// + /// 数据源由外部更新事件 + /// + public event AsyncEventHandler SourceChanged + { + add + { + var streamProviderWithNotification = _configStream as IStreamProviderWithNotification; + if (streamProviderWithNotification != null) + streamProviderWithNotification.StreamSourceChanged += value; + } + remove + { + var streamProviderWithNotification = _configStream as IStreamProviderWithNotification; + if (streamProviderWithNotification != null) + streamProviderWithNotification.StreamSourceChanged -= value; + } + } + + #region Implementation of IConfigStream + + /// + /// 从数据流中加载 配置文件 对象 + /// + /// + public async Task LoadAsync() + { + using (var stream = _configStream.OpenRead()) + using (var reader = new StreamReader(stream)) + { + // 读取配置信息 + var settingString = await reader.ReadToEndAsync(); + if (string.IsNullOrEmpty(settingString)) + return new ConfigData(); + + return ExtraSettingFromString(settingString); + } + } + + /// + /// 加载配置文件对象 + /// + /// + public ConfigData Load() + { + using (var stream = _configStream.OpenRead()) + using (var reader = new StreamReader(stream)) + { + // 读取配置信息 + var settingString = reader.ReadToEnd(); + if (string.IsNullOrEmpty(settingString)) + return new ConfigData(); + + return ExtraSettingFromString(settingString); + } + } + + /// + /// 配置文件保存至数据流 + /// + /// 配置信息数据 + /// + public async Task SaveAsync(ConfigData section) + { + string settingString = GenerateSettingString(section); + using (var stream = _configStream.OpenWrite()) + using (StreamWriter writer = new StreamWriter(stream)) + { + await writer.WriteAsync(settingString); + await writer.FlushAsync(); + } + } + + + /// + /// 配置文件保存至数据流 + /// + /// 配置信息数据 + /// + public void Save(ConfigData section) + { + string settingString = GenerateSettingString(section); + using (var stream = _configStream.OpenWrite()) + using (StreamWriter writer = new StreamWriter(stream)) + { + writer.Write(settingString); + writer.Flush(); + } + } + + /// + /// 生成设置参数字符串 + /// + /// + /// + private static string GenerateSettingString(ConfigData data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + + // 转换为一个Dictionary嵌套,然后写入 + + var stack = new Stack>>(); + var referenced = new HashSet(); // 保存已经读取的节点 + + var rootDict = new Dictionary(); + stack.Push(new Tuple>("", rootDict)); + + // 递归转换 + while (stack.Any()) + { + var cur = stack.Pop(); + var curPath = cur.Item1; + var curDict = cur.Item2; + + // 检查循环引用 + if (referenced.Contains(curPath)) + throw new ArgumentException("Circular reference in config section"); + referenced.Add(curPath); + + // 处理值 + var valuePaths = data.GetChildrenNodes(curPath, false); + foreach (var valuePath in valuePaths) + { + var path = ConfigPath.CombinePath(curPath, valuePath); + var cp = new ConfigPath(valuePath); + var configValue = data.OpenConfigValue(path); + + var value = configValue.Value; + + // 处理枚举 + if (value is Enum e) + value = e.ToString(); + + curDict.Add(cp.Current, value); + } + + // 处理节点 + var sectionPaths = data.GetChildrenNodes(curPath, true); + foreach (var sectionPath in sectionPaths) + { + var path = ConfigPath.CombinePath(curPath, sectionPath); + + var dictionary = new Dictionary(); + var cp = new ConfigPath(sectionPath); + curDict.Add(cp.Current, dictionary); + + stack.Push(new Tuple>(path, dictionary)); + } + } + + // 执行序列化,并写到流中 + var settingString = JsonConvert.SerializeObject(rootDict, Formatting.Indented); + return settingString; + } + + #endregion + + /// + /// 解析处理设置参数 + /// + /// + /// + private static ConfigData ExtraSettingFromString(string settingString) + { + // 执行转换 + var root = JsonConvert.DeserializeObject(settingString) as JObject; + var data = new ConfigData(); + var stack = new Stack>(new[] + { + new Tuple(root, "") + }); + var referenced = new HashSet(); + + // 递归执行JObject至ConfigSection的转换 + while (stack.Any()) + { + var cur = stack.Pop(); + var curItem = cur.Item1; + var curPath = cur.Item2; + + // 引用检查 + if (referenced.Contains(curItem)) + continue; + referenced.Add(curItem); + + // 执行本次转换 + foreach (var item in curItem) + { + var combinePath = ConfigPath.CombinePath(curPath, item.Key); + + // 如果是一个 JObject,递归转换下去 + var jObject = item.Value as JObject; + if (jObject != null) + { + stack.Push(new Tuple(jObject, combinePath)); + continue; + } + + // 处理值 + var jValue = item.Value as JValue; + if (jValue != null) + { + var cv = data.OpenOrCreateConfigValue(combinePath); + cv.Value = jValue.Value; + continue; + } + + throw new NotSupportedException($"Object type {item.Value.GetType().Name} is not supported"); + } + } + + return data; + } + } +} diff --git a/Grinder.Infrastructure/Config/ConfigStream.Json/Properties/AssemblyInfo.cs b/Grinder.Infrastructure/Config/ConfigStream.Json/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a308afc --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.Json/Properties/AssemblyInfo.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using System.Runtime.InteropServices; +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5d22f933-5bf8-4db1-be3c-cac8765dabce")] diff --git a/Grinder.Infrastructure/Config/ConfigStream.JsonTests/ConfigStream.JsonTests.csproj.DotSettings b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/ConfigStream.JsonTests.csproj.DotSettings new file mode 100644 index 0000000..73e9656 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/ConfigStream.JsonTests.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp60 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Persistence.JsonTests.csproj.DotSettings b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Persistence.JsonTests.csproj.DotSettings new file mode 100644 index 0000000..73e9656 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Persistence.JsonTests.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp60 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj new file mode 100644 index 0000000..c3a1e9d --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj @@ -0,0 +1,138 @@ + + + + + + Debug + AnyCPU + {F5808BED-35F8-41AA-A126-5E3D65A8D853} + Library + Properties + ConfigStream.JsonTests + ConfigStream.JsonTests + v4.6.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + 7.0 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + 7.0 + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + 6 + prompt + MinimumRecommendedRules.ruleset + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + ..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll + True + + + + + + + + + + + + + + + + + + {5D22F933-5BF8-4DB1-BE3C-CAC8765DABCE} + Configuration.Store.Json + + + {E70AADB2-1940-454B-8BFF-1A674F7D39F0} + Configuration + + + {B3F4ED07-9A02-4926-B827-3AFA00330E58} + TampingInfrastructure + + + + + + + + + + False + + + False + + + False + + + False + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj.DotSettings b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj.DotSettings new file mode 100644 index 0000000..73e9656 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Configuration.Store.JsonTests.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp60 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigStream.JsonTests/JsonConfigStreamTests.cs b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/JsonConfigStreamTests.cs new file mode 100644 index 0000000..fbe24fd --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/JsonConfigStreamTests.cs @@ -0,0 +1,50 @@ +using System.IO; +using System.Threading.Tasks; +using FirstLineTamping.Configuration; +using FirstLineTamping.Configuration.Store.Json; +using FirstLineTamping.Configuration.StreamProvider; +using NUnit.Framework; + +namespace ConfigStream.JsonTests +{ + [TestFixture()] + public class JsonConfigStreamTests + { + /// + /// 先写入,再读出,验证一致 + /// + /// + [Test()] + public async Task SaveThenLoadTest() + { + var config = new Config(); + + var person = config.GetSection(); + person.SetValue("Name", "Nepton"); + person.SetValue("Age", 38); + person.SetValue("Sex", "M"); + person.SetValue("City", "Kunming"); + + var child = person.GetSection("Child"); + child.SetValue("Name", "doudou"); + child.SetValue("Age", "6"); + + var stream = new MemoryStreamProvider(); + config.SetConfigStore(new JsonConfigStore(stream)); + + // 写入 + await config.SaveAsync(); + + // 读出 + var newConfig = new Config(new JsonConfigStore(stream)); + await newConfig.LoadAsync(); + + // 验证 + Assert.AreEqual(person.GetValue("Name"), newConfig.GetValue("Name")); + Assert.AreEqual(person.GetValue("Age"), newConfig.GetValue("Age")); + Assert.AreEqual(person.GetValue("Sex"), newConfig.GetValue("Sex")); + Assert.AreEqual(person.GetValue("Child.Age"), newConfig.GetValue("Child.Age")); + Assert.AreEqual(person.GetValue("City"), newConfig.GetValue("City")); + } + } +} diff --git a/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Properties/AssemblyInfo.cs b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c7e07ee --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ConfigStream.JsonTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConfigStream.JsonTests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f5808bed-35f8-41aa-a126-5e3d65a8d853")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Grinder.Infrastructure/Config/ConfigStream.JsonTests/packages.config b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/packages.config new file mode 100644 index 0000000..e897f2a --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigStream.JsonTests/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/Configuration/Config.cs b/Grinder.Infrastructure/Config/Configuration/Config.cs new file mode 100644 index 0000000..16545d4 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/Config.cs @@ -0,0 +1,653 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +using grinder.Configuration.Helper; + +namespace grinder.Configuration +{ + /// + /// 配置信息的数据全部保存在该对象 + /// + public class Config + { + /// + /// 配置文件持久化接口 + /// + private IConfigStore _configStore; + + /// + /// 存储数据 + /// + private ConfigData _data = new(); + + /// + /// 允许一个执行者和一个等待着的队列,这个对象在属性更改自动保存的时候防止大批量执行。 + /// + private readonly OneWaiterTaskQueue _oneWaiterTaskQueue = new(); + + /// + /// 在读取节点时, 如果节点不存在,是否把默认值写入节点 + /// + public bool WriteDefaultValueEnable + { + get; + set; + } = true; + + /// + /// 构造函数,含有持久化模块 + /// + /// + public Config(IConfigStore configStore) + { + SetConfigStore(configStore); + Load(); + } + + public Config() + { + } + + #region 数据变更事件 + + /// + /// 内存内容变化,写值 + /// + private void OnConfigSourceChanged() + { + if (SaveMethod != SaveMethods.PropertyChanged || _configStore == null) + return; + + // 如果大量的保存请求到这儿, 只让一个保存正在执行和一个保存模块等待,提高性能 + _oneWaiterTaskQueue.TryEnqueue(async () => + { + // 滞后一秒执行保存,这样可以让保存执行最低间隔一秒,而且间隔一秒自动保存不会有什么影响 + await SaveAsync(); + await Task.Delay(1000); + }); + } + + /// + /// 数据源变更时,重新加载内容 + /// + /// + /// + /// + private async Task ConfigStore_SourceChanged(object sender, EventArgs e) + { + await LoadAsync(); + } + + #endregion + + #region Load & Save + + /// + /// 设置配置文件持久化接口 + /// + /// + public void SetConfigStore(IConfigStore newStore) + { + if (_configStore == newStore) + return; + + if (_configStore != null) + _configStore.SourceChanged -= ConfigStore_SourceChanged; + + _configStore = newStore; + _configStore.SourceChanged += ConfigStore_SourceChanged; + } + + /// + /// 持久化保存 + /// + /// + public async Task SaveAsync() + { + await SaveCoreAsync(true); + } + + /// + /// 加载配置信息 + /// + /// + public async Task LoadAsync() + { + await LoadCoreAsync(true); + } + + /// + /// 加载配置信息 + /// + public void Load() + { + LoadCore(true); + } + + /// + /// 持久化保存-内部执行 + /// + /// + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local + private async Task SaveCoreAsync(bool throwWhenStoreNotReady) + { + var configStore = _configStore; + + if (configStore == null) + { + if (throwWhenStoreNotReady) + throw new InvalidOperationException($"{nameof(IConfigStore)} is required"); + + return; + } + + await configStore.SaveAsync(_data); + } + + /// + /// 持久化保存参数另存为, 这个操作不应影响内部默认的 Store + /// + /// + public async Task SaveAsAsync(IConfigStore store) + { + if (store == null) + throw new ArgumentNullException(nameof(store)); + + await store.SaveAsync(_data); + } + + /// + /// 从指定的 Store 加载配置, 这个操作不应影响内部默认的 Store + /// + /// + public async Task LoadFromAsync(IConfigStore store) + { + if (store == null) + throw new ArgumentNullException(nameof(store)); + + _data = await store.LoadAsync() ?? new ConfigData(); + } + + /// + /// 加载配置-内部调用 + /// + /// + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local + private async Task LoadCoreAsync(bool throwWhenStoreNotReady) + { + var configStore = _configStore; + if (configStore == null) + { + if (throwWhenStoreNotReady) + throw new InvalidOperationException($"{nameof(IConfigStore)} is required"); + + return; + } + + _data = await configStore.LoadAsync() ?? new ConfigData(); + } + + /// + /// 加载配置-内部调用 + /// + /// + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local + private void LoadCore(bool throwWhenStoreNotReady) + { + var configStore = _configStore; + if (configStore == null) + { + if (throwWhenStoreNotReady) + throw new InvalidOperationException($"{nameof(IConfigStore)} is required"); + + return; + } + + _data = configStore.Load() ?? new ConfigData(); + } + + /// + /// 写入文件的方式,通过手动调用 Flush 函数 or 属性更改后自动刷入 + /// + public SaveMethods SaveMethod + { + get; + set; + } = SaveMethods.PropertyChanged; + + #endregion + + #region Sections + + /// + /// 获取当前根节点 + /// + /// + public ConfigSection GetSection() + { + return new(this, ""); + } + + /// + /// 获取一个指定的子节点 + /// + /// + /// + public ConfigSection GetSection(string path) + { + return new(this, path); + } + + #endregion + + #region GetValue / SetValue + + /// + /// 读取值 + /// + /// 值的路径 + /// 期望的类型 + /// 默认值 + /// + public object GetValue(string path, Type expectedType, object defaultValue = default) + { + var item = _data.OpenConfigValue(path); + if (item != null) + return item.GetValue(expectedType, defaultValue); + + if (WriteDefaultValueEnable) + { + SetValue(path, defaultValue); + } + + return defaultValue; + } + + /// + /// 读取值 + /// + /// 值类型 + /// 值的路径 + /// 默认值 + /// + public TValue GetValue(string path, TValue defaultValue = default) + { + var item = _data.OpenConfigValue(path); + if (item != null) + return item.GetValue(defaultValue); + + if (WriteDefaultValueEnable) + { + SetValue(path, defaultValue); + } + + return defaultValue; + } + + /// + /// 读取值, 如果无法读取(例如路径不存在,无法转换类型),抛出异常 + /// + /// 值类型 + /// 值的路径 + /// + public TValue GetValueOrThrow(string path) + { + var item = _data.OpenConfigValue(path); + if (item != null) + return item.GetValue(); + + throw new ArgumentException("No value item in path"); + } + + + /// + /// 写入值 + /// + /// + /// + /// + public bool SetValue(string path, TValue value) + { + var cv = _data.OpenOrCreateConfigValue(path); + if (cv == null) + throw new ArgumentNullException(nameof(cv)); + + if (cv.SetValue(value)) + { + OnConfigSourceChanged(); + return true; + } + + return false; + } + + #endregion + + /// + /// 删除指定路径的所有项 + /// + /// + public void Remove(string path) + { + if (_data.Remove(path)) + OnConfigSourceChanged(); + } + + /// + /// 清空所有配置 + /// + public void Clear() + { + if (_data.Clear()) + OnConfigSourceChanged(); + } + + /// + /// 更名,把以 开头的路径更名为 + /// + /// 原路径 + /// 新路径 + public void Rename(string originPath, string newPath) + { + if (_data.Rename(originPath, newPath)) + OnConfigSourceChanged(); + } + + /// + /// 从另一个配置文件合并 + /// + /// + /// 是否覆盖已有数据 + public void MergeWith(Config config, bool overrideExists) + { + if (_data.MergeWith(config._data, overrideExists)) + OnConfigSourceChanged(); + } + + /// + /// 获取给定路径下的所有的第一层子路径的节点 + /// 例如对于如下路径:Order.Create.Name, GetSubPaths("Order", true) 返回 "Create" + /// + /// 指定的路径 + /// 要获取的路径是否拥有后续节点(是否为一个ConfigSection) + /// + public string[] GetChildrenNodes(string path, bool? hasMoreSubsequentPath = null) + { + return _data.GetChildrenNodes(path, hasMoreSubsequentPath); + } + + #region Convert From / To JObject + + /// + /// 转换为JObject + /// + /// + /// + public JObject ToJObject(string path) + { + // 转换为一个Dictionary嵌套,然后写入 + var stack = new Stack<(string Path, JObject JObject)>(); + var referenced = new HashSet(); // 保存已经读取的节点 + + var rootDict = new JObject(); + stack.Push((path, rootDict)); + + // 递归转换 + while (stack.Any()) + { + var cur = stack.Pop(); + var curPath = cur.Path; + + // 检查循环引用 + if (referenced.Contains(curPath)) + throw new ArgumentException("Circular reference in config section"); + referenced.Add(curPath); + + // 处理值 + var valuePaths = _data.GetChildrenNodes(curPath, false); + foreach (var valuePath in valuePaths) + { + var fullValuePath = ConfigPath.CombinePath(curPath, valuePath); + var cp = new ConfigPath(valuePath); + var configValue = _data.OpenConfigValue(fullValuePath); + + var value = configValue.Value; + + // 处理枚举 + if (value is Enum e) + value = e.ToString(); + + cur.JObject.Add(cp.Current, new JValue(value)); + } + + // 处理节点 + var sectionPaths = _data.GetChildrenNodes(curPath, true); + foreach (var sectionPath in sectionPaths) + { + var jObject = new JObject(); + var cp = new ConfigPath(sectionPath); + cur.JObject.Add(cp.Current, jObject); + + var fullSectionPath = ConfigPath.CombinePath(curPath, sectionPath); + stack.Push((fullSectionPath, jObject)); + } + } + + return rootDict; + } + + /// + /// 从 JObject 读取值, 然后组合到当前配置中 + /// + /// + /// + /// + public void FromJObject(string path, JObject jObject) + { + // 执行转换 + var stack = new Stack<(JObject JObject, string Path)>(); + stack.Push((jObject, path)); + var referenced = new HashSet(); + + // 递归执行JObject至ConfigSection的转换 + while (stack.Any()) + { + var cur = stack.Pop(); + + // 引用检查 + if (referenced.Contains(cur.JObject)) + continue; + referenced.Add(cur.JObject); + + // 执行本次转换 + foreach (var prop in cur.JObject) + { + var combinePath = ConfigPath.CombinePath(cur.Path, prop.Key); + + if (prop.Value == null) + continue; + + // 如果是一个 JObject,递归转换下去 + if (prop.Value is JObject jObjectSub) + { + stack.Push((jObjectSub, combinePath)); + continue; + } + + // 处理值 + if (prop.Value is JValue jValue) + { + var cv = _data.OpenOrCreateConfigValue(combinePath); + cv.Value = jValue.Value; + continue; + } + + throw new NotSupportedException($"Object type {prop.Value.GetType().Name} is not supported"); + } + } + } + + #endregion + + #region Convert From / To Dictionary + + /// + /// 生成设置参数字符串 + /// + /// + /// + public Dictionary ToDictionary(string path) + { + // 转换为一个Dictionary嵌套,然后写入 + var stack = new Stack<(string path, Dictionary dict)>(); + var referenced = new HashSet(); // 保存已经读取的节点 + + var rootDict = new Dictionary(); + stack.Push((path, rootDict)); + + // 递归转换 + while (stack.Any()) + { + var cur = stack.Pop(); + var curPath = cur.Item1; + var curDict = cur.Item2; + + // 检查循环引用 + if (referenced.Contains(curPath)) + throw new ArgumentException("Circular reference in config section"); + referenced.Add(curPath); + + // 处理值 + var valuePaths = _data.GetChildrenNodes(curPath, false); + foreach (var valuePath in valuePaths) + { + var fullValuePath = ConfigPath.CombinePath(curPath, valuePath); + var cp = new ConfigPath(valuePath); + var configValue = _data.OpenConfigValue(fullValuePath); + + var value = configValue.Value; + + // 处理枚举 + if (value is Enum e) + value = e.ToString(); + + curDict.Add(cp.Current, value); + } + + // 处理节点 + var sectionPaths = _data.GetChildrenNodes(curPath, true); + foreach (var sectionPath in sectionPaths) + { + var dictionary = new Dictionary(); + var cp = new ConfigPath(sectionPath); + curDict.Add(cp.Current, dictionary); + + var fullSectionPath = ConfigPath.CombinePath(curPath, sectionPath); + stack.Push((fullSectionPath, dictionary)); + } + } + + return rootDict; + } + + /// + /// 从 JObject 读取值, 然后组合到当前配置中 + /// + /// + /// + /// + public void FromDictionary(string path, Dictionary dict) + { + // 执行转换 + var stack = new Stack<(string Path, Dictionary Dict)>(); + stack.Push((path, dict)); + var referenced = new HashSet>(); + + // 递归执行JObject至ConfigSection的转换 + while (stack.Any()) + { + var cur = stack.Pop(); + + // 引用检查 + if (referenced.Contains(cur.Dict)) + continue; + referenced.Add(cur.Dict); + + // 执行本次转换 + foreach (var keyValue in cur.Dict) + { + var combinePath = ConfigPath.CombinePath(cur.Path, keyValue.Key); + + if (keyValue.Value == null) + continue; + + // 如果是一个 JObject,递归转换下去 + if (keyValue.Value is Dictionary subDict) + { + stack.Push((combinePath, subDict)); + continue; + } + + // 处理值 + if (keyValue.Value is JValue jValue) + { + var cv = _data.OpenOrCreateConfigValue(combinePath); + cv.Value = jValue.Value; + continue; + } + + throw new NotSupportedException($"Object type {keyValue.Value.GetType().Name} is not supported"); + } + } + } + + #endregion + + #region Convert From / To Object + + /// + /// 从指定的节点装换为一个设置对象 + /// + /// + /// + /// 是否声明子对象类型, (例如含有接口, 抽象类, 则需要传入 true) + /// + public T ToObject(string path, bool declareType = false) + { + var jObject = ToJObject(path); + + var setting = new JsonSerializer + { + TypeNameHandling = declareType ? TypeNameHandling.Auto : TypeNameHandling.None, + }; + + var obj = jObject.ToObject(setting); + return obj; + } + + /// + /// 从指定的节点装换为一个设置对象 + /// + /// + /// 要转换的 obj + /// 是否声明子对象类型, (例如含有接口, 抽象类, 则需要传入 true) + /// + public void FromObject(string path, object obj, bool declareType = false) + { + var setting = new JsonSerializer() + { + TypeNameHandling = declareType ? TypeNameHandling.Auto : TypeNameHandling.None + }; + var jObject = JObject.FromObject(obj, setting); + + FromJObject(path, jObject); + } + + #endregion + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigBase.cs b/Grinder.Infrastructure/Config/Configuration/ConfigBase.cs new file mode 100644 index 0000000..ed6a8ee --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/ConfigBase.cs @@ -0,0 +1,284 @@ +using Serilog; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace grinder.Configuration +{ + /// + /// 强类型命名配置对象基类 + /// 该对象是操作Config的基类 + /// + /// + /// 2019-10-16 11:34:51 增加接口 INotifyPropertyChanged TODO 已知问题:1 没有检测变化 2 不是所有的 SetValue 入口都进行了监控 + /// + public abstract class ConfigBase : INotifyPropertyChanged, IDefaultConfigWriter + { + private readonly Config _config; + + public Config Config => _config; + + /// + /// 仅返回默认值的模式,这个模式给 RestoreDefaultValue 使用,用户调用了 RestoreDefaultValue 后,程序打开这个开关,然后 GetValue....仅返回默认值,而不查询存储的内容。同时 RestoreDefaultValue 函数把读取到的默认值写入磁盘。 + /// + private bool _returnDefaultValueMode; + + /// + /// 定义作用域(包) + /// 在多个配置文件合并的时候,用来区分不同的作用域 + /// + public abstract string PathName + { + get; + } + + /// + /// 构造函数, + /// + /// 强命名该分组 + protected ConfigBase(Config config) + { + _config = config; + } + + + + + /// + /// 获取配置参数属性的描述信息 + /// + /// + public Dictionary GetPropertyDescriptions() + { + var dict = new Dictionary(); + + var props = GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + foreach (var prop in props) + { + var attr = prop.GetCustomAttribute(true); + if (attr == null) + continue; + + var path = ConfigPath.CombinePath(PathName, prop.Name); + dict.Add(path, attr.Description); + } + + return dict; + } + + + + #region Get / Set Value just for Property :) + + /// + /// 获取值, 该函数使用在对属性执行读写操作时 + /// + /// 值类型 + /// 如果没有存储该值,返回默认值 + /// 属性名 + /// + public TValue GetPropertyValue(TValue defaultValue, [CallerMemberName] string propertyName = default) + { + if (_returnDefaultValueMode) + return defaultValue; + + // 如果没有指定路径, 返回默认值, 而且不操作存储库 + if (PathName is not { } pathName) + return defaultValue; + + return _config.GetValue(ConfigPath.CombinePath(pathName, propertyName), defaultValue); + } + + + /// + /// 设置属性默认值 + /// + /// 值类型 + /// 目标值 + /// 属性名 + public void SetPropertyValue(TValue value, [CallerMemberName] string propertyName = default) + { + // 如果没有指定路径, 不操作存储库 + if (PathName is not { } pathName) + return; + + _config.SetValue(ConfigPath.CombinePath(pathName, propertyName), value); + OnPropertyChanged(propertyName); + } + + /// + /// 重命名属性节点 + /// + /// 原属性名 + /// 属性名 + public void RenameProperty(string originPropertyName, string newPropertyName) + { + // 如果没有指定路径, 不操作存储库 + if (PathName is not { } pathName) + return; + + var originPath = ConfigPath.CombinePath(pathName, originPropertyName); + var newPath = ConfigPath.CombinePath(pathName, newPropertyName); + _config.Rename(originPath, newPath); + } + + #endregion + + /// + /// 获取完整路径的值, 如果找不到,返回默认值。 + /// 如果你不需要指定完整路径, 请调用 GetPropertyValue + /// + /// 值的类型 + /// 保存配置参数的全路径 + /// 默认值,如果无法读取到内容,返回该值 + /// + public TValue GetValue(string path, TValue defaultValue) + { + if (_returnDefaultValueMode) + return defaultValue; + + return _config.GetValue(path, defaultValue); + } + + /// + /// 获取指定路径的值,如果无法获取到值,将抛出异常(用于防止路径指定错误) + /// 如果你不需要指定完整路径, 请调用 GetPropertyValue + /// + /// 值的类型 + /// 保存配置参数的全路径 + /// + public TValue GetValue(string path) + { + if (_returnDefaultValueMode) + return default; + + // todo 考虑抛出异常的合理性,暂时关闭异常抛出的方式 + //return _config.GetValueOrThrow(path); + return _config.GetValue(path, default(TValue)); + } + + /// + /// 获取完整路径的值 + /// 如果你不需要指定完整路径, 请调用 SetPropertyValue + /// + /// 值的类型 + /// 全路径 + /// 值 + /// + public bool SetValue(string path, TValue value) + { + return _config.SetValue(path, value); + } + + /// + /// 恢复默认值 + /// + public void RestoreDefaultValue() + { + var props = GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (var prop in props) + { + RestoreDefaultValue(prop); + } + } + public void xr() + { + var props = GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (var prop in props) + { + try + { + + // 仅返回默认值的模式,这个模式给 RestoreDefaultValue 使用,用户调用了 RestoreDefaultValue 后,程序打开这个开关, + // 然后 GetValue....仅返回默认值,而不查询存储的内容。同时 RestoreDefaultValue 函数把读取到的默认值写入磁盘。 + if (prop.CanRead && prop.CanWrite) + { + var value = prop.GetValue(this); + // prop.SetValue(this, value); + Log.Information($""); + // Raise property changed + OnPropertyChanged(nameof(prop.Name)); + } + } + finally + { + _returnDefaultValueMode = false; + } + } + } + + /// + /// 恢复默认值 + /// + /// + public void RestoreDefaultValue(string propertyName) + { + var prop = GetType().GetProperty(propertyName); + if (prop != null) + RestoreDefaultValue(prop); + } + + /// + /// 恢复默认值 + /// + /// + public void RestoreDefaultValue(PropertyInfo prop) + { + try + { + _returnDefaultValueMode = true; + + // 仅返回默认值的模式,这个模式给 RestoreDefaultValue 使用,用户调用了 RestoreDefaultValue 后,程序打开这个开关, + // 然后 GetValue....仅返回默认值,而不查询存储的内容。同时 RestoreDefaultValue 函数把读取到的默认值写入磁盘。 + if (prop.CanRead && prop.CanWrite) + { + var value = prop.GetValue(this); + prop.SetValue(this, value); + + // Raise property changed + OnPropertyChanged(nameof(prop.Name)); + } + } + finally + { + _returnDefaultValueMode = false; + } + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + /// + /// 把默认值持久化写入 + /// + /// + public virtual void WriteDefaultValue() + { + // TODO 目前设计不合理,重写该方法,并做相应重构,配置参数读取时不要默认写入. 其中这里应改为 prop.SetValue(prop.GetValue()); + + var props = GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (var prop in props) + { + // TODO 判断可读取时去尝试读取加载,并捕获异常,验证这样一来的可靠性 + try + { + // 在读取值的时候,如果发现值不存在,GetValue函数将自动追加一个节点到 ConfigSection 中 + if (prop.CanRead) + prop.GetValue(this); + } + catch + { + // no code here + } + } + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigData.cs b/Grinder.Infrastructure/Config/Configuration/ConfigData.cs new file mode 100644 index 0000000..ce0f9e2 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/ConfigData.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Concurrent; +using System.Linq; +using System.Text.RegularExpressions; + +namespace grinder.Configuration +{ + /// + /// 这个类负责存储所有的数据,新版本改为扁平化存储,取消树状存储形式 + /// + public class ConfigData + { + /// + /// 存储所有的设置参数 + /// + private readonly ConcurrentDictionary _dict = new(); + + /// + /// 打开子节点,如果不存在则创建一个 + /// + /// + /// + public ConfigValue OpenOrCreateConfigValue(string path) + { + ConfigPath.EnsurePathNotEmpty(path); + return _dict.GetOrAdd(path, _ => new ConfigValue()); + } + + /// + /// 打开子节点 + /// + /// + /// + public ConfigValue OpenConfigValue(string path) + { + ConfigPath.EnsurePathNotEmpty(path); + + _dict.TryGetValue(path, out var value); + return value; + } + + /// + /// 移除指定路径的一个参数项,或者一个Section下的所有参数项 + /// + /// 需要删除的参数的全路径 + /// 删除成功 + public bool Remove(string path) + { + if (path == null) + throw new ArgumentNullException(nameof(path)); + ConfigPath.EnsurePathNotEmpty(path); + + // 找到所有的路径 + var r = new Regex($@"^{path}(\.|$)", RegexOptions.Compiled); + var q = from key in _dict.Keys + where r.IsMatch(key) + select key; + + // 删除这些Key对应的项目 + return q.Aggregate(false, (current, key) => current | _dict.TryRemove(key, out _)); + } + + /// + /// 更名,把以 开头的路径更名为 + /// + /// 原路径 + /// 新路径 + /// 如果数据发生了更改,返回True,否则返回False + public bool Rename(string originPath, string newPath) + { + if (originPath == null) + throw new ArgumentNullException(nameof(originPath)); + if (newPath == null) + throw new ArgumentNullException(nameof(newPath)); + + ConfigPath.EnsurePathNotEmpty(originPath); + ConfigPath.EnsurePathNotEmpty(newPath); + + // 找到所有的路径 + var r = new Regex($@"^{originPath}(\.|$)", RegexOptions.Compiled); + var q = from key in _dict.Keys + where r.IsMatch(key) + select key; + + var hasChanged = false; + // 执行更名 + foreach (var path in q) + { + var newFullPath = Regex.Replace(path, $@"^{originPath}", newPath); + + if (_dict.TryRemove(path, out var value)) + { + _dict[newFullPath] = value; + + hasChanged = true; + } + } + + return hasChanged; + } + + /// + /// 获取给定路径下的所有的第一层子路径的节点 + /// 例如对于如下路径:Order.Create.Name, GetSubPaths("Order", true) 返回 "Create" + /// + /// 指定的路径 + /// 要获取的路径是否拥有后续节点(是否为一个ConfigSection) + /// + public string[] GetChildrenNodes(string path, bool? hasMoreSubsequentPath = null) + { + if (path == null) + throw new ArgumentNullException(nameof(path)); + + ConfigPath.EnsurePathValidated(path); + + if (string.IsNullOrEmpty(path) == false) + path += ConfigPath.PathSeparator; + + // 找到所有的路径 + var q = from key in _dict.Keys + where key.StartsWith(path) + let cp = new ConfigPath(key.Substring(path.Length)) + where hasMoreSubsequentPath.HasValue == false || cp.HasMoreSubsequentPath == hasMoreSubsequentPath + orderby cp.Current + select cp.Current; + + return q.Distinct().ToArray(); + } + + /// + /// 清空所有保存的配置信息 + /// + public bool Clear() + { + if (_dict.Any()) + { + _dict.Clear(); + return true; + } + + return false; + } + + /// + /// 从另一个配置存储合并配置参数 + /// + /// 另一个配置存储 + /// 如果出现路径重复,是否覆盖当前对象的数据 + public bool MergeWith(ConfigData second, bool overrideExists) + { + var changed = false; + + foreach (var keyValue in second._dict) + { + if (!overrideExists && _dict.ContainsKey(keyValue.Key)) + continue; + + var node = OpenOrCreateConfigValue(keyValue.Key); + if (!Equals(node.Value, keyValue.Value.Value)) + { + node.Value = keyValue.Value.Value; + changed = true; + } + } + + return changed; + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs b/Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs new file mode 100644 index 0000000..d7569c8 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs @@ -0,0 +1,20 @@ +namespace grinder.Configuration +{ + /// + /// 用来遍历 ConfigTree 的算法 + /// // TODO 有时间重构 Config 里的三个遍历算法, 剥离遍历和 + /// + internal class ConfigDataVisitor + { + private readonly ConfigData _data; + + public ConfigDataVisitor(ConfigData data) + { + _data = data; + } + + public void Visit(string path) + { + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigPath.cs b/Grinder.Infrastructure/Config/Configuration/ConfigPath.cs new file mode 100644 index 0000000..4792cb0 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/ConfigPath.cs @@ -0,0 +1,165 @@ +using System; +using System.Linq; + +namespace grinder.Configuration +{ + /// + /// 该对象负责处理配置路径字符串 + /// + public class ConfigPath + { + #region Static elements + /// + /// 检查Key 是否合法 + /// + /// + /// + public static bool IsNodeValidated(string newKey) + { + return newKey?.Length > 0 && newKey.Contains(PathSeparator) == false; + } + + /// + /// 确保路径不空 + /// + /// + public static void EnsurePathNotEmpty(string path) + { + var nodes = SplitPath(path); + if (nodes.Any() == false) + throw new ArgumentException("Path is empty"); + } + + /// + /// 确保Path合法,如果有问题,报错 + /// + /// + public static void EnsurePathValidated(string path) + { + SplitPath(path); + } + + /// + /// 通过传入的Path,生成路径数组 + /// + /// 路径字符串 + /// + public static string[] SplitPath(string fullPath) + { + if (fullPath == null) + throw new ArgumentNullException(nameof(fullPath)); + + if (fullPath == string.Empty) + return new string[0]; + + // 格式化当前的路径 + var paths = fullPath.Split(PathSeparator).Select(c => c.Trim()).ToArray(); + + // 组合路径前验证合法性 + if (paths.Any(string.IsNullOrEmpty)) + throw new ArgumentException("Path illegal, some path node is empty or whitespace"); + + return paths; + } + + /// + /// 组合路径 + /// + /// + /// + public static string CombinePath(params string[] paths) + { + if (paths == null) + throw new ArgumentNullException(nameof(paths)); + + // 过滤无效内容 + paths = paths.Where(c => string.IsNullOrEmpty(c) == false).ToArray(); + + // 格式化当前的路径 + paths = paths.SelectMany(c => c.Split(PathSeparator)).Select(c => c.Trim()).ToArray(); + + // 组合路径前验证合法性 + if (paths.Any(string.IsNullOrEmpty)) + throw new ArgumentException("Path illegal, some path node is empty or whitespace"); + + return string.Join(PathSeparator.ToString(), paths); + } + + /// + /// 路径分隔符 + /// + public const char PathSeparator = '.'; + + #endregion + + /// + /// 路径节点数组 + /// + private readonly string[] _paths; + + /// + /// 通过路径数组创建对象 + /// + /// 路径数组,已拆分的路径 + public ConfigPath(string path) + { + if (path == null) + throw new ArgumentNullException(nameof(path)); + + _paths = SplitPath(path); + } + + /// + /// 判断路径是否为空 + /// + /// + public bool IsEmpty => _paths.Length == 0; + + /// + /// 获取路径头。 + /// 例如 a.b.c 的路径头为 a + /// + /// + public string Current + { + get + { + if (_paths.Length == 0) + throw new ArgumentException("Path illegal, this is the empty path"); + + return _paths.First(); + } + } + + /// + /// 是否有更多的子节点 + /// + public bool HasMoreSubsequentPath => _paths.Length > 1; + + /// + /// 获取后续的路径。 + /// 例如 a.b.c 的后续路径为 b.c + /// + /// + public string SubsequentPath + { + get + { + if (_paths.Length == 0) + throw new ArgumentException("Path illegal, this is the last node of path"); + + var list = _paths.ToList(); + list.RemoveAt(0); + + return CombinePath(list.ToArray()); + } + } + + /// + /// 返回路径 + /// + public string[] Paths => _paths; + + + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigSection.cs b/Grinder.Infrastructure/Config/Configuration/ConfigSection.cs new file mode 100644 index 0000000..4a06642 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/ConfigSection.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json.Linq; + +namespace grinder.Configuration +{ + /// + /// 这个类负责保存配置信息数据,意味着一个配置信息分组 + /// + public class ConfigSection + { + private readonly Config _config; + + private readonly string _pathPrefix; + + /// Initializes a new instance of the class. + public ConfigSection(Config config, string pathPrefix) + { + _config = config; + _pathPrefix = pathPrefix; + } + public string GetFullPath(string path) + { + return ConfigPath.CombinePath(_pathPrefix, path); + } + + /// + /// 获取值 + /// + /// 路径 + /// 配置参数值的数据类型 + /// 默认值,如果值不存在返回默认值 + /// + public object GetValue(string path, Type expectedType, object defaultValue = default) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentException("Value cannot be null or empty.", nameof(path)); + + path = ConfigPath.CombinePath(_pathPrefix, path); + + return _config.GetValue(path, expectedType, defaultValue); + } + + /// + /// 获取值 + /// + /// 要获取的值的类型 + /// 路径 + /// 默认值,如果值不存在返回默认值 + /// + public TValue GetValue(string path, TValue defaultValue = default) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentException("Value cannot be null or empty.", nameof(path)); + + path = ConfigPath.CombinePath(_pathPrefix, path); + + return _config.GetValue(path, defaultValue); + } + + /// + /// 获取指定Key对应的子Section对象 + /// + /// + /// + public ConfigSection GetSection(string path) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentException("Value cannot be null or empty.", nameof(path)); + + path = ConfigPath.CombinePath(_pathPrefix, path); + + return _config.GetSection(path); + } + + /// + /// 获取所有子 Section + /// + /// + public string[] GetChildrenNodes(bool? hasMoreSubsequentPath = null) + { + return _config.GetChildrenNodes(_pathPrefix, hasMoreSubsequentPath); + } + + /// + /// 设置配置值 + /// + /// 值的类型 + /// 路径 + /// 默认值 + public void SetValue(string path, TValue value) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentException("Value cannot be null or empty.", nameof(path)); + + path = ConfigPath.CombinePath(_pathPrefix, path); + + _config.SetValue(path, value); + } + + + /// + /// 删除指定路径的所有项 + /// + /// + public void Remove(string path) + { + path = ConfigPath.CombinePath(_pathPrefix, path); + + _config.Remove(path); + } + + + /// + /// 执行更名 + /// + /// + /// + public void Rename(string originName, string newName) + { + var originPath = ConfigPath.CombinePath(_pathPrefix, originName); + var newPath = ConfigPath.CombinePath(_pathPrefix, newName); + + _config.Rename(originPath, newPath); + } + + #region Convert From / To JObject + + /// + /// 转换为JObject + /// + /// + public JObject ToJObject() + { + return _config.ToJObject(_pathPrefix); + } + + /// + /// 从 JObject 读取值, 然后组合到当前配置中 + /// + /// + /// + public void FromJObject(JObject jObject) + { + _config.FromJObject(_pathPrefix, jObject); + } + + #endregion + + #region Convert From / To Dictionary + + /// + /// 生成设置参数字符串 + /// + /// + public Dictionary ToDictionary() + { + return _config.ToDictionary(_pathPrefix); + } + + /// + /// 从 JObject 读取值, 然后组合到当前配置中 + /// + /// + /// + public void FromDictionary(Dictionary dict) + { + _config.FromDictionary(_pathPrefix, dict); + } + + #endregion + + #region Convert From / To Object + + /// + /// 从指定的节点装换为一个设置对象 + /// + /// + /// 是否声明子对象类型, (例如含有接口, 抽象类, 则需要传入 true) + /// + public T ToObject(bool declareType = false) + { + return _config.ToObject(_pathPrefix, declareType); + } + + /// + /// 从指定的节点装换为一个设置对象 + /// + /// 要转换的 obj + /// 是否声明子对象类型, (例如含有接口, 抽象类, 则需要传入 true) + /// + public void FromObject(object obj, bool declareType = false) + { + _config.FromObject(_pathPrefix, obj, declareType); + } + + #endregion + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigValue.cs b/Grinder.Infrastructure/Config/Configuration/ConfigValue.cs new file mode 100644 index 0000000..f40bd28 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/ConfigValue.cs @@ -0,0 +1,119 @@ +using System; +using System.Reflection.Metadata.Ecma335; + +namespace grinder.Configuration +{ + /// + /// 配置参数的值 + /// + public class ConfigValue + { + /// + /// 存储的值 + /// + public object Value + { + get; + set; + } + + /// Returns a string that represents the current object. + /// A string that represents the current object. + public override string ToString() + { + return $"{Value}"; + } + + /// + /// 读取值 + /// + /// + /// + /// + public TValue GetValue(TValue defaultValue = default) + { + return (TValue) GetValue(typeof(TValue), defaultValue); + } + + /// + /// 读取值 + /// + /// + /// + /// + public object GetValue(Type expectedType, object defaultValue = default) + { + if (expectedType.IsInstanceOfType(Value)) + return Value; + + if (Value == null) + return defaultValue; + + // 尝试转换类型 + try + { + // 枚举的单独处理 + if (expectedType.IsEnum) + { + if (Value is string) + return Enum.Parse(expectedType, Value.ToString() ?? string.Empty, false); + + // ReSharper disable once PossibleInvalidCastException + return Value; + } + + // 处理其他情况 + var result = Convert.ChangeType(Value, expectedType); + return result; + } + catch + { + // ignored + } + + // 保存的值无法读取,返回默认值 + return defaultValue; + } + + /// + /// 获取值,如果无法转换,抛出异常 + /// + /// + /// + public TValue GetValueOrThrow() + { + if (Value is TValue) + return (TValue) Value; + + if (Value == null) + { + if (typeof(TValue).IsClass) + return default(TValue); + + throw new InvalidCastException($"Can not cast null to {typeof(TValue).Name}"); + } + + var result = (TValue) Convert.ChangeType(Value, typeof(TValue)); + return result; + } + + + /// + /// 写入值 + /// + /// + /// + /// return TRUE if value was changed, otherwise return FALSE + public bool SetValue(TValue value) + { + if (!Equals(value, Value)) + { + Value = value; + + return true; + } + + return false; + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/Configuration.csproj b/Grinder.Infrastructure/Config/Configuration/Configuration.csproj new file mode 100644 index 0000000..5c05d05 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/Configuration.csproj @@ -0,0 +1,29 @@ + + + + net8.0-windows7.0 + Oulida.Configuration + latest + enable + AnyCPU + AnyCPU;x64;x86 + + + none + false + + + none + false + + + none + false + + + + + + + + diff --git a/Grinder.Infrastructure/Config/Configuration/Document/configuration-class-dependencies-graph.png b/Grinder.Infrastructure/Config/Configuration/Document/configuration-class-dependencies-graph.png new file mode 100644 index 0000000000000000000000000000000000000000..4688c6ad935d484af8e566b8a754ab0e25608528 GIT binary patch literal 51853 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 literal 0 HcmV?d00001 diff --git a/Grinder.Infrastructure/Config/Configuration/Document/configuration-concept.png b/Grinder.Infrastructure/Config/Configuration/Document/configuration-concept.png new file mode 100644 index 0000000000000000000000000000000000000000..610ce0992749dccd65732f7e9312320a9578e3a8 GIT binary patch literal 8648 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 Z!l=!f0)s>u0&hHk)K#>Vixe#a{{yY1)Aj%W literal 0 HcmV?d00001 diff --git a/Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs b/Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs new file mode 100644 index 0000000..ee545ef --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs @@ -0,0 +1,10 @@ +using System; +using System.Threading.Tasks; + +namespace grinder.Configuration.Helper +{ + public delegate Task AsyncEventHandler(object sender, EventArgs e); + + public delegate Task AsyncEventHandler(object sender, TEventArgs e); + +} diff --git a/Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs b/Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs new file mode 100644 index 0000000..084f793 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs @@ -0,0 +1,82 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace grinder.Configuration.Helper +{ + /// + /// 只允许一个等待着的任务队列,该队列允许一个执行者工作中,同时一个等待着在等待并进入工作 + /// 如果一个任务入队,并且发现已经有一个等待着,则返回False + /// + /// 场景:配置文件许多模块要求写入磁盘,如果当前有一个等待着等待写入,那么就把这件事情交给他吧,因为大家都是调用相同方法写入文件 + public class OneWaiterTaskQueue + { + /// + /// 等待者 + /// + private readonly SemaphoreSlim _waiter; + + /// + /// 执行者 + /// + private readonly SemaphoreSlim _executor; + + public OneWaiterTaskQueue() + { + _waiter = new SemaphoreSlim(1); + _executor = new SemaphoreSlim(1); + } + + /// + /// 是否有人在等待 + /// + public bool HasWaiter => _waiter.CurrentCount == 0; + + /// + /// 是否拥有异常 + /// + public bool HasFaulted => LastException != null; + + /// + /// 返回最后一个错误 + /// + public Exception LastException { get; private set; } + + /// + /// 尝试入队执行,如果已经有一个等待着,放弃入队尝试 + /// + /// + /// + public bool TryEnqueue(Func taskGenerator) + { + // 如果已经拥有一个等待者,return false; + if (_waiter.Wait(0) == false) + return false; + + Task.Run(async () => + { + // 得到等待权,开始等待执行 + await _executor.WaitAsync(); + + // 得到执行权,我不再是等待者,释放等待权信号,让给下一个等待者 + _waiter.Release(); + + try + { + await taskGenerator(); + } + catch (Exception ex) + { + LastException = ex; + } + finally + { + // 释放执行信号 + _executor.Release(); + } + }); + + return true; + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/IConfigStore.cs b/Grinder.Infrastructure/Config/Configuration/IConfigStore.cs new file mode 100644 index 0000000..7c2cba7 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/IConfigStore.cs @@ -0,0 +1,47 @@ +using System.Threading.Tasks; +using grinder.Configuration.Helper; + +namespace grinder.Configuration +{ + /// + /// 配置信息持久化接口 + /// + /// 取消持久化的目标流,持久化方法自己完成实现 + public interface IConfigStore + { + /// + /// 从数据流中加载 配置文件 对象 + /// + /// + Task LoadAsync(); + + + /// + /// 加载配置文件对象 + /// + /// + ConfigData Load(); + + + /// + /// 配置文件保存至数据流 + /// + /// 配置信息数据 + /// + Task SaveAsync(ConfigData data); + + + /// + /// 配置文件保存至数据流 + /// + /// + /// + void Save(ConfigData data); + + + /// + /// 数据源变更事件 + /// + event AsyncEventHandler SourceChanged; + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs b/Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs new file mode 100644 index 0000000..f95086e --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs @@ -0,0 +1,14 @@ +namespace grinder.Configuration +{ + /// + /// 接口负责把默认的配置文件参数持久化(这样一来用户可以直接修改被持久化的文件,提高效率) + /// + public interface IDefaultConfigWriter + { + /// + /// 把默认值持久化写入 + /// + /// + void WriteDefaultValue(); + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs b/Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs new file mode 100644 index 0000000..31cc228 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace grinder.Configuration +{ + /// + /// 需要持久化的设置参数特性头声明 + /// + public class PersistencePropertyAttribute : Attribute + { + public object DefaultValue { get; } + + public PersistencePropertyAttribute(object defaultValue) + { + DefaultValue = defaultValue; + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/README.md b/Grinder.Infrastructure/Config/Configuration/README.md new file mode 100644 index 0000000..9ebac5c --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/README.md @@ -0,0 +1,303 @@ +| Property | Value +|:-------------|:----------------------- +| Project Name | Configuration +| Author | Liu Wan Li +| Create Time | 2019-04-09 + + +| Date | Author | Description +|:-------------|:-----------|:------------------------------------- +| 2019-05-09 | Liu Wan Li | 重构配置参数模块,并更新文档 + + +# Summary +该模块用来为处理配置信息提供支持 +- 支持配置信息呈树状结构呈现 +- 支持配置信息多种方式的持久化 + +# Concept +**ConfigSection** + +ConfigSection 为配置资源的核心对象。一个 ConfigSection 就像一个目录,用来保存多个 +由 ConfigSection 和 object 组成的集合。参数信息以 object 的形态,保存于 ConfigSection +的集合中。 + +**Value** + +Value 用来保存参数的具体数据,可以为多种基础数据类型,例如 int double Guid DateTime等。 +值以 object 的形式保存与配置参数中,调用者需要清楚的了解值的类型。通过以下方法读取值: +```C# +// 调用者需清楚的知道,返回的数据类型为 int,在调用时传入期待返回的值类型 +var path = "Employee.Age"; +int value = data.GetValue(path); +``` + +> 原则上,Value 参数可以为任何类型,但是受限制于目前持久化的的设计,仅支持基础数据类型,例如 int string +> double float DateTime Guid 等。如果有需要,再扩充这部分功能。 + +从下图中可以看出,ConfigSection 就像 Windows 的目录,可以保存子 ConfigSection,亦可保存 Value。 + +![Configuration Concept](Document/configuration-concept.png) + +**Path** + +Path 为路径,用来读取或者写入配置文件提供查找的方式。例如上图中,通过 +路径 Section1.Section2.Value1 可以获取到相应存储的值。 + +路径之间使用 "." 进行分隔,路径名称取名原则上考虑序列化目标的命名约束情况, +建议使用字母开头,可以包含字母和数字的一个字符串。 + +路径名有以下约束: +- 不得为 null 或者空字符串或者仅空格的字符串 +- 大小写敏感 +- 不得含有路径分隔符 + +# Usage + +这部分介绍配置参数的两种读写方式、以及数据保存部分对象结构。 + +可以通过字典操作的方法,读写配置参数,也可以通过强类型的方法读写。 + +## 字典方式读写 + +调用者通过传入路径字符串读取或者写入值。 + +```C# +// 设置员工的年龄 +data.SetValue("Employee.Age", 30); + +// 读取员工年龄时,第二个参数为默认值,当读取失败时,返回该默认值 +int age = data.GetValue("Employee.Age", 0); // should return 30 +int value = data.GetValue("Employee.NewField", -1); // should return -1 +``` + +> **注意** +> 编译器可以通过参数类型,推断出 `data.SetValue(path, age);` 的方法泛型类型, +> 因此直接写为`data.SetValue(path, age)`即可,后续代码我将省略泛型类型; + +读写时也可以读取出一个Section,然后单独操作该Section读写方法,代码如下; + +```C# +// 初始化一个含有一个 Employee 节点的配置对象 +var root = new ConfigSection(rootSect => +{ + rootSect.SetValue("Employee", new ConfigSection(employeeSection => + { + employeeSection.SetValue("Name", "Nepton"); + employeeSection.SetValue("Sex", "M"); + employeeSection.SetValue("Age", 38); + employeeSection.SetValue("DateOfJoin", new DateTime(2019, 2, 26)); + })); +}); + +// 读取 employee 节点 +var employee = root.GetSection("Employee"); +Assert.IsNotNull(employee); + +// 通过使用 employee 读取,注意使用相对路径 +string name = employee.GetValue("Name", ""); // should return "Nepton" +int age = employee.GetValue("Age", 0); // should return 38 +string sex = employee.GetValue("Sex", ""); // should return "M" +``` + +## 强类型对象 + +### 定义 + +基于字典的读取方式灵活,但是可能出现由于路径拼写错误而无法正确读写内容的情况。可以定义配置文件对象, +通过强命名的方式读写配置信息,尽可能避免防止出现路径拼写错误的情况。使用强类型对象的步骤: +1. 创建一个配置文件类,继承于 ConfigBase +2. 重写 Path 属性,提供该对象读取配置参数的路径 +3. 定义需要的参数,例如 LineWidth,调用基类的 GetValue 和 SetValue 读写配置属性 + +下边为演示代码 +```C# +public class YourConfig : ConfigBase +{ + public YourConfig(IConfigSection configSection) : base(configSection) { } + + public override string Path => "GeometryEditor.Appearance"; + + public int LineWidth + { + get => GetValue(1); + set => SetValue(value); + } +} +``` + +### 使用 + +使用 YourConfig 对象可以通过以下几种方式进行 + +1. 使用 Ioc 注入的方式,在构造函数处注入对象 + +```C# +public class YourClass +{ + private YourConfig _config; + + public YourClass(YourConfig config) + { + _config = config; + } + + public void YourMethod() + { + // 读取信息 + var lineWidth = _config.LineWidth; + + // 保存信息 + _config.LineWidth = 5; + } +} +``` + +2. 通过创建对象的方式读写配置参数 +```C# +public class YourClass +{ + public void YourMethod() + { + // 初始化 通过对象创建的方式创建 config 对象 + var configData = _resolver.Resolve(); + var config = new YourConfig(configData); + + // 读取信息 + var lineWidth = config.LineWidth; + + // 保存信息 + config.LineWidth = 5; + } +} +``` + +3. 通过单件模式创建 +```C# +public class YourClass +{ + public void YourMethod() + { + // 如果配置信息对象通过静态属性的方式创建了单件实例,通过该方法获取配置对象 + var config = YourConfig.Instance; + + // 读取信息 + var lineWidth = config.LineWidth; + + // 保存信息 + config.LineWidth = 5; + } +} +``` + +## 实现持久化存储 + +IConfigStore 定义了配置参数持久化存储的接口,LoadAsync方法用来从持久化流读取数据;SaveAsync用 +来把配置参数数据写入到持久化存储区;而SourceChanged用来监听持久化存储区是否由外界更改了数据内容。 + +```C# +public interface IConfigStore +{ + Task LoadAsync(); + + Task SaveAsync(ConfigSection sections); + + event AsyncEventHandler SourceChanged; +} + +``` +> 目前 IConfigStore 没有针对IConfigSection,而针对实例类 ConfigSection + +目前实现了 JSON 文件格式的持久化模块,具体参见项目 Configuration.Store.Json,使用方法如下: + +```C# +var fileStream = new FileStreamProvider("config.json"); +var jsonStore = new JsonConfigStore(fileStream); + +var configSection = await jsonStore.LoadAsync(); +var employeeName = configSection.GetValue("Employee.Name"); +``` + +存储的数据按照对象的层级进行了格式化,开发人员或者部署人员可以通过第三方工具轻松的调整设置参数。 + +```JSON +{ + "Emplopyee": { + "Name": "Nepton", + "Sex" : "M" + } +} +``` + +## 在项目中配置 + +ConfigData 继承于 ConfigSection,除了用来保存配置信息以外,ConfigData 引入了 IConfigStore,用来持久化保存配置参数 +信息至磁盘、数据库等位置。 + +该对象可以以单件的方式,注册在Ioc中,并关联 IConfigSection 接口,强类型的对象注入时引用 ConfigData 对象,实现 +全局数据的静态读写。 + +```c# +// 注册配置文件模块 +var configFilePath = Path.Combine( + AppDomain.CurrentDomain.BaseDirectory, "setting.json"); + +containerRegistry.RegisterInstance( + new JsonConfigStore(new FileStreamProvider(configFilePath))); +containerRegistry.RegisterSingleton(); +``` + +手动保存配置信息,如果要批量设置参数后,一次性保存,可以设置为手动保存配置信息,那么在适当的时候,请调 +用 SaveAsync(或者相应同步方法)执行保存操作。 +```C# +public class YourClass +{ + public async Task YourMethod() + { + var configData = _resolver.Resolve(ConfigData); + await configData.SaveAsync(); // 或者 configData.Save(); 同步调用 + } +} +``` + +手动重新读取配置信息,如果外部配置信息改变,或者在手动保存模式下,想撤销内存的更改,调用 +LoadAsync(或者相应同步方法)执行读取操作,当读取完成后,内存数据将丢失。 + +```C# +public class YourClass +{ + public async Task YourMethod() + { + // 调用Save函数立即保存 + var configData = _resolver.Resolve(ConfigData); + await configData.LoadAsync(); // 或者 configData.Load(); 同步调用 + } +} +``` + +# Struction + +下图是配置参数对象关系静态图: + +![Configuration Class Dependencies Graph](Document/configuration-class-dependencies-graph.png) + +- **IConfigSection** + 接口 IConfigSection 声明了保存配置参数以及子 Section 的对象功能的函数声明,具体实现类为 ConfigSection + +- **ConfigSection** + 接口 IConfigSection 的默认实现版本 + +- **ConfigData** + 继承于 ConfigSection,在基类的基础上扩展并提供了持久化存储的功能,与接口 IConfigStore 建立了关系。 + +- **IConfigStore** + 接口 IConfigStore 声明了一个持久化存储对象如何把 IConfigSection 进行存储,以及如何读取存储数据并生成 IConfigSection 的对象。 + +- **ConfigBase** + ConfigBase 类包装了 IConfigSection,并提供一套机制让开发者实现强类型检查的配置参数对象。 + +- **ConfigPath** + 这是一个辅助类,负责处理路径解析,例如 Employee.Age 这样的配置参数查询路径的解析工作由 ConfigPath 处理 + +> Notice +> 其他类仅负责处理周边的代码和功能,不一一详细描述 diff --git a/Grinder.Infrastructure/Config/Configuration/SaveMethods.cs b/Grinder.Infrastructure/Config/Configuration/SaveMethods.cs new file mode 100644 index 0000000..5fe4c66 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/SaveMethods.cs @@ -0,0 +1,18 @@ +namespace grinder.Configuration +{ + /// + /// 刷新至数据库的方法 + /// + public enum SaveMethods + { + /// + /// 当属性更新时,自动更新 + /// + PropertyChanged, + + /// + /// 手动刷新 + /// + Manual, + } +} \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs b/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs new file mode 100644 index 0000000..dcfaabc --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using grinder.Configuration.Helper; +using grinder.Configuration.StreamProvider; + +namespace grinder.Configuration.Store.Json +{ + /// + /// JSON 配置文件转换流 + /// + public class JsonConfigStore : IConfigStore + { + /// + /// 配置文件读写流(这个设计到技术资源,例如磁盘, 单独抽出来为了更好的单元测试) + /// + private readonly IStreamProvider _configStream; + + public JsonConfigStore(IStreamProvider configStream) + { + if (configStream == null) + throw new ArgumentNullException(nameof(configStream)); + + _configStream = configStream; + } + + /// + /// 数据源由外部更新事件 + /// + public event AsyncEventHandler SourceChanged + { + add + { + if (_configStream is IStreamProviderWithNotification streamProviderWithNotification) + streamProviderWithNotification.StreamSourceChanged += value; + } + remove + { + if (_configStream is IStreamProviderWithNotification streamProviderWithNotification) + streamProviderWithNotification.StreamSourceChanged -= value; + } + } + + #region Implementation of IConfigStream + + /// + /// 从数据流中加载 配置文件 对象 + /// + /// + public async Task LoadAsync() + { + await using (var stream = _configStream.OpenRead()) + { + using var reader = new StreamReader(stream); + // 读取配置信息 + var settingString = await reader.ReadToEndAsync(); + if (string.IsNullOrEmpty(settingString)) + return new ConfigData(); + + return ExtraSettingFromString(settingString); + } + } + + /// + /// 加载配置文件对象 + /// + /// + public ConfigData Load() + { + using (var stream = _configStream.OpenRead()) + using (var reader = new StreamReader(stream)) + { + // 读取配置信息 + var settingString = reader.ReadToEnd(); + if (string.IsNullOrEmpty(settingString)) + return new ConfigData(); + + return ExtraSettingFromString(settingString); + } + } + + /// + /// 配置文件保存至数据流 + /// + /// 配置信息数据 + /// + public async Task SaveAsync(ConfigData section) + { + string settingString = GenerateSettingString(section); + await using (var stream = _configStream.OpenWrite()) + await using (var writer = new StreamWriter(stream)) + { + await writer.WriteAsync(settingString); + await writer.FlushAsync(); + } + } + + + /// + /// 配置文件保存至数据流 + /// + /// 配置信息数据 + /// + public void Save(ConfigData section) + { + string settingString = GenerateSettingString(section); + using (var stream = _configStream.OpenWrite()) + using (var writer = new StreamWriter(stream)) + { + writer.Write(settingString); + writer.Flush(); + } + } + + /// + /// 生成设置参数字符串 + /// + /// + /// + private static string GenerateSettingString(ConfigData data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + + // 转换为一个Dictionary嵌套,然后写入 + + var stack = new Stack>>(); + var referenced = new HashSet(); // 保存已经读取的节点 + + var rootDict = new Dictionary(); + stack.Push(new Tuple>("", rootDict)); + + // 递归转换 + while (stack.Any()) + { + var cur = stack.Pop(); + var curPath = cur.Item1; + var curDict = cur.Item2; + + // 检查循环引用 + if (referenced.Contains(curPath)) + throw new ArgumentException("Circular reference in config section"); + referenced.Add(curPath); + + // 处理值 + var valuePaths = data.GetChildrenNodes(curPath, false); + foreach (var valuePath in valuePaths) + { + var path = ConfigPath.CombinePath(curPath, valuePath); + var cp = new ConfigPath(valuePath); + var configValue = data.OpenConfigValue(path); + + var value = configValue.Value; + + // 处理枚举 + if (value is Enum e) + value = e.ToString(); + + curDict.Add(cp.Current, value); + } + + // 处理节点 + var sectionPaths = data.GetChildrenNodes(curPath, true); + foreach (var sectionPath in sectionPaths) + { + var path = ConfigPath.CombinePath(curPath, sectionPath); + + var dictionary = new Dictionary(); + var cp = new ConfigPath(sectionPath); + curDict.Add(cp.Current, dictionary); + + stack.Push(new Tuple>(path, dictionary)); + } + } + + // 执行序列化,并写到流中 + var settingString = JsonConvert.SerializeObject(rootDict, Formatting.Indented); + return settingString; + } + + #endregion + + /// + /// 解析处理设置参数 + /// + /// + /// + private static ConfigData ExtraSettingFromString(string settingString) + { + // 执行转换 + var root = JsonConvert.DeserializeObject(settingString) as JObject; + var data = new ConfigData(); + var stack = new Stack>(new[] + { + new Tuple(root, "") + }); + var referenced = new HashSet(); + + // 递归执行JObject至ConfigSection的转换 + while (stack.Any()) + { + var cur = stack.Pop(); + var curItem = cur.Item1; + var curPath = cur.Item2; + + // 引用检查 + if (referenced.Contains(curItem)) + continue; + referenced.Add(curItem); + + // 执行本次转换 + foreach (var item in curItem) + { + var combinePath = ConfigPath.CombinePath(curPath, item.Key); + + if (item.Value == null) + continue; + + // 如果是一个 JObject,递归转换下去 + if (item.Value is JObject jObject) + { + stack.Push(new Tuple(jObject, combinePath)); + continue; + } + + // 处理值 + if (item.Value is JValue jValue) + { + var cv = data.OpenOrCreateConfigValue(combinePath); + cv.Value = jValue.Value; + continue; + } + + throw new NotSupportedException($"Object type {item.Value.GetType().Name} is not supported"); + } + } + + return data; + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.md b/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.md new file mode 100644 index 0000000..b6cc1fc --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.md @@ -0,0 +1,9 @@ +| Property | Value +|:-------------|:----------------------- +| Project Name | ConfigStream.Json +| Author | Liu Wan Li +| Create Time | 2019-04-09 + +# Summary +这个项目实现一个Json 文件格式的配置文件持久化版本。采用 Newtonsoft.Json 作为转换提供 +接口的定义在 TampingFoundation 项目的 Configs 中 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs new file mode 100644 index 0000000..14820ae --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using grinder.Configuration.Helper; +using Serilog; + +namespace grinder.Configuration.StreamProvider +{ + /// + /// 文件流提供者 + /// + public class FileStreamProvider : IStreamProviderWithNotification + { + private readonly string _filePath; + + /// + /// 构造函数 + /// + /// 文件名,包含文件全路径 + /// 监视文件更改 + public FileStreamProvider(string filePath, bool watchForChanged = false) + { + if (filePath == null) + throw new ArgumentNullException(nameof(filePath)); + + if (watchForChanged) + { + Task.Run(() => WatchForChanged(filePath)); + } + + _filePath = filePath; + } + + /// + /// 监视文件更改 + /// + /// 文件路径 + /// + private async Task WatchForChanged(string filePath) + { + var watcher = new FileSystemWatcher(filePath); + int errorCount = 0; + + while (true) + { + try + { + watcher.WaitForChanged(WatcherChangeTypes.All); + + await Task.Delay(1000); + StreamSourceChanged?.Invoke(this, EventArgs.Empty); + } + catch (Exception ex) + { + errorCount += 1; + if (errorCount > 100) + { + Log.Error(ex, "Configuration file watching ERR, terminal."); + return; + } + + Log.Error(ex, "Configuration file watching ERR, retry after 5 seconds."); + await Task.Delay(5000); + } + } + } + + /// + /// 流更新事件。 + /// 注意:OpenWrite 写入流不会激发该事件,该事件由程序外部激发调用 + /// + public event AsyncEventHandler StreamSourceChanged; + + #region Implementation of IStreamProvider + + /// + /// 以读取的方式打开流 + /// + /// + public Stream OpenRead() + { + if (File.Exists(_filePath)) + return File.OpenRead(_filePath); + + // 文件不存在, 返回空流 + return new MemoryStream(); + } + + /// + /// 为写入打开流 + /// + /// + public Stream OpenWrite() + { + var fullPath = Path.GetFullPath(_filePath); + var dir = Path.GetDirectoryName(fullPath); + + if (string.IsNullOrEmpty(dir)) + throw new Exception($"Invalid file path: {_filePath}"); + + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + + return File.Create(_filePath); + } + + #endregion + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs new file mode 100644 index 0000000..0b2f5e3 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs @@ -0,0 +1,22 @@ +using System.IO; + +namespace grinder.Configuration.StreamProvider +{ + /// + /// 数据流提供接口,例如内存流,文件流等 + /// + public interface IStreamProvider + { + /// + /// 以读取的方式打开流 + /// + /// + Stream OpenRead(); + + /// + /// 为写入打开流 + /// + /// + Stream OpenWrite(); + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs new file mode 100644 index 0000000..07a3bc7 --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs @@ -0,0 +1,16 @@ +using grinder.Configuration.Helper; + +namespace grinder.Configuration.StreamProvider +{ + /// + /// 含有通知消息的接口 + /// + public interface IStreamProviderWithNotification : IStreamProvider + { + /// + /// 流更新事件。 + /// 注意:OpenWrite 写入流不会激发该事件,该事件由程序外部激发调用 + /// + event AsyncEventHandler StreamSourceChanged; + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs new file mode 100644 index 0000000..3cda0ee --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +namespace grinder.Configuration.StreamProvider +{ + /// + /// 内存流提供者,主要用于单元测试 + /// + public class MemoryStreamProvider : IStreamProvider + { + private MemoryStream _stream = new MemoryStream(); + + public MemoryStreamProvider() + { + } + + /// Initializes a new instance of the class. + public MemoryStreamProvider(MemoryStream stream) + { + if (stream == null) + throw new ArgumentNullException(nameof(stream)); + + _stream = stream; + } + + /// + /// 内存流 + /// + public byte[] Buffer => _stream.ToArray(); + + #region Implementation of IStreamProvider + + /// + /// 以读取的方式打开流 + /// + /// + public Stream OpenRead() + { + var buffer = _stream.ToArray(); + var stream = new MemoryStream(buffer, false); + + return stream; + } + + /// + /// 为写入打开流 + /// + /// + public Stream OpenWrite() + { + _stream = new MemoryStream(); + return _stream; + } + + #endregion + } +} diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/ConfigDataTests.cs b/Grinder.Infrastructure/Config/ConfigurationTests/ConfigDataTests.cs new file mode 100644 index 0000000..bafd5dc --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/ConfigDataTests.cs @@ -0,0 +1,158 @@ +using System; +using FirstLineTamping.Configuration; +using Moq; +using NUnit.Framework; + +namespace ConfigurationTests +{ + [TestFixture()] + public class ConfigDataTests + { + /// + /// 正常读写 + /// + [Test()] + public void PathSetValue() + { + var data = new Config(); + + string path = "Employee.Age"; + int age = 30; + + // 设置员工的年龄 + data.SetValue(path, age); + + // 读取时,第二个参数为默认值,当读取失败时,返回该默认值 + int actual = data.GetValue(path, 0); + + Assert.AreEqual(age, actual); + } + + [Test] + public void TestEmployee() + { + // 初始化一个含有一个 Employee 节点的配置对象 + var root = new Config(); + var employee = root.GetSection("Employee"); + employee.SetValue("Name", "Nepton"); + employee.SetValue("Sex", "M"); + employee.SetValue("Age", 38); + employee.SetValue("DateOfJoin", new DateTime(2019, 2, 26)); + + // 读取 employee 节点 + employee = root.GetSection("Employee"); + Assert.IsNotNull(employee); + + // 通过使用 employee 读取,注意使用相对路径 + string name = employee.GetValue("Name", ""); // should return "Nepton" + int age = employee.GetValue("Age", 0); // should return "38" + string sex = employee.GetValue("Sex", ""); // should return "M" + + Assert.AreEqual("Nepton", name); + Assert.AreEqual(38, age); + Assert.AreEqual("M", sex); + } + + + /// + /// 正常读写 + /// + [Test()] + public void PathSetValueThenGetFromBranch() + { + var data = new Config(); + const int expected = 100; + + // 分两段设置 + data.SetValue("A.B.C.D.E", expected); + + // 另一种方式分两段读取 + var a = data.GetSection("A"); + var bc = a.GetSection("B.C"); + var de = bc.GetValue("D.E"); + + Assert.AreEqual(expected, de); + } + + /// + /// 正常读写 + /// + [Test()] + public void PathSetValueThenGetFromBranch2() + { + var data = new Config(); + const int expected = 100; + + // 分两段设置 + data.SetValue("A.B.C.D.E", expected); + + // 另一种方式分两段读取 + var actual = data.GetSection("A.B.C").GetValue("D.E", 0); + + Assert.AreEqual(expected, actual); + } + + + /// + /// 测试无效路径 + /// + [Test] + public void PassIncorrectPath_Throw() + { + var data = new Config(); + + var invalidPaths = new[] + { + "A. .B", + "", + ".", + "A..B", + "A.", + ".B", + "..B", + null, + }; + + foreach (var path in invalidPaths) + { + Assert.That(() => data.SetValue(path, 100), Throws.Exception.AssignableTo()); + Assert.That(() => data.GetValue(path, 100), Throws.Exception.AssignableTo()); + } + } + + /// + /// 测试属性更改的时候正确调用保存 + /// + [Test] + public void SetValueThenSerializeToStore() + { + var mock = new Mock(); + var data = new Config(mock.Object) + { + SaveMethod = SaveMethods.PropertyChanged + }; + + data.SetValue("A", 100); + mock.Verify(c => c.SaveAsync(It.IsNotNull()), Times.Once); + } + + /// + /// 把一个Section读出来,单独修改,ConfigData内数据同步变化 + /// + [Test] + public void ValidateSectionReference() + { + var configData = new Config(); + configData.SetValue("Name.LastName", "Liu"); + + var nameSection = configData.GetSection("Name"); + + nameSection.SetValue("LastName", "Fu"); + Assert.AreEqual(nameSection.GetValue("LastName"), configData.GetValue("Name.LastName")); + + var name2Section = configData.GetSection("Name"); + name2Section.SetValue("LastName", "Hang"); + Assert.AreEqual(nameSection.GetValue("LastName"), name2Section.GetValue("LastName")); + } + } +} diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj b/Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj new file mode 100644 index 0000000..17ad922 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj @@ -0,0 +1,173 @@ + + + + + + Debug + AnyCPU + {8BB020AD-7BF9-49E8-A7CF-BEA438FF7760} + Library + Properties + ConfigurationTests + ConfigurationTests + v4.6.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + 7.0 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + 7.0 + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + 6 + prompt + MinimumRecommendedRules.ruleset + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + ..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll + + + ..\packages\CommonServiceLocator.2.0.4\lib\net46\CommonServiceLocator.dll + + + ..\packages\Moq.4.10.1\lib\net45\Moq.dll + + + ..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll + True + + + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + ..\packages\Unity.5.11.1\lib\net46\Unity.Abstractions.dll + + + ..\packages\Unity.5.11.1\lib\net46\Unity.Container.dll + + + + + + + + + + + + + + + + + + + + + {5D22F933-5BF8-4DB1-BE3C-CAC8765DABCE} + Configuration.Store.Json + + + {E70AADB2-1940-454B-8BFF-1A674F7D39F0} + Configuration + + + {971A0CC3-AFAF-4FA8-AE17-446534A349B1} + TampingDbService + + + {B3F4ED07-9A02-4926-B827-3AFA00330E58} + TampingInfrastructure + + + {F9A128D3-2CCB-4918-9B96-3DA8DDAF3AB5} + TampingContract + + + + + + + + + + + False + + + False + + + False + + + False + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj.DotSettings b/Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj.DotSettings new file mode 100644 index 0000000..73e9656 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/ConfigurationTests.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp60 \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/OneWaiterTaskQueueTests.cs b/Grinder.Infrastructure/Config/ConfigurationTests/OneWaiterTaskQueueTests.cs new file mode 100644 index 0000000..f3050a1 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/OneWaiterTaskQueueTests.cs @@ -0,0 +1,62 @@ +using System; +using System.Threading.Tasks; +using FirstLineTamping.Configuration; +using FirstLineTamping.Configuration.Helper; +using NUnit.Framework; + +namespace ConfigurationTests +{ + [TestFixture()] + public class OneWaiterTaskQueueTests + { + /// + /// 测试任务队列正确性 + /// + [Test()] + public void TryEnqueueTest() + { + var queue = new OneWaiterTaskQueue(); + + // 第一个任务入队 + var result = queue.TryEnqueue(LongTimeTask); + Assert.IsTrue(result); + + // 第二个任务入队 + result = queue.TryEnqueue(LongTimeTask); + Assert.IsTrue(result); + Assert.IsTrue(queue.HasWaiter); + + // 第三个任务入队 + result = queue.TryEnqueue(LongTimeTask); + Assert.IsFalse(result); + } + + public async Task LongTimeTask() + { + // 在单元测试函数完成前,不要退出 + await Task.Delay(10000000); + } + + /// + /// 测试任务队列遇到异常情况 + /// + [Test()] + public void TryEnqueueHasException() + { + var queue = new OneWaiterTaskQueue(); + + var ex = new NotSupportedException("Not Supported"); + + var result = queue.TryEnqueue(()=>ExceptionTask(ex)); + Assert.IsTrue(result); + Assert.IsTrue(queue.HasFaulted); + Assert.AreEqual(ex, queue.LastException); + } + + public Task ExceptionTask(NotSupportedException ex) + { + throw ex; + } + + } +} diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/PermissionTest.cs b/Grinder.Infrastructure/Config/ConfigurationTests/PermissionTest.cs new file mode 100644 index 0000000..bba32d5 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/PermissionTest.cs @@ -0,0 +1,97 @@ +using CommonServiceLocator; +using FirstLineTamping.Configuration; +using Moq; +using FirstLineTamping.Contract.Authorities; +using NUnit.Framework; +using TampingDbService.Entities; +using TampingDbService.Entities.Users; +using Unity; + +namespace ConfigurationTests +{ + [TestFixture] + public class PermissionTest + { + /// + /// 含有权限的读写, 允许操作 + /// + [Test] + public void AuthorityPermitTest() + { + var admin = new User("admin", "", new UserAuthority(Authority.All)); + + var loginUserSessionMock = new Mock(); + loginUserSessionMock.Setup(c => c.GetLoginUser()).Returns(admin); + + // register service locator + var serviceLocatorMock = new Mock(); + serviceLocatorMock.Setup(c => c.GetInstance()).Returns(loginUserSessionMock.Object); + ServiceLocator.SetLocatorProvider(() => serviceLocatorMock.Object); + + var cs = new Config(); + var path = "Employee.Name"; + cs.SetAuthority(path, new ObjectAuthority(Authority.Anonymous), new ObjectAuthority(Authority.Anonymous)); + + var nepton = "Nepton"; + cs.SetValue(path, nepton); + var actual = cs.GetValue(path, ""); + + Assert.AreEqual(nepton, actual); + } + + + /// + /// 含有权限的读写,拒绝,并抛异常 + /// + [Test] + public void AuthorityDenyTest() + { + var baby = new User("admin", "", new UserAuthority(Authority.None)); + + var loginUserSessionMock = new Mock(); + loginUserSessionMock.Setup(c => c.GetLoginUser()).Returns(baby); + + // register service locator + var serviceLocatorMock = new Mock(); + serviceLocatorMock.Setup(c => c.GetInstance()).Returns(loginUserSessionMock.Object); + ServiceLocator.SetLocatorProvider(() => serviceLocatorMock.Object); + + var cs = new Config(); + var path = "Employee.Name"; + cs.SetAuthority(path, new ObjectAuthority(Authority.Anonymous), new ObjectAuthority(Authority.Anonymous)); + + var nepton = "Nepton"; + Assert.Throws(() => cs.SetValue(path, nepton)); + Assert.Throws(() => cs.GetValue(path, "")); + } + + + /// + /// 含有权限的读写,拒绝,并抛异常 + /// + [Test] + public void AuthorityReadOnlyTest() + { + var user = new User("test", "", new UserAuthority(Authority.Anonymous)); + + var loginUserSessionMock = new Mock(); + loginUserSessionMock.Setup(c => c.GetLoginUser()).Returns(user); + + // register service locator + var serviceLocatorMock = new Mock(); + serviceLocatorMock.Setup(c => c.GetInstance()).Returns(loginUserSessionMock.Object); + ServiceLocator.SetLocatorProvider(() => serviceLocatorMock.Object); + + var cs = new Config(); + var path = "Employee.Name"; + var nepton = "Nepton"; + cs.SetValue(path, nepton); + + cs.SetAuthority(path, new ObjectAuthority(Authority.Anonymous), new ObjectAuthority(Authority.Engineer)); + Assert.Throws(() => cs.SetValue(path, "Test123")); + + var actual = cs.GetValue(path, ""); + Assert.AreEqual(nepton, actual); + } + } +} diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/Properties/AssemblyInfo.cs b/Grinder.Infrastructure/Config/ConfigurationTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9d44b81 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ConfigurationTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConfigurationTests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8bb020ad-7bf9-49e8-a7cf-bea438ff7760")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTest.cs b/Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTest.cs new file mode 100644 index 0000000..20574fa --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTest.cs @@ -0,0 +1,35 @@ +using CommonServiceLocator; +using FirstLineTamping.Contract.Authorities; +using Moq; +using NUnit.Framework; +using NUnit.Framework.Internal; +using TampingDbService.Entities; +using TampingDbService.Entities.Users; + +namespace ConfigurationTests +{ + [TestFixture] + public class StrongNameConfigTest + { + /// + /// 强命名配置测试 + /// + [Test] + public void StrongNameAuthorityConfigTest() + { + var loginUserSessionMock = new Mock(); + loginUserSessionMock.Setup(c => c.GetLoginUser()).Returns(new User("Operate", "", new UserAuthority(Authority.Operator, Authority.None))); + + // register service locator + var serviceLocatorMock = new Mock(); + serviceLocatorMock.Setup(c => c.GetInstance()).Returns(loginUserSessionMock.Object); + ServiceLocator.SetLocatorProvider(() => serviceLocatorMock.Object); + + var config = new StrongNameConfigTestSample(); + + var age = 38; + Assert.Throws(() => config.Age = age); + Assert.AreEqual(0, config.Age); + } + } +} diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTestSample.cs b/Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTestSample.cs new file mode 100644 index 0000000..8ecdedc --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/StrongNameConfigTestSample.cs @@ -0,0 +1,38 @@ +using FirstLineTamping.Configuration; +using FirstLineTamping.Contract.Authorities; + +namespace ConfigurationTests +{ + public class StrongNameConfigTestSample : ConfigBase + { + /// + /// 构造函数, + /// + public StrongNameConfigTestSample() : base(new Config()) + { + } + + /// + /// 定义作用域(包) + /// 在多个配置文件合并的时候,用来区分不同的作用域 + /// + public override string PathName => "Employee"; + + /// + /// 年龄 + /// + [ConfigAuthorize(Authority.Anonymous | Authority.Operator, + Authority.Engineer | Authority.Remote)] + public int Age + { + get + { + return GetPropertyValue(0); + } + set + { + SetPropertyValue(value); + } + } + } +} diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/app.config b/Grinder.Infrastructure/Config/ConfigurationTests/app.config new file mode 100644 index 0000000..58b89cf --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Grinder.Infrastructure/Config/ConfigurationTests/packages.config b/Grinder.Infrastructure/Config/ConfigurationTests/packages.config new file mode 100644 index 0000000..6fb0702 --- /dev/null +++ b/Grinder.Infrastructure/Config/ConfigurationTests/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/GrinderApp.Core/GrinderApp.Core.csproj b/GrinderApp.Core/GrinderApp.Core.csproj new file mode 100644 index 0000000..cc9918f --- /dev/null +++ b/GrinderApp.Core/GrinderApp.Core.csproj @@ -0,0 +1,9 @@ + + + net8.0-windows7.0 + true + + + + + \ No newline at end of file diff --git a/GrinderApp.Core/Mvvm/RegionViewModelBase.cs b/GrinderApp.Core/Mvvm/RegionViewModelBase.cs new file mode 100644 index 0000000..1453fd9 --- /dev/null +++ b/GrinderApp.Core/Mvvm/RegionViewModelBase.cs @@ -0,0 +1,35 @@ +using System; +using Prism.Regions; + +namespace GrinderApp.Core.Mvvm +{ + public class RegionViewModelBase : ViewModelBase, INavigationAware, IConfirmNavigationRequest + { + protected IRegionManager RegionManager { get; private set; } + + public RegionViewModelBase(IRegionManager regionManager) + { + RegionManager = regionManager; + } + + public virtual void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback) + { + continuationCallback(true); + } + + public virtual bool IsNavigationTarget(NavigationContext navigationContext) + { + return true; + } + + public virtual void OnNavigatedFrom(NavigationContext navigationContext) + { + + } + + public virtual void OnNavigatedTo(NavigationContext navigationContext) + { + + } + } +} diff --git a/GrinderApp.Core/Mvvm/ViewModelBase.cs b/GrinderApp.Core/Mvvm/ViewModelBase.cs new file mode 100644 index 0000000..de389ec --- /dev/null +++ b/GrinderApp.Core/Mvvm/ViewModelBase.cs @@ -0,0 +1,18 @@ +using Prism.Mvvm; +using Prism.Navigation; + +namespace GrinderApp.Core.Mvvm +{ + public abstract class ViewModelBase : BindableBase, IDestructible + { + protected ViewModelBase() + { + + } + + public virtual void Destroy() + { + + } + } +} diff --git a/GrinderApp.Core/RegionNames.cs b/GrinderApp.Core/RegionNames.cs new file mode 100644 index 0000000..1942273 --- /dev/null +++ b/GrinderApp.Core/RegionNames.cs @@ -0,0 +1,7 @@ +namespace GrinderApp.Core +{ + public static class RegionNames + { + public const string ContentRegion = "ContentRegion"; + } +} diff --git a/GrinderApp/GrinderApp.sln b/GrinderApp/GrinderApp.sln new file mode 100644 index 0000000..79a1e1f --- /dev/null +++ b/GrinderApp/GrinderApp.sln @@ -0,0 +1,66 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35514.174 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{560C8FDA-B322-4831-9947-F3597BB2FA8E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{3CF79AE9-2100-4B03-BCB0-9BD67784E06A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{3F73F93D-0B10-4FC2-BCF6-29D31151F254}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrinderApp", "GrinderApp\GrinderApp.csproj", "{4C5EE941-6B15-4CDC-91E6-B37C80D49B5A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrinderApp.Core", "..\GrinderApp.Core\GrinderApp.Core.csproj", "{57942328-DB8D-4E81-AF0F-3776A3B9DDFB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrinderApp.Services", "..\Services\GrinderApp.Services\GrinderApp.Services.csproj", "{EBF839AE-EB10-4807-979D-6983669B15E4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrinderApp.Services.Interfaces", "..\Services\GrinderApp.Services.Interfaces\GrinderApp.Services.Interfaces.csproj", "{27F6296C-6144-4508-B973-F239057B023E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrinderApp.Modules.ModuleName", "..\Modules\GrinderApp.Modules.ModuleName\GrinderApp.Modules.ModuleName.csproj", "{0644D152-A161-4687-924B-86AF1FC32F1D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Grinder.Infrastructure", "Grinder.Infrastructure", "{306C4966-F4C7-4F82-9FE3-6D04168B1421}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Configuration", "..\Grinder.Infrastructure\Config\Configuration\Configuration.csproj", "{E0A59C7B-E122-47FA-AB12-079F3A2BA43E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4C5EE941-6B15-4CDC-91E6-B37C80D49B5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C5EE941-6B15-4CDC-91E6-B37C80D49B5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C5EE941-6B15-4CDC-91E6-B37C80D49B5A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C5EE941-6B15-4CDC-91E6-B37C80D49B5A}.Release|Any CPU.Build.0 = Release|Any CPU + {57942328-DB8D-4E81-AF0F-3776A3B9DDFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57942328-DB8D-4E81-AF0F-3776A3B9DDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57942328-DB8D-4E81-AF0F-3776A3B9DDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57942328-DB8D-4E81-AF0F-3776A3B9DDFB}.Release|Any CPU.Build.0 = Release|Any CPU + {EBF839AE-EB10-4807-979D-6983669B15E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EBF839AE-EB10-4807-979D-6983669B15E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EBF839AE-EB10-4807-979D-6983669B15E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBF839AE-EB10-4807-979D-6983669B15E4}.Release|Any CPU.Build.0 = Release|Any CPU + {27F6296C-6144-4508-B973-F239057B023E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27F6296C-6144-4508-B973-F239057B023E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27F6296C-6144-4508-B973-F239057B023E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27F6296C-6144-4508-B973-F239057B023E}.Release|Any CPU.Build.0 = Release|Any CPU + {0644D152-A161-4687-924B-86AF1FC32F1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0644D152-A161-4687-924B-86AF1FC32F1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0644D152-A161-4687-924B-86AF1FC32F1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0644D152-A161-4687-924B-86AF1FC32F1D}.Release|Any CPU.Build.0 = Release|Any CPU + {E0A59C7B-E122-47FA-AB12-079F3A2BA43E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E0A59C7B-E122-47FA-AB12-079F3A2BA43E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E0A59C7B-E122-47FA-AB12-079F3A2BA43E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E0A59C7B-E122-47FA-AB12-079F3A2BA43E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {EBF839AE-EB10-4807-979D-6983669B15E4} = {3F73F93D-0B10-4FC2-BCF6-29D31151F254} + {27F6296C-6144-4508-B973-F239057B023E} = {3F73F93D-0B10-4FC2-BCF6-29D31151F254} + {0644D152-A161-4687-924B-86AF1FC32F1D} = {3CF79AE9-2100-4B03-BCB0-9BD67784E06A} + {E0A59C7B-E122-47FA-AB12-079F3A2BA43E} = {306C4966-F4C7-4F82-9FE3-6D04168B1421} + EndGlobalSection +EndGlobal diff --git a/GrinderApp/GrinderApp/App.xaml b/GrinderApp/GrinderApp/App.xaml new file mode 100644 index 0000000..1db21a2 --- /dev/null +++ b/GrinderApp/GrinderApp/App.xaml @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/GrinderApp/GrinderApp/App.xaml.cs b/GrinderApp/GrinderApp/App.xaml.cs new file mode 100644 index 0000000..6335726 --- /dev/null +++ b/GrinderApp/GrinderApp/App.xaml.cs @@ -0,0 +1,31 @@ +using System.Windows; +using GrinderApp.Modules.ModuleName; +using GrinderApp.Services; +using GrinderApp.Services.Interfaces; +using GrinderApp.Views; +using Prism.Ioc; +using Prism.Modularity; + +namespace GrinderApp +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App + { + protected override Window CreateShell() + { + return Container.Resolve(); + } + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterSingleton(); + } + + protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) + { + moduleCatalog.AddModule(); + } + } +} diff --git a/GrinderApp/GrinderApp/GrinderApp.csproj b/GrinderApp/GrinderApp/GrinderApp.csproj new file mode 100644 index 0000000..cb13924 --- /dev/null +++ b/GrinderApp/GrinderApp/GrinderApp.csproj @@ -0,0 +1,17 @@ + + + WinExe + net8.0-windows7.0 + true + + + + + + + + + + + + \ No newline at end of file diff --git a/GrinderApp/GrinderApp/ViewModels/MainWindowViewModel.cs b/GrinderApp/GrinderApp/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..9904e88 --- /dev/null +++ b/GrinderApp/GrinderApp/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,39 @@ +using GrinderApp.Core.Mvvm; +using MaterialDesignThemes.Wpf; +using Prism.Mvvm; + +namespace GrinderApp.ViewModels +{ + public class MainWindowViewModel : ViewModelBase + { + private string _title = "Prism Application"; + public string Title + { + get { return _title; } + set { SetProperty(ref _title, value); } + } + private bool _IsLightTheme = false ; + public bool IsLightTheme + { + get => _IsLightTheme; + set + { + if (SetProperty(ref _IsLightTheme, value)) + { + ModifyTheme(value); + } + } + } + private static void ModifyTheme(bool isDarkTheme) + { + var paletteHelper = new PaletteHelper(); + var theme = paletteHelper.GetTheme(); + theme.SetBaseTheme(isDarkTheme ? BaseTheme.Dark : BaseTheme.Light); + paletteHelper.SetTheme(theme); + } + public MainWindowViewModel() + { + + } + } +} diff --git a/GrinderApp/GrinderApp/Views/MainWindow.xaml b/GrinderApp/GrinderApp/Views/MainWindow.xaml new file mode 100644 index 0000000..edc1772 --- /dev/null +++ b/GrinderApp/GrinderApp/Views/MainWindow.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/GrinderApp/GrinderApp/Views/MainWindow.xaml.cs b/GrinderApp/GrinderApp/Views/MainWindow.xaml.cs new file mode 100644 index 0000000..ffdd49d --- /dev/null +++ b/GrinderApp/GrinderApp/Views/MainWindow.xaml.cs @@ -0,0 +1,164 @@ +using System.Diagnostics.CodeAnalysis; +using System; +using System.Windows; +using System.Windows.Input; +using System.Windows.Interop; +using MahApps.Metro.Controls; + +namespace GrinderApp.Views +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : MetroWindow + { + public MainWindow() + { + InitializeComponent(); + } + + #region full screen mode + bool fullScreenMode = true ; + /// + /// full screen mode. + /// we cache this value because invoke high frequency by WndProc. + /// + public bool FullScreenMode + { + get + { + // return hostConfig.FullScreenMode; + return fullScreenMode; + } + set + { + // hostConfig.FullScreenMode = value; + fullScreenMode = value; + } + } + /// + /// 更新全屏模式的风格 + /// + private void UpdateStyleWithFullScreenMode(bool fullScreenMode) + { + + + // 全屏控制 + if (fullScreenMode) // 全屏 + { + ShowMaxRestoreButton = false; // hide max restore button + ShowMinButton = false; // hide min button + ShowCloseButton = false; // hide close button + IgnoreTaskbarOnMaximize = true; // cover task bar in full screen mode + WindowState = WindowState.Maximized; // toggle maximize mode + ResizeMode = ResizeMode.NoResize; // prevent window restore by [WIN]+[LEFT] keys + IsWindowDraggable = false; // prevent title be drag + } + else + { + ShowMaxRestoreButton = true; + ShowMinButton = true; + ShowCloseButton = true; + IgnoreTaskbarOnMaximize = false; + WindowState = WindowState.Normal; + ResizeMode = ResizeMode.CanResizeWithGrip; + Width = 1280; + Height = 800; + IsWindowDraggable = true; + } + } + + /// + /// 在拖动标题移动窗口的过程中,对 IsWindowDraggable 的一个补充,默认的,如果标题条上有 TextBlock, 这些区域无法拖动 + /// + /// + protected override void OnMouseDown(MouseButtonEventArgs e) + { + // 对 IsWindowDraggable 的一个补充,默认的,如果标题条上有 TextBlock, 这些区域无法拖动 + if (!FullScreenMode && e.ChangedButton == MouseButton.Left) + { + var position = e.GetPosition(this); + if (position.Y < TitleBarHeight) + { + DragMove(); + } + } + + base.OnMouseDown(e); + } + + /// + /// register windows message function: WndProc + /// + /// + protected override void OnSourceInitialized(EventArgs e) + { + base.OnSourceInitialized(e); + var source = PresentationSource.FromVisual(this) as HwndSource; + source?.AddHook(WndProc); + } + + /// + /// process window message + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("ReSharper", "IdentifierTypo")] + [SuppressMessage("ReSharper", "CommentTypo")] + private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + const int WM_SYSCOMMAND = 0x0112; // WM_SYSCOMMAND message + const int SC_RESTORE = 0xF120; // SC_RESTORE from WM_SYSCOMMAND in wParam + + switch (msg) + { + case WM_SYSCOMMAND: + if (wParam.ToInt32() == SC_RESTORE) + { + // prevent restore from maximize by [WIN]+[DOWN] + if (FullScreenMode && WindowState == WindowState.Maximized) + { + handled = true; + } + } + + break; + } + + return IntPtr.Zero; + } + + /// + /// 防止用户使用其他方式、技巧、工具在全屏模式复原了窗体 + /// + /// + protected override void OnStateChanged(EventArgs e) + { + // 全屏模式,必须有这句话,否则用户强制 Restore 就毁了 + if (FullScreenMode && WindowState == WindowState.Maximized) + { + IsWindowDraggable = false; + ResizeMode = ResizeMode.NoResize; + } + else + { + IsWindowDraggable = true; + ResizeMode = ResizeMode.CanResizeWithGrip; + } + + base.OnStateChanged(e); + } + + + #endregion + + private void MetroWindow_Loaded(object sender, RoutedEventArgs e) + { + UpdateStyleWithFullScreenMode(FullScreenMode); + } + } +} diff --git a/Modules/GrinderApp.Modules.ModuleName/GrinderApp.Modules.ModuleName.csproj b/Modules/GrinderApp.Modules.ModuleName/GrinderApp.Modules.ModuleName.csproj new file mode 100644 index 0000000..30961fb --- /dev/null +++ b/Modules/GrinderApp.Modules.ModuleName/GrinderApp.Modules.ModuleName.csproj @@ -0,0 +1,20 @@ + + + net8.0-windows7.0 + true + + + True + + + True + + + + + + + + + + \ No newline at end of file diff --git a/Modules/GrinderApp.Modules.ModuleName/ModuleNameModule.cs b/Modules/GrinderApp.Modules.ModuleName/ModuleNameModule.cs new file mode 100644 index 0000000..116f798 --- /dev/null +++ b/Modules/GrinderApp.Modules.ModuleName/ModuleNameModule.cs @@ -0,0 +1,28 @@ +using GrinderApp.Core; +using GrinderApp.Modules.ModuleName.Views; +using Prism.Ioc; +using Prism.Modularity; +using Prism.Regions; + +namespace GrinderApp.Modules.ModuleName +{ + public class ModuleNameModule : IModule + { + private readonly IRegionManager _regionManager; + + public ModuleNameModule(IRegionManager regionManager) + { + _regionManager = regionManager; + } + + public void OnInitialized(IContainerProvider containerProvider) + { + _regionManager.RequestNavigate(RegionNames.ContentRegion, "ViewA"); + } + + public void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterForNavigation(); + } + } +} \ No newline at end of file diff --git a/Modules/GrinderApp.Modules.ModuleName/ViewModels/ViewAViewModel.cs b/Modules/GrinderApp.Modules.ModuleName/ViewModels/ViewAViewModel.cs new file mode 100644 index 0000000..1ed3209 --- /dev/null +++ b/Modules/GrinderApp.Modules.ModuleName/ViewModels/ViewAViewModel.cs @@ -0,0 +1,27 @@ +using GrinderApp.Core.Mvvm; +using GrinderApp.Services.Interfaces; +using Prism.Regions; + +namespace GrinderApp.Modules.ModuleName.ViewModels +{ + public class ViewAViewModel : RegionViewModelBase + { + private string _message; + public string Message + { + get { return _message; } + set { SetProperty(ref _message, value); } + } + + public ViewAViewModel(IRegionManager regionManager, IMessageService messageService) : + base(regionManager) + { + Message = messageService.GetMessage(); + } + + public override void OnNavigatedTo(NavigationContext navigationContext) + { + //do something + } + } +} diff --git a/Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml b/Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml new file mode 100644 index 0000000..deb483a --- /dev/null +++ b/Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml @@ -0,0 +1,13 @@ + + + + + diff --git a/Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml.cs b/Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml.cs new file mode 100644 index 0000000..e412934 --- /dev/null +++ b/Modules/GrinderApp.Modules.ModuleName/Views/ViewA.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace GrinderApp.Modules.ModuleName.Views +{ + /// + /// Interaction logic for ViewA.xaml + /// + public partial class ViewA : UserControl + { + public ViewA() + { + InitializeComponent(); + } + } +} diff --git a/Services/GrinderApp.Services.Interfaces/GrinderApp.Services.Interfaces.csproj b/Services/GrinderApp.Services.Interfaces/GrinderApp.Services.Interfaces.csproj new file mode 100644 index 0000000..f45bdfc --- /dev/null +++ b/Services/GrinderApp.Services.Interfaces/GrinderApp.Services.Interfaces.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.1 + + + diff --git a/Services/GrinderApp.Services.Interfaces/IMessageService.cs b/Services/GrinderApp.Services.Interfaces/IMessageService.cs new file mode 100644 index 0000000..58d180e --- /dev/null +++ b/Services/GrinderApp.Services.Interfaces/IMessageService.cs @@ -0,0 +1,7 @@ +namespace GrinderApp.Services.Interfaces +{ + public interface IMessageService + { + string GetMessage(); + } +} diff --git a/Services/GrinderApp.Services/GrinderApp.Services.csproj b/Services/GrinderApp.Services/GrinderApp.Services.csproj new file mode 100644 index 0000000..7388c4a --- /dev/null +++ b/Services/GrinderApp.Services/GrinderApp.Services.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.1 + Library + + + + + + + diff --git a/Services/GrinderApp.Services/MessageService.cs b/Services/GrinderApp.Services/MessageService.cs new file mode 100644 index 0000000..a0d493f --- /dev/null +++ b/Services/GrinderApp.Services/MessageService.cs @@ -0,0 +1,12 @@ +using GrinderApp.Services.Interfaces; + +namespace GrinderApp.Services +{ + public class MessageService : IMessageService + { + public string GetMessage() + { + return "Hello from the Message Service"; + } + } +} diff --git a/Tests/GrinderApp.Modules.ModuleName.Tests/GrinderApp.Modules.ModuleName.Tests.csproj b/Tests/GrinderApp.Modules.ModuleName.Tests/GrinderApp.Modules.ModuleName.Tests.csproj new file mode 100644 index 0000000..c905380 --- /dev/null +++ b/Tests/GrinderApp.Modules.ModuleName.Tests/GrinderApp.Modules.ModuleName.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0-windows7.0 + + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/Tests/GrinderApp.Modules.ModuleName.Tests/ViewModels/ViewAViewModelFixture.cs b/Tests/GrinderApp.Modules.ModuleName.Tests/ViewModels/ViewAViewModelFixture.cs new file mode 100644 index 0000000..e0695cb --- /dev/null +++ b/Tests/GrinderApp.Modules.ModuleName.Tests/ViewModels/ViewAViewModelFixture.cs @@ -0,0 +1,41 @@ +using GrinderApp.Modules.ModuleName.ViewModels; +using GrinderApp.Services.Interfaces; +using Moq; +using Prism.Regions; +using Xunit; + +namespace GrinderApp.Modules.ModuleName.Tests.ViewModels +{ + public class ViewAViewModelFixture + { + Mock _messageServiceMock; + Mock _regionManagerMock; + const string MessageServiceDefaultMessage = "Some Value"; + + public ViewAViewModelFixture() + { + var messageService = new Mock(); + messageService.Setup(x => x.GetMessage()).Returns(MessageServiceDefaultMessage); + _messageServiceMock = messageService; + + _regionManagerMock = new Mock(); + } + + [Fact] + public void MessagePropertyValueUpdated() + { + var vm = new ViewAViewModel(_regionManagerMock.Object, _messageServiceMock.Object); + + _messageServiceMock.Verify(x => x.GetMessage(), Times.Once); + + Assert.Equal(MessageServiceDefaultMessage, vm.Message); + } + + [Fact] + public void MessageINotifyPropertyChangedCalled() + { + var vm = new ViewAViewModel(_regionManagerMock.Object, _messageServiceMock.Object); + Assert.PropertyChanged(vm, nameof(vm.Message), () => vm.Message = "Changed"); + } + } +} diff --git a/UniLuaX.sln b/UniLuaX.sln index 7907d49..cf82d8e 100644 --- a/UniLuaX.sln +++ b/UniLuaX.sln @@ -3,11 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.9.34723.18 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniLuaX", "Assets\UniLua\UniLuaX.csproj", "{B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "luaEdiy", "luaEdiy\luaEdiy.csproj", "{D90D537F-B4D5-40F7-BBE4-2259C351141A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniLuaEditor", "UniLuaEditor\UniLuaEditor.csproj", "{9AAFA100-2783-4206-BA3F-E8048BC4DF1F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "luaEdiy", "luaEdiy\luaEdiy.csproj", "{C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrinderApp", "GrinderApp\GrinderApp\GrinderApp.csproj", "{F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,18 +13,14 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B2AFA056-1E01-46A2-8CC8-31DB50E47AF7}.Release|Any CPU.Build.0 = Release|Any CPU - {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9AAFA100-2783-4206-BA3F-E8048BC4DF1F}.Release|Any CPU.Build.0 = Release|Any CPU - {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C67842DD-36E8-4FE9-BDA2-C50253CB3CD5}.Release|Any CPU.Build.0 = Release|Any CPU + {D90D537F-B4D5-40F7-BBE4-2259C351141A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D90D537F-B4D5-40F7-BBE4-2259C351141A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D90D537F-B4D5-40F7-BBE4-2259C351141A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D90D537F-B4D5-40F7-BBE4-2259C351141A}.Release|Any CPU.Build.0 = Release|Any CPU + {F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F314A553-F4D4-4E2D-A860-CFE3AFDC1C04}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 2582e757f53290546948b2aa0654fcc770cff80f Mon Sep 17 00:00:00 2001 From: kmsmg Date: Mon, 23 Dec 2024 23:25:50 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E6=9C=AA=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Config/Configuration/Config.cs | 4 +- .../Config/Configuration/ConfigBase.cs | 2 +- .../Config/Configuration/ConfigData.cs | 2 +- .../Config/Configuration/ConfigDataVisitor.cs | 2 +- .../Config/Configuration/ConfigPath.cs | 2 +- .../Config/Configuration/ConfigSection.cs | 2 +- .../Config/Configuration/ConfigSectionView.cs | 29 ++ .../Config/Configuration/ConfigValue.cs | 2 +- .../Configuration/Helper/AsyncEventHandler.cs | 2 +- .../Helper/OneWaiterTaskQueue.cs | 2 +- .../Config/Configuration/IConfigStore.cs | 4 +- .../Configuration/IDefaultConfigWriter.cs | 2 +- .../PersistencePropertyAttribute.cs | 2 +- .../Config/Configuration/SaveMethods.cs | 2 +- .../Configuration/Store/JsonConfigStore.cs | 6 +- .../StreamProvider/FileStreamProvider.cs | 4 +- .../StreamProvider/IStreamProvider.cs | 2 +- .../IStreamProviderWithNotification.cs | 4 +- .../StreamProvider/MemoryStreamProvider.cs | 2 +- GrinderApp.Core/GrinderApp.Core.csproj | 6 + .../IConfigurationEditorViewLoader.cs | 13 + .../Interface/IModuleViewLoader.cs | 35 ++ GrinderApp.Core/Interface/IViewLoader.cs | 20 + GrinderApp/GrinderApp.sln | 7 + GrinderApp/GrinderApp/GrinderApp.csproj | 2 +- .../Browse/ConfigDescription.cs | 59 +++ .../Browse/ConfigSectionItem.cs | 173 ++++++++ .../Browse/ConfigValueItem.cs | 95 +++++ .../Browse/ConfigValueItem.cs.bak | 94 +++++ .../Browse/ConfigurationBrowse.xaml | 218 ++++++++++ .../Browse/ConfigurationBrowse.xaml.cs | 67 ++++ .../Browse/ConfigurationBrowseViewModel.cs | 373 ++++++++++++++++++ .../Browse/I18n.Designer.cs | 180 +++++++++ .../ConfigurationEditor/Browse/I18n.resx | 159 ++++++++ .../Browse/I18n.zh-CN.resx | 159 ++++++++ .../Browse/NullToVisibilityConverter.cs | 22 ++ .../Browse/TreeViewItem.xaml | 194 +++++++++ .../ConfigurationEditor.csproj | 63 +++ .../ConfigurationEditorModule.cs | 33 ++ .../ConfigurationEditorViewLoader.cs | 61 +++ .../Helper/BindableBaseWithDataError.cs | 90 +++++ .../Helper/BindableSelectedItemBehavior.cs | 59 +++ .../Helper/DefaultMessageBox.cs | 19 + .../Helper/FocusExtension.cs | 35 ++ .../Helper/IDialogWindow.cs | 18 + .../ConfigurationEditor/Helper/IMessageBox.cs | 54 +++ .../Helper/ValidateForAttribute.cs | 20 + .../ConfigurationEditor/MessageBoxSetting.cs | 24 ++ .../Modules/ConfigurationEditor/README.md | 28 ++ .../SectionEdit/I18n.Designer.cs | 135 +++++++ .../ConfigurationEditor/SectionEdit/I18n.resx | 144 +++++++ .../SectionEdit/I18n.zh-CN.resx | 144 +++++++ .../SectionEdit/SectionEditViewModel.cs | 145 +++++++ .../SectionEdit/SectionEditWindow.xaml | 60 +++ .../SectionEdit/SectionEditWindow.xaml.cs | 34 ++ .../Shell/ConfigurationShell.xaml | 29 ++ .../Shell/ConfigurationShell.xaml.cs | 15 + .../Shell/ConfigurationShellViewModel.cs | 9 + .../ConfigurationEditor/Value/DataType.cs | 38 ++ .../ConfigurationEditor/Value/ValueHelper.cs | 95 +++++ .../ValueEdit/I18n.Designer.cs | 153 +++++++ .../ConfigurationEditor/ValueEdit/I18n.resx | 150 +++++++ .../ValueEdit/I18n.zh-CN.resx | 150 +++++++ .../ValueEdit/ValueEditWidow.xaml | 129 ++++++ .../ValueEdit/ValueEditWidow.xaml.bak | 130 ++++++ .../ValueEdit/ValueEditWidow.xaml.cs | 41 ++ .../ValueEdit/ValueEditWidow.xaml.cs.bak | 41 ++ .../ValueEdit/ValueEditWidowViewModel.cs | 205 ++++++++++ 68 files changed, 4279 insertions(+), 25 deletions(-) create mode 100644 Grinder.Infrastructure/Config/Configuration/ConfigSectionView.cs create mode 100644 GrinderApp.Core/Interface/IConfigurationEditorViewLoader.cs create mode 100644 GrinderApp.Core/Interface/IModuleViewLoader.cs create mode 100644 GrinderApp.Core/Interface/IViewLoader.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/ConfigDescription.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/ConfigSectionItem.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs.bak create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowseViewModel.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/I18n.Designer.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/I18n.resx create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/I18n.zh-CN.resx create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/NullToVisibilityConverter.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Browse/TreeViewItem.xaml create mode 100644 GrinderApp/Modules/ConfigurationEditor/ConfigurationEditor.csproj create mode 100644 GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorModule.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorViewLoader.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Helper/BindableBaseWithDataError.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Helper/BindableSelectedItemBehavior.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Helper/DefaultMessageBox.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Helper/FocusExtension.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Helper/IDialogWindow.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Helper/IMessageBox.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Helper/ValidateForAttribute.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/MessageBoxSetting.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/README.md create mode 100644 GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.Designer.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.resx create mode 100644 GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.zh-CN.resx create mode 100644 GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditViewModel.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditWindow.xaml create mode 100644 GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditWindow.xaml.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Shell/ConfigurationShell.xaml create mode 100644 GrinderApp/Modules/ConfigurationEditor/Shell/ConfigurationShell.xaml.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Shell/ConfigurationShellViewModel.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Value/DataType.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/Value/ValueHelper.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/I18n.Designer.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/I18n.resx create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/I18n.zh-CN.resx create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/ValueEditWidow.xaml create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/ValueEditWidow.xaml.bak create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/ValueEditWidow.xaml.cs create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/ValueEditWidow.xaml.cs.bak create mode 100644 GrinderApp/Modules/ConfigurationEditor/ValueEdit/ValueEditWidowViewModel.cs diff --git a/Grinder.Infrastructure/Config/Configuration/Config.cs b/Grinder.Infrastructure/Config/Configuration/Config.cs index 16545d4..3292c69 100644 --- a/Grinder.Infrastructure/Config/Configuration/Config.cs +++ b/Grinder.Infrastructure/Config/Configuration/Config.cs @@ -6,9 +6,9 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using grinder.Configuration.Helper; +using GrinderApp.Configuration.Helper; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 配置信息的数据全部保存在该对象 diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigBase.cs b/Grinder.Infrastructure/Config/Configuration/ConfigBase.cs index ed6a8ee..58a1688 100644 --- a/Grinder.Infrastructure/Config/Configuration/ConfigBase.cs +++ b/Grinder.Infrastructure/Config/Configuration/ConfigBase.cs @@ -4,7 +4,7 @@ using System.Reflection; using System.Runtime.CompilerServices; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 强类型命名配置对象基类 diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigData.cs b/Grinder.Infrastructure/Config/Configuration/ConfigData.cs index ce0f9e2..92175b1 100644 --- a/Grinder.Infrastructure/Config/Configuration/ConfigData.cs +++ b/Grinder.Infrastructure/Config/Configuration/ConfigData.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Text.RegularExpressions; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 这个类负责存储所有的数据,新版本改为扁平化存储,取消树状存储形式 diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs b/Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs index d7569c8..5ea41b8 100644 --- a/Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs +++ b/Grinder.Infrastructure/Config/Configuration/ConfigDataVisitor.cs @@ -1,4 +1,4 @@ -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 用来遍历 ConfigTree 的算法 diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigPath.cs b/Grinder.Infrastructure/Config/Configuration/ConfigPath.cs index 4792cb0..7cca95f 100644 --- a/Grinder.Infrastructure/Config/Configuration/ConfigPath.cs +++ b/Grinder.Infrastructure/Config/Configuration/ConfigPath.cs @@ -1,7 +1,7 @@ using System; using System.Linq; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 该对象负责处理配置路径字符串 diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigSection.cs b/Grinder.Infrastructure/Config/Configuration/ConfigSection.cs index 4a06642..6eb2e25 100644 --- a/Grinder.Infrastructure/Config/Configuration/ConfigSection.cs +++ b/Grinder.Infrastructure/Config/Configuration/ConfigSection.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Newtonsoft.Json.Linq; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 这个类负责保存配置信息数据,意味着一个配置信息分组 diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigSectionView.cs b/Grinder.Infrastructure/Config/Configuration/ConfigSectionView.cs new file mode 100644 index 0000000..1e03bfd --- /dev/null +++ b/Grinder.Infrastructure/Config/Configuration/ConfigSectionView.cs @@ -0,0 +1,29 @@ +using GrinderApp.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GrinderApp.Configuration +{ + + public class ConfigSectionView + { + public string Name + { + get; + } + + public ConfigSection Section + { + get; + } + + public ConfigSectionView(string name, ConfigSection section) + { + Name = name; + Section = section; + } + } +} diff --git a/Grinder.Infrastructure/Config/Configuration/ConfigValue.cs b/Grinder.Infrastructure/Config/Configuration/ConfigValue.cs index f40bd28..bc6677c 100644 --- a/Grinder.Infrastructure/Config/Configuration/ConfigValue.cs +++ b/Grinder.Infrastructure/Config/Configuration/ConfigValue.cs @@ -1,7 +1,7 @@ using System; using System.Reflection.Metadata.Ecma335; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 配置参数的值 diff --git a/Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs b/Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs index ee545ef..03c9071 100644 --- a/Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs +++ b/Grinder.Infrastructure/Config/Configuration/Helper/AsyncEventHandler.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -namespace grinder.Configuration.Helper +namespace GrinderApp.Configuration.Helper { public delegate Task AsyncEventHandler(object sender, EventArgs e); diff --git a/Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs b/Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs index 084f793..e700fc3 100644 --- a/Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs +++ b/Grinder.Infrastructure/Config/Configuration/Helper/OneWaiterTaskQueue.cs @@ -2,7 +2,7 @@ using System.Threading; using System.Threading.Tasks; -namespace grinder.Configuration.Helper +namespace GrinderApp.Configuration.Helper { /// /// 只允许一个等待着的任务队列,该队列允许一个执行者工作中,同时一个等待着在等待并进入工作 diff --git a/Grinder.Infrastructure/Config/Configuration/IConfigStore.cs b/Grinder.Infrastructure/Config/Configuration/IConfigStore.cs index 7c2cba7..c8bba12 100644 --- a/Grinder.Infrastructure/Config/Configuration/IConfigStore.cs +++ b/Grinder.Infrastructure/Config/Configuration/IConfigStore.cs @@ -1,7 +1,7 @@ using System.Threading.Tasks; -using grinder.Configuration.Helper; +using GrinderApp.Configuration.Helper; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 配置信息持久化接口 diff --git a/Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs b/Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs index f95086e..ed0f439 100644 --- a/Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs +++ b/Grinder.Infrastructure/Config/Configuration/IDefaultConfigWriter.cs @@ -1,4 +1,4 @@ -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 接口负责把默认的配置文件参数持久化(这样一来用户可以直接修改被持久化的文件,提高效率) diff --git a/Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs b/Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs index 31cc228..c4799cf 100644 --- a/Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs +++ b/Grinder.Infrastructure/Config/Configuration/PersistencePropertyAttribute.cs @@ -1,6 +1,6 @@ using System; -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 需要持久化的设置参数特性头声明 diff --git a/Grinder.Infrastructure/Config/Configuration/SaveMethods.cs b/Grinder.Infrastructure/Config/Configuration/SaveMethods.cs index 5fe4c66..d25b8e6 100644 --- a/Grinder.Infrastructure/Config/Configuration/SaveMethods.cs +++ b/Grinder.Infrastructure/Config/Configuration/SaveMethods.cs @@ -1,4 +1,4 @@ -namespace grinder.Configuration +namespace GrinderApp.Configuration { /// /// 刷新至数据库的方法 diff --git a/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs b/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs index dcfaabc..af34308 100644 --- a/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs +++ b/Grinder.Infrastructure/Config/Configuration/Store/JsonConfigStore.cs @@ -5,10 +5,10 @@ using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using grinder.Configuration.Helper; -using grinder.Configuration.StreamProvider; +using GrinderApp.Configuration.Helper; +using GrinderApp.Configuration.StreamProvider; -namespace grinder.Configuration.Store.Json +namespace GrinderApp.Configuration.Store.Json { /// /// JSON 配置文件转换流 diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs index 14820ae..2862c89 100644 --- a/Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/FileStreamProvider.cs @@ -1,10 +1,10 @@ using System; using System.IO; using System.Threading.Tasks; -using grinder.Configuration.Helper; +using GrinderApp.Configuration.Helper; using Serilog; -namespace grinder.Configuration.StreamProvider +namespace GrinderApp.Configuration.StreamProvider { /// /// 文件流提供者 diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs index 0b2f5e3..1bdb9e9 100644 --- a/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProvider.cs @@ -1,6 +1,6 @@ using System.IO; -namespace grinder.Configuration.StreamProvider +namespace GrinderApp.Configuration.StreamProvider { /// /// 数据流提供接口,例如内存流,文件流等 diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs index 07a3bc7..eb55a94 100644 --- a/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/IStreamProviderWithNotification.cs @@ -1,6 +1,6 @@ -using grinder.Configuration.Helper; +using GrinderApp.Configuration.Helper; -namespace grinder.Configuration.StreamProvider +namespace GrinderApp.Configuration.StreamProvider { /// /// 含有通知消息的接口 diff --git a/Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs b/Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs index 3cda0ee..dc820cd 100644 --- a/Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs +++ b/Grinder.Infrastructure/Config/Configuration/StreamProvider/MemoryStreamProvider.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace grinder.Configuration.StreamProvider +namespace GrinderApp.Configuration.StreamProvider { /// /// 内存流提供者,主要用于单元测试 diff --git a/GrinderApp.Core/GrinderApp.Core.csproj b/GrinderApp.Core/GrinderApp.Core.csproj index cc9918f..9cd0c9a 100644 --- a/GrinderApp.Core/GrinderApp.Core.csproj +++ b/GrinderApp.Core/GrinderApp.Core.csproj @@ -6,4 +6,10 @@ + + + + + + \ No newline at end of file diff --git a/GrinderApp.Core/Interface/IConfigurationEditorViewLoader.cs b/GrinderApp.Core/Interface/IConfigurationEditorViewLoader.cs new file mode 100644 index 0000000..5526c3a --- /dev/null +++ b/GrinderApp.Core/Interface/IConfigurationEditorViewLoader.cs @@ -0,0 +1,13 @@ +using GrinderApp.Configuration; + +namespace GrinderApp.Core.Interface +{ + /// + /// 配置文件编辑器 + /// + public interface IConfigurationEditorViewLoader + { + void Show(string regionName, params ConfigSectionView[] configSectionView); + public void Show(string regionName); + } +} diff --git a/GrinderApp.Core/Interface/IModuleViewLoader.cs b/GrinderApp.Core/Interface/IModuleViewLoader.cs new file mode 100644 index 0000000..51a9677 --- /dev/null +++ b/GrinderApp.Core/Interface/IModuleViewLoader.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GrinderApp.Core.Interface +{ + /// + /// 模块视图 + /// + public interface IModuleViewLoader : IViewLoader + { + /// + /// 显示视图 + /// + /// + // void Show(string regionName); + + /// + /// 名称 + /// + string Name { get; } + + /// + /// 图标 todo 没有完全想好支持的格式, 目前支持 MaterialDesign 图标的枚举 + /// + string Icon { get; } + + /// + /// 默认显示顺序 + /// + int DefaultIndex { get; } + } +} diff --git a/GrinderApp.Core/Interface/IViewLoader.cs b/GrinderApp.Core/Interface/IViewLoader.cs new file mode 100644 index 0000000..c8bd1c6 --- /dev/null +++ b/GrinderApp.Core/Interface/IViewLoader.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GrinderApp.Core.Interface +{ + /// + /// 视图加载接口 + /// + public interface IViewLoader + { + /// + /// 显示视图 + /// + /// + void Show(string regionName); + } +} diff --git a/GrinderApp/GrinderApp.sln b/GrinderApp/GrinderApp.sln index 79a1e1f..520bd13 100644 --- a/GrinderApp/GrinderApp.sln +++ b/GrinderApp/GrinderApp.sln @@ -23,6 +23,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Grinder.Infrastructure", "G EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Configuration", "..\Grinder.Infrastructure\Config\Configuration\Configuration.csproj", "{E0A59C7B-E122-47FA-AB12-079F3A2BA43E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigurationEditor", "Modules\ConfigurationEditor\ConfigurationEditor.csproj", "{BB76CB5E-81E5-4371-B661-1E1F6A96AD67}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -53,6 +55,10 @@ Global {E0A59C7B-E122-47FA-AB12-079F3A2BA43E}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0A59C7B-E122-47FA-AB12-079F3A2BA43E}.Release|Any CPU.ActiveCfg = Release|Any CPU {E0A59C7B-E122-47FA-AB12-079F3A2BA43E}.Release|Any CPU.Build.0 = Release|Any CPU + {BB76CB5E-81E5-4371-B661-1E1F6A96AD67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB76CB5E-81E5-4371-B661-1E1F6A96AD67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB76CB5E-81E5-4371-B661-1E1F6A96AD67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB76CB5E-81E5-4371-B661-1E1F6A96AD67}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -62,5 +68,6 @@ Global {27F6296C-6144-4508-B973-F239057B023E} = {3F73F93D-0B10-4FC2-BCF6-29D31151F254} {0644D152-A161-4687-924B-86AF1FC32F1D} = {3CF79AE9-2100-4B03-BCB0-9BD67784E06A} {E0A59C7B-E122-47FA-AB12-079F3A2BA43E} = {306C4966-F4C7-4F82-9FE3-6D04168B1421} + {BB76CB5E-81E5-4371-B661-1E1F6A96AD67} = {3CF79AE9-2100-4B03-BCB0-9BD67784E06A} EndGlobalSection EndGlobal diff --git a/GrinderApp/GrinderApp/GrinderApp.csproj b/GrinderApp/GrinderApp/GrinderApp.csproj index cb13924..ade8082 100644 --- a/GrinderApp/GrinderApp/GrinderApp.csproj +++ b/GrinderApp/GrinderApp/GrinderApp.csproj @@ -6,7 +6,7 @@ - + diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigDescription.cs b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigDescription.cs new file mode 100644 index 0000000..590441a --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigDescription.cs @@ -0,0 +1,59 @@ +using System.Linq; +using Serilog; +using System.Collections.Generic; +using Unity; +using GrinderApp.Configuration; + +namespace ConfigurationEditor.Browse +{ + public class ConfigDescription : IConfigDescription + { + private readonly Dictionary _propertyDescriptions = new Dictionary(); + + public ConfigDescription(IUnityContainer unityContainer) + { + // 解析系统的配置参数的属性的描述, 在 ConfigBase 中, 通常都配置一个 DescriptionAttribute, 这个方法把这些 Attribute 解析出来, 显示在UI上 + ResolveConfigPropertyDescriptionAttributes(unityContainer); + } + + public string GetDescription(string key) + { + return _propertyDescriptions.TryGetValue(key, out var value) ? value : ""; + } + + /// + /// 解析系统的配置参数的属性的描述, 在 ConfigBase 中, 通常都配置一个 DescriptionAttribute, 这个方法把这些 Attribute 解析出来, 显示在UI上 + /// + /// + private void ResolveConfigPropertyDescriptionAttributes(IUnityContainer unityContainer) + { + var q = (from r in unityContainer.Registrations + where typeof(ConfigBase).IsAssignableFrom(r.MappedToType) || typeof(ConfigBase).IsAssignableFrom(r.RegisteredType) + select r).ToArray(); + foreach (var item in q) + { + try + { + var configBase = unityContainer.Resolve(item.RegisteredType) as ConfigBase; + if (configBase != null) + { + var dict = configBase.GetPropertyDescriptions(); + foreach (var kv in dict) + { + _propertyDescriptions[kv.Key] = kv.Value; + } + } + } + catch (System.Exception ex) + { + Log.Warning(ex, "无法加载配置文件 {Config} 的描述信息", item.MappedToType.Name); + } + } + } + + } + public interface IConfigDescription + { + string GetDescription(string key); + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigSectionItem.cs b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigSectionItem.cs new file mode 100644 index 0000000..86d2716 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigSectionItem.cs @@ -0,0 +1,173 @@ +using System.Collections.ObjectModel; +using System.Linq; +using GrinderApp.Configuration; +using Prism.Mvvm; + +using ConfigurationEditor.Helper; + + +namespace ConfigurationEditor.Browse +{ + /// + /// 配置节点视图模型 + /// + public class ConfigSectionItem : BindableBase + { + private readonly IMessageBox _messageBox; + private readonly IConfigDescription _configDescription; + + #region 选中和展开属性 + + private bool _isSelected; + + /// + /// 选中属性 + /// + public bool IsSelected + { + get => _isSelected; + set => SetProperty(ref _isSelected, value); + } + + + private bool _isExpanded; + + /// + /// 是否展开 + /// + public bool IsExpanded + { + get => _isExpanded; + set => SetProperty(ref _isExpanded, value); + } + + #endregion + + /// + /// 构造函数,创建一个根 + /// + /// 根节点名称 + /// 节点树 + /// + public ConfigSectionItem(string rootName, ConfigSection rootSection, IMessageBox messageBox, IConfigDescription configDescription) + { + _messageBox = messageBox; + Parent = null; + Section = rootSection; + Key = rootName; + _configDescription = configDescription ?? throw new System.ArgumentNullException(nameof(configDescription)); + + UpdateSections(); + } + + /// + /// 构造函数 + /// + /// 配置父节点对象 + /// 配置节点名 + /// + public ConfigSectionItem(ConfigSectionItem parentSectionItem, string name, IMessageBox messageBox, IConfigDescription configDescription) + { + _messageBox = messageBox; + + // 获取当前节点 + Parent = parentSectionItem; + Section = parentSectionItem.Section.GetSection(name); + Key = name; + _configDescription = configDescription ?? throw new System.ArgumentNullException(nameof(configDescription)); + + UpdateSections(); + } + + public void UpdateSections() + { + RaisePropertyChanged(nameof(Children)); + } + + /// + /// 父节点 + /// + public ConfigSectionItem Parent + { + get; + } + + /// + /// 当前节点 + /// + public ConfigSection Section + { + get; + } + + private string _key; + + /// + /// 配置节点名 + /// + public string Key + { + get => _key; + set => SetProperty(ref _key, value); + } + + private readonly ObservableCollection _sections = new ObservableCollection(); + + /// + /// 子节点 + /// + public ObservableCollection Children + { + get + { + var pathNodes = Section.GetChildrenNodes(true); + foreach (var key in pathNodes) + { + if (_sections.Any(c => c.Key == key) == false) + _sections.Add(new ConfigSectionItem(this, key, _messageBox, _configDescription)); + } + + foreach (var item in _sections.ToArray()) + { + if (pathNodes.Contains(item.Key) == false) + _sections.Remove(item); + } + + return _sections; + } + } + + private readonly ObservableCollection _values = new ObservableCollection(); + + /// + /// 值 + /// + public ObservableCollection Values + { + get + { + var nodes = Section.GetChildrenNodes(false); + nodes = nodes.OrderBy(c => c).ToArray(); + + foreach (var key in nodes) + { + if (_values.Any(c => c.Key == key) == false) + _values.Add(new ConfigValueItem(this, key, _messageBox, _configDescription)); + } + + foreach (var item in _values.ToArray()) + { + if (nodes.Contains(item.Key) == false) + _values.Remove(item); + } + + return _values; + } + } + + public void UpdateValues() + { + RaisePropertyChanged(nameof(Values)); + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs new file mode 100644 index 0000000..3950db9 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs @@ -0,0 +1,95 @@ +using ConfigurationEditor.Helper; +using ConfigurationEditor.Value; +using Prism.Mvvm; + + +namespace ConfigurationEditor.Browse +{ + /// + /// 配置参数 + /// + public class ConfigValueItem : BindableBase + { + public ConfigValueItem(ConfigSectionItem section, string key, IMessageBox messageBox, IConfigDescription configDescription ) + { + Key = key; + _section = section; + _messageBox = messageBox; + _configDescription = configDescription ?? throw new System.ArgumentNullException(nameof(configDescription)); + + } + + public void Update() + { + RaisePropertyChanged(null); + } + + + /// + /// 保存该值的Section + /// + private readonly ConfigSectionItem _section; + + private readonly IMessageBox _messageBox; + private readonly IConfigDescription _configDescription; + + /// + /// 参数 Key + /// + public string Key + { + get; + set; + } + + + /// + /// 数据类型 + /// + public DataType? Type + { + get + { + var value = _section.Section.GetValue(Key); + var type = ValueHelper.GetDataType(value); + + return type; + } + } + + /// + /// 值 + /// + public string ValueText + { + get + { + var value = _section.Section.GetValue(Key); + var valueText = ValueHelper.GetValueText(value); + return valueText; + } + } + /// + /// 描述信息 + /// + public string Description => _configDescription.GetDescription(_section.Section.GetFullPath(Key)); + + + /// + /// 当前是否选中 + /// + private bool _bSelected; + public bool Selected + { + get { return _bSelected; } + set { SetProperty(ref _bSelected, value); } + } + + /// Returns a string that represents the current object. + /// A string that represents the current object. + public override string ToString() + { + return $"{nameof(Key)}: {Key}, {nameof(Type)}: {Type}, {nameof(ValueText)}: {ValueText}, {nameof(Selected)}: {Selected}"; + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs.bak b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs.bak new file mode 100644 index 0000000..f3c9d92 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigValueItem.cs.bak @@ -0,0 +1,94 @@ +using ConfigurationEditor.Value; +using Octopus.Windows.Framework.Dialogs; +using Prism.Mvvm; + +namespace ConfigurationEditor.Browse +{ + /// + /// 配置参数 + /// + public class ConfigValueItem : BindableBase + { + public ConfigValueItem(ConfigSectionItem section, string key, IMessageBox messageBox, IConfigDescription configDescription ) + { + Key = key; + _section = section; + _messageBox = messageBox; + _configDescription = configDescription ?? throw new System.ArgumentNullException(nameof(configDescription)); + + } + + public void Update() + { + RaisePropertyChanged(null); + } + + + /// + /// 保存该值的Section + /// + private readonly ConfigSectionItem _section; + + private readonly IMessageBox _messageBox; + private readonly IConfigDescription _configDescription; + + /// + /// 参数 Key + /// + public string Key + { + get; + set; + } + + + /// + /// 数据类型 + /// + public DataType? Type + { + get + { + var value = _section.Section.GetValue(Key); + var type = ValueHelper.GetDataType(value); + + return type; + } + } + + /// + /// 值 + /// + public string ValueText + { + get + { + var value = _section.Section.GetValue(Key); + var valueText = ValueHelper.GetValueText(value); + return valueText; + } + } + /// + /// 描述信息 + /// + public string Description => _configDescription.GetDescription(_section.Section.GetFullPath(Key)); + + + /// + /// 当前是否选中 + /// + private bool _bSelected; + public bool Selected + { + get { return _bSelected; } + set { SetProperty(ref _bSelected, value); } + } + + /// Returns a string that represents the current object. + /// A string that represents the current object. + public override string ToString() + { + return $"{nameof(Key)}: {Key}, {nameof(Type)}: {Type}, {nameof(ValueText)}: {ValueText}, {nameof(Selected)}: {Selected}"; + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml new file mode 100644 index 0000000..c371296 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml.cs b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml.cs new file mode 100644 index 0000000..dc51228 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowse.xaml.cs @@ -0,0 +1,67 @@ +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; + +namespace ConfigurationEditor.Browse +{ + /// + /// Interaction logic for ConfigurationBrowse + /// + public partial class ConfigurationBrowse : UserControl + { + public ConfigurationBrowse() + { + InitializeComponent(); + + Loaded += (sender, e) => + { + SectionTree.Focus(); + }; + } + + public ConfigurationBrowseViewModel ViewModel => DataContext as ConfigurationBrowseViewModel; + + /// + /// ListViewItem 鼠标双击无法绑定 InputBindings,因此这么写 + /// /// + /// + /// + private void ListViewItem_MouseDoubleClickExecuteEditCommand(object sender, MouseButtonEventArgs e) + { + if (ViewModel.EditValueCommand.CanExecute()) + ViewModel.EditValueCommand.Execute(); + } + + /// + /// if one listViewItem has focus, then another listViewItem is selected, then the focus is move to another listViewItem + /// + /// On the listView, the focus is on the selection + /// + /// + private void ListViewItem_FocusWhenSelected(object sender, RoutedEventArgs e) + { + var item = sender as ListViewItem; + Debug.Assert(item != null, nameof(item) + " != null"); + + // retrieve keyboard focus + var focusElement = Keyboard.FocusedElement as DependencyObject; + if (focusElement == null) + return; + + // find focus scope + var focusScope = FocusManager.GetFocusScope(focusElement); + + // if focus scope is ListView + if (focusScope == ValueListView && item.IsSelected) + item.Focus(); + } + + private void SectionTree_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e) + { + var focus = Keyboard.FocusedElement as TreeViewItem; + if (focus != null && SectionTree.IsFocused == false) + SectionTree.Focus(); + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowseViewModel.cs b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowseViewModel.cs new file mode 100644 index 0000000..932ce3b --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/ConfigurationBrowseViewModel.cs @@ -0,0 +1,373 @@ + +using ConfigurationEditor.SectionEdit; +using ConfigurationEditor.ValueEdit; +using GrinderApp.Configuration; +using Prism.Commands; +using Prism.Mvvm; +using Prism.Navigation.Regions; +using System.Collections.ObjectModel; +using System.Linq; +using System.Windows; + +namespace ConfigurationEditor.Browse +{ + /// + /// 配置参数浏览视图模型 + /// + public class ConfigurationBrowseViewModel : BindableBase, INavigationAware + { + /// + /// + private readonly ConfigurationEditor.Helper.IMessageBox _messageBox; + private readonly IConfigDescription _configDescription; + Config config; + /// + /// 构造函数 + /// + /// + public ConfigurationBrowseViewModel(ConfigurationEditor.Helper.IMessageBox messageBox, IConfigDescription configDescription) + { + _messageBox = messageBox; + _configDescription = configDescription; + // 初始化提供的节点 + config = new Config(); + Roots = new ObservableCollection(new[] + { + new ConfigSectionItem("ROOT", new ConfigSection(config, ""), messageBox,configDescription), + }); + } + + #region Section Collection & Value Collection + + private ObservableCollection _roots; + + /// + /// 根节点(为了绑定,弄成数组) + /// + public ObservableCollection Roots + { + get => _roots; + set => SetProperty(ref _roots, value); + } + + private ConfigSectionItem _selectedSection; + + /// + /// 当前选择的节点 + /// + public ConfigSectionItem SelectedSection + { + get => _selectedSection; + set + { + SetProperty(ref _selectedSection, value); + + CreateSectionCommand.RaiseCanExecuteChanged(); + RenameSectionCommand.RaiseCanExecuteChanged(); + DeleteSectionCommand.RaiseCanExecuteChanged(); + CreateValueCommand.RaiseCanExecuteChanged(); + EditValueCommand.RaiseCanExecuteChanged(); + DeleteValueCommand.RaiseCanExecuteChanged(); + } + } + + private ConfigValueItem _selectedValue; + + /// + /// 当前选择的值 + /// + public ConfigValueItem SelectedValue + { + get => _selectedValue; + set + { + SetProperty(ref _selectedValue, value); + + EditValueCommand.RaiseCanExecuteChanged(); + DeleteValueCommand.RaiseCanExecuteChanged(); + } + } + + #endregion + + #region Selection Changed Command + + /// + /// + private DelegateCommand _sectionChangedCommand; + + /// + /// 选择的节点变更事件 + /// + public DelegateCommand SectionChangedCommand => + _sectionChangedCommand ??= new DelegateCommand(ExecuteSectionChangedCommand); + + /// + /// 选择节点改变,更新右侧值信息 + /// + /// + void ExecuteSectionChangedCommand(ConfigSectionItem section) + { + SelectedSection = section; + } + + #endregion + + #region Section Create + + private DelegateCommand _createSectionCommand; + + /// + /// 创建一个节点 + /// + public DelegateCommand CreateSectionCommand => + _createSectionCommand ??= new DelegateCommand(ExecuteCreateSectionCommand, CanExecuteCreateSectionCommand); + + void ExecuteCreateSectionCommand() + { + var edit = new SectionEditWindow(); + edit.ViewModel.CreateSection(SelectedSection.Section); + if (edit.ShowDialog() == true) + { + SelectedSection.IsExpanded = true; + var newItem = SelectedSection.Children.FirstOrDefault(c => c.Key == edit.ViewModel.Name); + if (newItem != null) + newItem.IsSelected = true; + } + } + + bool CanExecuteCreateSectionCommand() + { + return SelectedSection != null; + } + + #endregion + + #region Section Rename + + private DelegateCommand _renameSectionCommand; + + /// + /// Rename command + /// + public DelegateCommand RenameSectionCommand => + _renameSectionCommand ??= new DelegateCommand(ExecuteRenameSectionCommand, CanExecuteRenameSectionCommand); + + /// + /// rename section + /// + void ExecuteRenameSectionCommand() + { + var view = new SectionEditWindow + { + Owner = Application.Current.MainWindow + }; + view.ViewModel.EditConfigSection(SelectedSection.Parent.Section, SelectedSection.Key); + + if (view.ShowDialog() ?? false) + { + SelectedSection.Key = view.ViewModel.Name; + } + } + + bool CanExecuteRenameSectionCommand() + { + return SelectedSection?.Parent != null; + } + + #endregion + + #region Section Delete + + private DelegateCommand _deleteSectionCommand; + + public DelegateCommand DeleteSectionCommand => + _deleteSectionCommand ??= new DelegateCommand(ExecuteDeleteSectionCommand, CanExecuteDeleteSectionCommand); + + /// + /// 删除 Section + /// + async void ExecuteDeleteSectionCommand() + { + if (await _messageBox.ShowQuestionAsync(I18n.Are_you_sure_delete_this_section) == true) + { + var key = SelectedSection.Key; // hold the key that needs to be deleted + + var parent = SelectedSection.Parent; + parent.IsSelected = true; + + // remove section then update ui + parent.Section.Remove(key); + parent.UpdateSections(); + } + } + + bool CanExecuteDeleteSectionCommand() + { + return SelectedSection?.Parent != null; + } + + #endregion + + #region Value Create + + /// + /// + private DelegateCommand _createValueCommand; + + /// + /// 创建新的值 + /// + public DelegateCommand CreateValueCommand => + _createValueCommand ??= new DelegateCommand(ExecuteCreateValueCommand, CanExecuteCreateValueCommand); + + + /// + /// 执行创建新值命令 + /// + void ExecuteCreateValueCommand() + { + var valueEdit = new ValueEditWidow + { + Owner = Application.Current.MainWindow + }; + valueEdit.ViewModel.CreateSection(SelectedSection.Section); + if (valueEdit.ShowDialog() == true) + { + SelectedSection.UpdateValues(); + SelectedValue = SelectedSection.Values.FirstOrDefault(c => c.Key == valueEdit.ViewModel.Key); + } + } + + /// + /// 判断是否可以创建新值 + /// + /// + bool CanExecuteCreateValueCommand() + { + return SelectedSection != null; + } + + #endregion + + #region Value Edit + + private DelegateCommand _editValueCommand; + + public DelegateCommand EditValueCommand => + _editValueCommand ??= new DelegateCommand(ExecuteEditValueCommand, CanExecuteEditValueCommand); + + void ExecuteEditValueCommand() + { + var valueEdit = new ValueEditWidow() + { + Owner = Application.Current.MainWindow + }; + + valueEdit.ViewModel.EditConfigSection(SelectedSection.Section, SelectedValue.Key); + + if (valueEdit.ShowDialog() == true) + { + // Key 不在范畴内, 因此特别添加 + SelectedValue.Key = valueEdit.ViewModel.Key; + SelectedValue.Update(); + } + } + + bool CanExecuteEditValueCommand() + { + return SelectedSection != null && SelectedValue != null; + } + + #endregion + + #region Value Delete + + private DelegateCommand _deleteValueCommand; + + public DelegateCommand DeleteValueCommand => + _deleteValueCommand ??= new DelegateCommand(ExecuteDeleteValueCommand, CanExecuteDeleteValueCommand); + + async void ExecuteDeleteValueCommand() + { + if (await _messageBox.ShowQuestionAsync(I18n.Are_you_sure_you_want_to_delete_this_item) == true) + { + var selectedValueItem = SelectedValue; + + // when value removed, ensure next value be selected. + ConfigValueItem nextValue = null; + foreach (var value in SelectedSection.Values.Reverse()) + { + if (value.Selected) + break; + + nextValue = value; + } + + foreach (var value in SelectedSection.Values) + { + if (value.Selected) + break; + + nextValue = value; + } + + // remove value + SelectedSection.Section.Remove(selectedValueItem.Key); + SelectedSection.UpdateValues(); + + // select next value + nextValue ??= SelectedSection.Values.FirstOrDefault(); + if (nextValue != null) + nextValue.Selected = true; + } + } + + bool CanExecuteDeleteValueCommand() + { + return SelectedSection != null && SelectedValue != null; + } + + #endregion + + #region Navigator + + /// Called when the implementer has been navigated to. + /// The navigation context. + public void OnNavigatedTo(NavigationContext navigationContext) + { + var param = navigationContext.Parameters["ConfigSections"] as ConfigSectionView[] ?? new ConfigSectionView[0]; + var roots = from p in param + let first = p == param.FirstOrDefault() + select new ConfigSectionItem(p.Name, p.Section, _messageBox, _configDescription) + { + IsSelected = first, + IsExpanded = first + }; + + Roots = new ObservableCollection(roots); + } + + /// + /// Called to determine if this instance can handle the navigation request. + /// + /// The navigation context. + /// + /// if this instance accepts the navigation request; otherwise, . + /// + public bool IsNavigationTarget(NavigationContext navigationContext) + { + return true; + } + + /// + /// Called when the implementer is being navigated away from. + /// + /// The navigation context. + public void OnNavigatedFrom(NavigationContext navigationContext) + { + } + + #endregion + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.Designer.cs b/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.Designer.cs new file mode 100644 index 0000000..d07250f --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.Designer.cs @@ -0,0 +1,180 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace ConfigurationEditor.Browse { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class I18n { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal I18n() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConfigurationEditor.Browse.I18n", typeof(I18n).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找类似 Are you sure delete this section 的本地化字符串。 + /// + public static string Are_you_sure_delete_this_section { + get { + return ResourceManager.GetString("Are_you_sure_delete_this_section", resourceCulture); + } + } + + /// + /// 查找类似 Are you sure you want to delete this item 的本地化字符串。 + /// + public static string Are_you_sure_you_want_to_delete_this_item { + get { + return ResourceManager.GetString("Are_you_sure_you_want_to_delete_this_item", resourceCulture); + } + } + + /// + /// 查找类似 DELETE 的本地化字符串。 + /// + public static string DELETE { + get { + return ResourceManager.GetString("DELETE", resourceCulture); + } + } + + /// + /// 查找类似 _Description 的本地化字符串。 + /// + public static string ListViewTitle_Description { + get { + return ResourceManager.GetString("ListViewTitle_Description", resourceCulture); + } + } + + /// + /// 查找类似 KEY 的本地化字符串。 + /// + public static string ListViewTitle_Key { + get { + return ResourceManager.GetString("ListViewTitle_Key", resourceCulture); + } + } + + /// + /// 查找类似 TYPE 的本地化字符串。 + /// + public static string ListViewTitle_Type { + get { + return ResourceManager.GetString("ListViewTitle_Type", resourceCulture); + } + } + + /// + /// 查找类似 VALUE 的本地化字符串。 + /// + public static string ListViewTitle_Value { + get { + return ResourceManager.GetString("ListViewTitle_Value", resourceCulture); + } + } + + /// + /// 查找类似 _New section... 的本地化字符串。 + /// + public static string MenuItem_CreateSection { + get { + return ResourceManager.GetString("MenuItem_CreateSection", resourceCulture); + } + } + + /// + /// 查找类似 _New value... 的本地化字符串。 + /// + public static string MenuItem_CreateValue { + get { + return ResourceManager.GetString("MenuItem_CreateValue", resourceCulture); + } + } + + /// + /// 查找类似 _Delete section 的本地化字符串。 + /// + public static string MenuItem_DeleteSection { + get { + return ResourceManager.GetString("MenuItem_DeleteSection", resourceCulture); + } + } + + /// + /// 查找类似 _Delete value 的本地化字符串。 + /// + public static string MenuItem_DeleteValue { + get { + return ResourceManager.GetString("MenuItem_DeleteValue", resourceCulture); + } + } + + /// + /// 查找类似 _Rename... 的本地化字符串。 + /// + public static string MenuItem_EditSection { + get { + return ResourceManager.GetString("MenuItem_EditSection", resourceCulture); + } + } + + /// + /// 查找类似 _Edit value... 的本地化字符串。 + /// + public static string MenuItem_EditValue { + get { + return ResourceManager.GetString("MenuItem_EditValue", resourceCulture); + } + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.resx b/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.resx new file mode 100644 index 0000000..ef8519a --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + KEY + + + TYPE + + + VALUE + + + _New section... + + + _New value... + + + _Delete section + + + _Delete value + + + _Rename... + + + _Edit value... + + + Are you sure you want to delete this item + + + DELETE + + + Are you sure delete this section + + + _Description + + \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.zh-CN.resx b/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.zh-CN.resx new file mode 100644 index 0000000..0c57cf4 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/I18n.zh-CN.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 新建节点(_N)... + + + 新建参数(_N)... + + + 删除(_D) + + + 删除(_D) + + + 重命名(_R) + + + 修改(_E) + + + 名称 + + + 类型 + + + + + + 删除 + + + 您确定要删除该节点 + + + 您确定要删除该值 + + + 描述 + + \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/NullToVisibilityConverter.cs b/GrinderApp/Modules/ConfigurationEditor/Browse/NullToVisibilityConverter.cs new file mode 100644 index 0000000..8951497 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/NullToVisibilityConverter.cs @@ -0,0 +1,22 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace ConfigurationEditor.Browse; + +public class NullableToVisibilityConverter : IValueConverter +{ + public Visibility NullValue { get; set; } = Visibility.Collapsed; + public Visibility NotNullValue { get; set; } = Visibility.Visible; + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value == null ? NullValue : NotNullValue; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return Binding.DoNothing; + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Browse/TreeViewItem.xaml b/GrinderApp/Modules/ConfigurationEditor/Browse/TreeViewItem.xaml new file mode 100644 index 0000000..f575338 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Browse/TreeViewItem.xaml @@ -0,0 +1,194 @@ + + + + + \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/ConfigurationEditor.csproj b/GrinderApp/Modules/ConfigurationEditor/ConfigurationEditor.csproj new file mode 100644 index 0000000..1630e10 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/ConfigurationEditor.csproj @@ -0,0 +1,63 @@ + + + net8.0-windows7.0 + true + ConfigurationEditor + AnyCPU;x64;x86 + + + none + false + + + none + false + + + none + false + + + + + + + + + + + + + + + + True + True + I18n.resx + + + True + True + I18n.resx + + + True + True + I18n.resx + + + + + PublicResXFileCodeGenerator + I18n.Designer.cs + + + PublicResXFileCodeGenerator + I18n.Designer.cs + + + PublicResXFileCodeGenerator + I18n.Designer.cs + + + \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorModule.cs b/GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorModule.cs new file mode 100644 index 0000000..45a91a8 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorModule.cs @@ -0,0 +1,33 @@ +using ConfigurationEditor.Browse; +using ConfigurationEditor.Shell; +using GrinderApp.Configuration; +using GrinderApp.Core.Interface; +using Prism.Ioc; +using Prism.Modularity; + + +namespace ConfigurationEditor.DependencyInjection +{ + /// + /// 配置编辑模块 + /// + public class ConfigurationEditorModule : IModule + { + /// + /// Used to register types with the container that will be used by your application. + /// + public void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.Register(); + containerRegistry.Register(nameof(ConfigurationEditorViewLoader)); + containerRegistry.Register(); + containerRegistry.RegisterForNavigation< ConfigurationShell>(nameof(ConfigurationShell)); + containerRegistry.RegisterForNavigation(); + } + + /// Notifies the module that it has be initialized. + public void OnInitialized(IContainerProvider containerProvider) + { + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorViewLoader.cs b/GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorViewLoader.cs new file mode 100644 index 0000000..565a85b --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/DependencyInjection/ConfigurationEditorViewLoader.cs @@ -0,0 +1,61 @@ +using ConfigurationEditor.Browse; +using ConfigurationEditor.Shell; +using MaterialDesignThemes.Wpf; +using GrinderApp.Configuration; +using Prism.Navigation.Regions; + +using Prism.Navigation; +using GrinderApp.Core.Interface; + +namespace ConfigurationEditor.DependencyInjection +{ + public class ConfigurationEditorViewLoader : IConfigurationEditorViewLoader, IModuleViewLoader + { + private readonly IRegionManager _regionManager; + private readonly Config _config; + + public ConfigurationEditorViewLoader(IRegionManager regionManager, Config config) + { + _regionManager = regionManager; + _config = config; + } + + public void Show(string regionName, params ConfigSectionView[] configSections) + { + // _regionManager.RequestNavigate(regionName,nameof ( ConfigurationShell)); + _regionManager.RequestNavigate(regionName, nameof(ConfigurationBrowse), new NavigationParameters + { + { + "ConfigSections", configSections + } + }); + } + + /// + /// 在呈现区显示 + /// + /// 呈现区 + public void Show(string regionName) + { + var configSection = _config.GetSection(); + // Show(regionName, new ConfigSectionView("Default", configSection)); + Show(regionName, new ConfigSectionView("Root", configSection)); + // _regionManager.RequestNavigate(regionName, nameof(ConfigurationShell)); + } + + /// + /// 名称 + /// + public string Name => "参数设置"; + + /// + /// 图标 todo 没有完全想好支持的格式, 目前支持 MaterialDesign 图标的枚举 + /// + public string Icon => PackIconKind.Cog.ToString(); + + /// + /// 默认显示顺序 + /// + public int DefaultIndex => 1000; + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Helper/BindableBaseWithDataError.cs b/GrinderApp/Modules/ConfigurationEditor/Helper/BindableBaseWithDataError.cs new file mode 100644 index 0000000..c15fa98 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Helper/BindableBaseWithDataError.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Text; +using Prism.Mvvm; + +namespace ConfigurationEditor.Helper +{ + /// + /// 含有错误处理的绑定基类 + /// + public class BindableBaseWithDataError : BindableBase, IDataErrorInfo + { + /// + /// 验证方法 + /// + private readonly Dictionary _validateMethods = new Dictionary(); + + public BindableBaseWithDataError() + { + var methods = this.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance); + foreach (var method in methods) + { + var attr = method.GetCustomAttributes(typeof(ValidateForAttribute), true).FirstOrDefault() as ValidateForAttribute; + if (attr == null) + continue; + + if (method.ReturnType != typeof(string)) + throw new InvalidProgramException("You must declare return as string in method that special ValidateForAttribute"); + + _validateMethods.Add(attr.PropertyName, method); + } + } + + /// Gets the error message for the property with the given name. + /// The error message for the property. The default is an empty string (""). + /// The name of the property whose error message to get. + public string this[string columnName] + { + get + { + MethodInfo method; + if (_validateMethods.TryGetValue(columnName, out method) == false) + return null; + + return method.Invoke(this, null) as string; + } + } + + /// + /// 判断是否仍有错误 + /// + public virtual bool HasInFault + { + get + { + foreach (var methodsValue in _validateMethods.Values) + { + var result = methodsValue.Invoke(this, null) as string; + if (string.IsNullOrEmpty(result) == false) + return true; + } + + return false; + } + } + + /// Gets an error message indicating what is wrong with this object. + /// An error message indicating what is wrong with this object. The default is an empty string (""). + public virtual string Error + { + get + { + var sb = new StringBuilder(); + + foreach (var methodsValue in _validateMethods.Values) + { + var result = methodsValue.Invoke(this, null) as string; + if (string.IsNullOrEmpty(result) == false) + sb.AppendLine(result); + + } + + return sb.ToString(); + } + } + } +} \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/Helper/BindableSelectedItemBehavior.cs b/GrinderApp/Modules/ConfigurationEditor/Helper/BindableSelectedItemBehavior.cs new file mode 100644 index 0000000..060d8c7 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Helper/BindableSelectedItemBehavior.cs @@ -0,0 +1,59 @@ +using Microsoft.Xaml.Behaviors; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows; + +namespace ConfigurationEditor.Helper +{ + + public class BindableSelectedItemBehavior : Behavior + { + #region SelectedItem Property + + public object SelectedItem + { + get { return (object)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof(object), typeof(BindableSelectedItemBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged)); + + private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + var item = e.NewValue as TreeViewItem; + if (item != null) + { + item.SetValue(TreeViewItem.IsSelectedProperty, true); + } + } + + #endregion + + protected override void OnAttached() + { + base.OnAttached(); + + this.AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged; + } + + protected override void OnDetaching() + { + base.OnDetaching(); + + if (this.AssociatedObject != null) + { + this.AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged; + } + } + + private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e) + { + this.SelectedItem = e.NewValue; + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Helper/DefaultMessageBox.cs b/GrinderApp/Modules/ConfigurationEditor/Helper/DefaultMessageBox.cs new file mode 100644 index 0000000..7b2f6d2 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Helper/DefaultMessageBox.cs @@ -0,0 +1,19 @@ +//using System.Windows; +//using FirstLineTamping.UI.Contract.MessageBox; + +//namespace FirstLineTamping.UI.ConfigurationEditor.Helper +//{ +// public class DefaultMessageBox : IMessageBox +// { +// /// +// /// 显示一个问题让用户选择 +// /// +// /// +// /// +// /// +// public bool ShowQuestion(string text, string title) +// { +// return MessageBox.Show(text, title, MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK; +// } +// } +//} \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/Helper/FocusExtension.cs b/GrinderApp/Modules/ConfigurationEditor/Helper/FocusExtension.cs new file mode 100644 index 0000000..48c71b3 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Helper/FocusExtension.cs @@ -0,0 +1,35 @@ +using System.Windows; + +namespace ConfigurationEditor.Helper +{ + public static class FocusExtension + { + public static bool GetIsFocused(DependencyObject obj) + { + return (bool) obj.GetValue(IsFocusedProperty); + } + + + public static void SetIsFocused(DependencyObject obj, bool value) + { + obj.SetValue(IsFocusedProperty, value); + } + + + public static readonly DependencyProperty IsFocusedProperty = + DependencyProperty.RegisterAttached( + "IsFocused", typeof(bool), typeof(FocusExtension), + new UIPropertyMetadata(false, OnIsFocusedPropertyChanged)); + + + private static void OnIsFocusedPropertyChanged(DependencyObject d, + DependencyPropertyChangedEventArgs e) + { + var uie = (UIElement) d; + if ((bool) e.NewValue) + { + uie.Focus(); + } + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Helper/IDialogWindow.cs b/GrinderApp/Modules/ConfigurationEditor/Helper/IDialogWindow.cs new file mode 100644 index 0000000..c7109d4 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Helper/IDialogWindow.cs @@ -0,0 +1,18 @@ +namespace ConfigurationEditor.Helper +{ + /// + /// 可关闭的窗口, 提供给视图模型调用关闭窗口使用 + /// + public interface IDialogWindow + { + /// + /// 对话框确定关闭 + /// + void Ok(); + + /// + /// 对话框取消关闭 + /// + void Cancel(); + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Helper/IMessageBox.cs b/GrinderApp/Modules/ConfigurationEditor/Helper/IMessageBox.cs new file mode 100644 index 0000000..be9a33c --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Helper/IMessageBox.cs @@ -0,0 +1,54 @@ +using System.Threading.Tasks; +using System.Windows; +using System; + +namespace ConfigurationEditor.Helper +{ + /// + /// 消息框接口 + /// + public interface IMessageBox + { + /// + /// 显示消息对话框 + /// + /// + Task ShowAsync(string text, MessageBoxSetting settingAction = null); + /// + /// 显示一个问题让用户选择 + /// + /// + /// + /// + bool ShowQuestion(string text, string title); + + /// + /// 显示一个等待用户确认询问 + /// + public async Task ShowQuestionAsync(string text, Action settingAction = null) + { + var option = new MessageBoxSetting + { + Title = "请选择", + Button = MessageBoxButton.YesNo, + Icon = MessageBoxImage.Question, + }; + settingAction?.Invoke(option); + + if (option.Button == MessageBoxButton.OK) + throw new NotSupportedException(); + + var result = await ShowAsync(text, option); + return result switch + { + MessageBoxResult.None => null, + MessageBoxResult.OK => true, + MessageBoxResult.Cancel => null, + MessageBoxResult.Yes => true, + MessageBoxResult.No => false, + _ => throw new ArgumentOutOfRangeException() + }; + } + + }; +} diff --git a/GrinderApp/Modules/ConfigurationEditor/Helper/ValidateForAttribute.cs b/GrinderApp/Modules/ConfigurationEditor/Helper/ValidateForAttribute.cs new file mode 100644 index 0000000..aff5083 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/Helper/ValidateForAttribute.cs @@ -0,0 +1,20 @@ +using System; + +namespace ConfigurationEditor.Helper +{ + /// + /// 描述该方法为哪一个属性验证 + /// + internal class ValidateForAttribute : Attribute + { + public string PropertyName + { + get; + } + + public ValidateForAttribute(string propertyName) + { + PropertyName = propertyName; + } + } +} \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/MessageBoxSetting.cs b/GrinderApp/Modules/ConfigurationEditor/MessageBoxSetting.cs new file mode 100644 index 0000000..d6c8f82 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/MessageBoxSetting.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace ConfigurationEditor +{ + + /// + /// 消息框选项 + /// + public class MessageBoxSetting + { + public string Title { get; set; } + + public MessageBoxButton Button { get; set; } + + public MessageBoxImage Icon { get; set; } + + public string[] ButtonTexts { get; set; } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/README.md b/GrinderApp/Modules/ConfigurationEditor/README.md new file mode 100644 index 0000000..1a466bb --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/README.md @@ -0,0 +1,28 @@ +| Property | Value +|:-------------|:----------------------- +| Project Name | ConfigurationEditor +| Author | Liu Wan Li +| Create Time | 2019-05-13 + +# Summary +这个项目负责配置参数的编辑和维护工作 +#--------------------------------------- +关于配置参数的一些基本约定 +| Author | Shenyong +| Create Time | 2019-05-14 +每一台在运行的设备都有一套完整的参数控制该设备的运行。 +该套参数我们称为ConfigSets。 +每台设备可以存储多个ConfigSets 实例,但是任何时刻只有一套ConfigSets 实例在使用。 +ConfigSets 按以下结构组织: + ConfigSets[+]--+->Category: string //设备类别 + +->GUID:string //唯一编号 + +->CreatDate:DateTime //建立日期 + +->ModifyDate:DateTime //最后修改日期 + +->ProductSN:string //产品编号 + +->EditGeo[+] //编辑GEO 文件参数, + +->Machine[+] //机械参数 + +->.......[+] + + +# IViewLoader Name +ConfigurationEditor diff --git a/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.Designer.cs b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.Designer.cs new file mode 100644 index 0000000..45c80aa --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.Designer.cs @@ -0,0 +1,135 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ConfigurationEditor.SectionEdit { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class I18n { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal I18n() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConfigurationEditor.SectionEdit.I18n", typeof(I18n).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to _Cancel. + /// + public static string ButtonCancel_Text { + get { + return ResourceManager.GetString("ButtonCancel_Text", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to _OK. + /// + public static string ButtonOk_Text { + get { + return ResourceManager.GetString("ButtonOk_Text", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter config section name:. + /// + public static string LabelSectionName_Text { + get { + return ResourceManager.GetString("LabelSectionName_Text", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Section is not exist. + /// + public static string Section_is_not_exist { + get { + return ResourceManager.GetString("Section_is_not_exist", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Section name is not validated. + /// + public static string Section_name_is_not_validated { + get { + return ResourceManager.GetString("Section_name_is_not_validated", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Section name was be used. + /// + public static string Section_name_was_be_used { + get { + return ResourceManager.GetString("Section_name_was_be_used", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The name is not in section. + /// + public static string The_name_is_not_in_section { + get { + return ResourceManager.GetString("The_name_is_not_in_section", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Section name. + /// + public static string Window_Title { + get { + return ResourceManager.GetString("Window_Title", resourceCulture); + } + } + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.resx b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.resx new file mode 100644 index 0000000..444c687 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + _Cancel + + + _OK + + + Enter config section name: + + + Section name + + + The name is not in section + + + Section name is not validated + + + Section name was be used + + + Section is not exist + + \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.zh-CN.resx b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.zh-CN.resx new file mode 100644 index 0000000..e9df270 --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/I18n.zh-CN.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 取消(_C) + + + 确定(_O) + + + 输入节点名称: + + + 节点名称 + + + 该名称内容不是一个节点 + + + 节点名无效 + + + 节点名已被使用 + + + 节点不存在 + + \ No newline at end of file diff --git a/GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditViewModel.cs b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditViewModel.cs new file mode 100644 index 0000000..b20013b --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditViewModel.cs @@ -0,0 +1,145 @@ +using System; +using System.Diagnostics; +using System.Linq; +using ConfigurationEditor.Helper; +using GrinderApp.Configuration; +using Prism.Commands; //using FirstLineTamping.Infrastructure.UI.ViewModels; + +namespace ConfigurationEditor.SectionEdit +{ + /// + /// 设置配置节点名 + /// + public class SectionEditWindowViewModel : BindableBaseWithDataError + { + /// + /// 创建节点 + /// + /// + public void CreateSection(ConfigSection parentSection) + { + if (parentSection == null) + throw new ArgumentNullException(nameof(parentSection)); + + _parentSection = parentSection; + + Name = ""; + } + + /// + /// 设置配置节点 + /// + /// 持有这个Section的parent + /// 需要编辑的 SectionName + public void EditConfigSection(ConfigSection parentSection, string name = null) + { + if (parentSection == null) + throw new ArgumentNullException(nameof(parentSection)); + if (name == null) + throw new ArgumentNullException(nameof(name)); + + if (parentSection.GetChildrenNodes().Contains(name) == false) + throw new ArgumentException(I18n.The_name_is_not_in_section); + + _parentSection = parentSection; + _originName = name; + Name = name; + } + + private ConfigSection _parentSection; + + #region Name + + /// + /// 修改前的原值 + /// + private string _originName; + + /// + /// 新名称 + /// + private string _name; + + /// + /// 新名称 + /// + public string Name + { + get => _name; + set + { + SetProperty(ref _name, value); + _confirmCommand.RaiseCanExecuteChanged(); + } + } + + /// + /// 验证SectionName + /// + /// + [ValidateFor(nameof(Name))] + private string NameValidation() + { + var stringData = Name; + + if (ConfigPath.IsNodeValidated(stringData) == false) + return I18n.Section_name_is_not_validated; + + if (Name != _originName && _parentSection?.GetChildrenNodes().Contains(Name) == true) + return I18n.Section_name_was_be_used; + + return null; + } + + #endregion + + #region Ok Button Command + + private DelegateCommand _confirmCommand; + + /// + /// OK button + /// + public DelegateCommand ConfirmCommand => + _confirmCommand ??= new DelegateCommand(ExecuteConfirmCommand, CanExecuteConfirmCommand); + + /// + /// 执行关闭按钮 + /// + /// + void ExecuteConfirmCommand(IDialogWindow dialogWindow) + { + Debug.Assert(_parentSection != null); + + // create new or edit current + if (_originName == null) + { + var newPath = ConfigPath.CombinePath(Name, "(Default)"); + _parentSection.SetValue(newPath, ""); + } + else if (_originName != Name) + { + var section = _parentSection.GetSection(_originName); + if (section == null) + throw new Exception(I18n.Section_is_not_exist); + + _parentSection.Rename(_originName, Name); + } + + dialogWindow.Ok(); + } + + /// + /// 判断是否可以执行 + /// + /// + /// + bool CanExecuteConfirmCommand(IDialogWindow closeableWindow) + { + // name equal _originName is not fault, but we do not allow this + return !base.HasInFault; + } + + #endregion + } +} diff --git a/GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditWindow.xaml b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditWindow.xaml new file mode 100644 index 0000000..ead6cbf --- /dev/null +++ b/GrinderApp/Modules/ConfigurationEditor/SectionEdit/SectionEditWindow.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + +