diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b8949dc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+bin
+obj
+bin\log
+packages
+_gsdata_
+_ReSharper*
+TestResults
+app_data
+*.suo
+*.user
+*.log
+*.pubxml
+*.publish.xml
+.svn
+.vs
+*.dbmdl
+*.jfm
+*.exe
+.idea
+node_modules
+dist
+/src/Ddf/Ddf.App/ddf-dcloud/unpackage/cache
+/src/Ddf/Ddf.App/ddf-dcloud/unpackage/release/apk
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1 @@
+
diff --git a/lib/README.md b/lib/README.md
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/lib/README.md
@@ -0,0 +1 @@
+
diff --git a/res/README.md b/res/README.md
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/res/README.md
@@ -0,0 +1 @@
+
diff --git a/script/README.md b/script/README.md
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/script/README.md
@@ -0,0 +1 @@
+
diff --git a/src/.editorconfig b/src/.editorconfig
new file mode 100644
index 0000000..60c2173
--- /dev/null
+++ b/src/.editorconfig
@@ -0,0 +1,89 @@
+[*.{appxmanifest,asax,ascx,aspx,axaml,axml,build,config,cs,cshtml,csproj,css,dbml,discomap,dtd,htm,html,js,json,jsproj,jsx,lsproj,master,njsproj,nuspec,paml,proj,props,proto,razor,resjson,resw,resx,skin,StyleCop,targets,tasks,ts,tsx,vb,vbproj,xaml,xamlx,xml,xoml,xsd}]
+indent_style = space
+indent_size = space
+tab_width = 4
+
+[*]
+
+# Microsoft .NET properties
+csharp_indent_braces = false
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = local_functions, methods, types
+csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion
+csharp_style_var_elsewhere = true:suggestion
+csharp_style_var_for_built_in_types = true:suggestion
+csharp_style_var_when_type_is_apparent = true:suggestion
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
+dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
+dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
+
+# ReSharper inspection severities
+resharper_arrange_redundant_parentheses_highlighting = hint
+resharper_arrange_this_qualifier_highlighting = hint
+resharper_arrange_type_member_modifiers_highlighting = hint
+resharper_arrange_type_modifiers_highlighting = hint
+resharper_built_in_type_reference_style_for_member_access_highlighting = hint
+resharper_built_in_type_reference_style_highlighting = hint
+resharper_redundant_base_qualifier_highlighting = warning
+resharper_suggest_var_or_type_built_in_types_highlighting = hint
+resharper_suggest_var_or_type_elsewhere_highlighting = hint
+resharper_suggest_var_or_type_simple_types_highlighting = hint
+
+# ReSharper properties
+resharper_align_first_arg_by_paren = true
+resharper_align_linq_query = true
+resharper_align_multiline_argument = true
+resharper_align_multiline_array_and_object_initializer = false
+resharper_align_multiline_calls_chain = true
+resharper_align_multiline_expression = true
+resharper_align_multiline_extends_list = true
+resharper_align_multiline_for_stmt = true
+resharper_align_multiline_property_pattern = true
+resharper_align_multiline_switch_expression = true
+resharper_align_multline_type_parameter_constrains = true
+resharper_align_multline_type_parameter_list = true
+resharper_align_tuple_components = true
+resharper_csharp_align_multiline_parameter = true
+resharper_csharp_align_multiple_declaration = true
+resharper_csharp_empty_block_style = together
+resharper_csharp_indent_size = 4
+resharper_csharp_indent_style = space
+resharper_csharp_insert_final_newline = true
+resharper_csharp_max_line_length = 120
+resharper_csharp_stick_comment = false
+resharper_csharp_tab_width = 4
+resharper_csharp_wrap_arguments_style = chop_if_long
+resharper_csharp_wrap_before_comma = false
+resharper_csharp_wrap_chained_method_calls = chop_if_long
+resharper_csharp_wrap_extends_list_style = chop_if_long
+resharper_csharp_wrap_parameters_style = chop_if_long
+resharper_indent_anonymous_method_block = true
+resharper_indent_nested_fixed_stmt = true
+resharper_indent_nested_foreach_stmt = true
+resharper_indent_nested_for_stmt = true
+resharper_indent_nested_lock_stmt = true
+resharper_indent_nested_usings_stmt = true
+resharper_indent_nested_while_stmt = true
+resharper_indent_preprocessor_if = usual_indent
+resharper_indent_preprocessor_other = usual_indent
+resharper_int_align = true
+resharper_keep_existing_arrangement = false
+resharper_keep_existing_linebreaks = false
+resharper_max_initializer_elements_on_line = 1
+resharper_outdent_commas = true
+resharper_outdent_dots = true
+resharper_wrap_array_initializer_style = chop_always
+resharper_wrap_before_comma = false
+resharper_wrap_object_and_collection_initializer_style = chop_always
+
+[*.cs]
+indent_style = space
+indent_size = 4
+tab_width = 4
diff --git a/src/NSExt.sln b/src/NSExt.sln
new file mode 100644
index 0000000..25a57b6
--- /dev/null
+++ b/src/NSExt.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "NSExt\NSExt.csproj", "{54814D1B-C587-4D90-A7BE-4BE1E170D5FC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {54814D1B-C587-4D90-A7BE-4BE1E170D5FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/src/NSExt.sln.DotSettings b/src/NSExt.sln.DotSettings
new file mode 100644
index 0000000..bc7c36a
--- /dev/null
+++ b/src/NSExt.sln.DotSettings
@@ -0,0 +1,95 @@
+
+ DO_NOT_SHOW
+ DO_NOT_SHOW
+ <?xml version="1.0" encoding="utf-16"?><Profile name="Built-in: Full Cleanup With File Header"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CppAddTypenameTemplateKeywords>True</CppAddTypenameTemplateKeywords><CppRemoveCastDescriptor>True</CppRemoveCastDescriptor><CppRemoveElseKeyword>True</CppRemoveElseKeyword><CppShortenQualifiedName>True</CppShortenQualifiedName><CppDeleteRedundantSpecifier>True</CppDeleteRedundantSpecifier><CppRemoveStatement>True</CppRemoveStatement><CppDeleteRedundantTypenameTemplateKeywords>True</CppDeleteRedundantTypenameTemplateKeywords><CppCStyleToStaticCastDescriptor>True</CppCStyleToStaticCastDescriptor><CppReplaceExpressionWithBooleanConst>True</CppReplaceExpressionWithBooleanConst><CppMakeIfConstexpr>True</CppMakeIfConstexpr><CppMakePostfixOperatorPrefix>True</CppMakePostfixOperatorPrefix><CppChangeSmartPointerToMakeFunction>True</CppChangeSmartPointerToMakeFunction><CppReplaceThrowWithRethrowFix>True</CppReplaceThrowWithRethrowFix><CppTypeTraitAliasDescriptor>True</CppTypeTraitAliasDescriptor><CppReplaceExpressionWithNullptr>True</CppReplaceExpressionWithNullptr><CppReplaceTieWithStructuredBindingDescriptor>True</CppReplaceTieWithStructuredBindingDescriptor><CppUseAssociativeContainsDescriptor>True</CppUseAssociativeContainsDescriptor><CppUseEraseAlgorithmDescriptor>True</CppUseEraseAlgorithmDescriptor><CppCodeStyleCleanupDescriptor ArrangeBraces="True" ArrangeAuto="True" ArrangeFunctionDeclarations="True" ArrangeNestedNamespaces="True" ArrangeTypeAliases="True" ArrangeCVQualifiers="True" ArrangeSlashesInIncludeDirectives="True" ArrangeOverridingFunctions="True" SortIncludeDirectives="True" SortMemberInitializers="True" /><CppReformatCode>True</CppReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" ArrangeArgumentsStyle="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><RemoveCodeRedundanciesVB>True</RemoveCodeRedundanciesVB><Xaml.RedundantFreezeAttribute>True</Xaml.RedundantFreezeAttribute><Xaml.RemoveRedundantModifiersAttribute>True</Xaml.RemoveRedundantModifiersAttribute><Xaml.RemoveRedundantNameAttribute>True</Xaml.RemoveRedundantNameAttribute><Xaml.RemoveRedundantResource>True</Xaml.RemoveRedundantResource><Xaml.RemoveRedundantCollectionProperty>True</Xaml.RemoveRedundantCollectionProperty><Xaml.RemoveRedundantAttachedPropertySetter>True</Xaml.RemoveRedundantAttachedPropertySetter><Xaml.RemoveRedundantStyledValue>True</Xaml.RemoveRedundantStyledValue><Xaml.RemoveRedundantNamespaceAlias>True</Xaml.RemoveRedundantNamespaceAlias><Xaml.RemoveForbiddenResourceName>True</Xaml.RemoveForbiddenResourceName><Xaml.RemoveRedundantGridDefinitionsAttribute>True</Xaml.RemoveRedundantGridDefinitionsAttribute><Xaml.RemoveRedundantUpdateSourceTriggerAttribute>True</Xaml.RemoveRedundantUpdateSourceTriggerAttribute><Xaml.RemoveRedundantBindingModeAttribute>True</Xaml.RemoveRedundantBindingModeAttribute><Xaml.RemoveRedundantGridSpanAttribut>True</Xaml.RemoveRedundantGridSpanAttribut><XMLReformatCode>True</XMLReformatCode><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><HtmlReformatCode>True</HtmlReformatCode><VBOptimizeImports>True</VBOptimizeImports><VBShortenReferences>True</VBShortenReferences><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><VBReformatCode>True</VBReformatCode><VBFormatDocComments>True</VBFormatDocComments><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><IDEA_SETTINGS><profile version="1.0">
+ <option name="myName" value="Built-in: Full Cleanup With File Header" />
+</profile></IDEA_SETTINGS><RIDER_SETTINGS><profile>
+ <Language id="CSS">
+ <Reformat>true</Reformat>
+ <Rearrange>true</Rearrange>
+ </Language>
+ <Language id="EditorConfig">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="HTML">
+ <Reformat>true</Reformat>
+ <Rearrange>true</Rearrange>
+ <OptimizeImports>true</OptimizeImports>
+ </Language>
+ <Language id="HTTP Request">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Handlebars">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Ini">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="JSON">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Jade">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="JavaScript">
+ <Reformat>true</Reformat>
+ <Rearrange>true</Rearrange>
+ <OptimizeImports>true</OptimizeImports>
+ </Language>
+ <Language id="Markdown">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Properties">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="RELAX-NG">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="SQL">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="XML">
+ <Reformat>true</Reformat>
+ <Rearrange>true</Rearrange>
+ <OptimizeImports>true</OptimizeImports>
+ </Language>
+ <Language id="yaml">
+ <Reformat>true</Reformat>
+ </Language>
+</profile></RIDER_SETTINGS><CSUpdateFileHeader>True</CSUpdateFileHeader><CppUpdateFileHeader>True</CppUpdateFileHeader></Profile>
+ <?xml version="1.0" encoding="utf-16"?>
+<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
+ <TypePattern DisplayName="Type Pattern">
+ <Entry DisplayName="Entry">
+ <Entry.Match>
+ <Kind Is="Property" />
+ </Entry.Match>
+ <Entry.SortBy>
+ <Name />
+ </Entry.SortBy>
+ </Entry>
+ </TypePattern>
+</Patterns>
+ DI
+ DO
+ IV
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
+ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
+ True
+ @program: $PROJECT$
+@file: $FILENAME$
+@author: tao ke
+@mailto: taokeu@gmail.com
+@created: $CREATED_MONTH$/$CREATED_DAY$/$CREATED_YEAR$ $CREATED_TIME$
+
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
\ No newline at end of file
diff --git a/src/NSExt/ByteExtensions.cs b/src/NSExt/ByteExtensions.cs
new file mode 100644
index 0000000..a72fcdb
--- /dev/null
+++ b/src/NSExt/ByteExtensions.cs
@@ -0,0 +1,34 @@
+// @program: NSExt
+// @file: ByteExtensions.cs
+// @author: tao ke
+// @mailto: taokeu@gmail.com
+// @created: 07/15/2022 16:49
+
+using System.Text;
+
+namespace NSExt;
+
+public static class ByteExtensions
+{
+ ///
+ /// base64编码
+ ///
+ /// 待编码的字节数组
+ /// 编码后的base64字符串
+ public static string Base64(this byte[] me)
+ {
+ return Convert.ToBase64String(me);
+ }
+
+
+ ///
+ /// 将字节数组解码成字符串
+ ///
+ /// 字节数组
+ /// 字符串使用的编码方式
+ /// 解码后的原始字符串
+ public static string HexDe(this byte[] me, Encoding e)
+ {
+ return e.GetString(me);
+ }
+}
diff --git a/src/NSExt/DateTimeExtensions.cs b/src/NSExt/DateTimeExtensions.cs
new file mode 100644
index 0000000..22a33d5
--- /dev/null
+++ b/src/NSExt/DateTimeExtensions.cs
@@ -0,0 +1,81 @@
+// @program: NSExt
+// @file: DateTimeExtensions.cs
+// @author: tao ke
+// @mailto: taokeu@gmail.com
+// @created: 07/15/2022 16:49
+
+// ReSharper disable UnusedMember.Global
+
+namespace NSExt;
+
+public static class DateTimeExtensions
+{
+ ///
+ /// 将一个过去时间对象与当前时间相减转换成“xx以前”的字符串,如2秒以前,3天以前
+ ///
+ /// 时间对象
+ /// 字符串
+ public static string TimeAgo(this DateTime me)
+ {
+ var ts = DateTime.Now - me;
+ if (ts.Days > 0) return ts.Days + "天前";
+
+ if (ts.Hours > 0) return ts.Hours + "小时前";
+
+ if (ts.Minutes > 0) return ts.Minutes + "分钟前";
+
+ return ts.Seconds + "秒前";
+ }
+
+
+ ///
+ /// 指定时间的世界协调时的unix时间戳形式
+ ///
+ /// 指定时间
+ /// unix时间戳
+ public static long TimeUnixUtc(this DateTime me)
+ {
+ return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
+ }
+
+ ///
+ /// 指定时间的世界协调时的unix时间戳形式(毫秒)
+ ///
+ ///
+ ///
+ public static long TimeUnixUtcMs(this DateTime me)
+ {
+ return (me.ToUniversalTime().Ticks - 621355968000000000) / 10000;
+ }
+
+
+ // ReSharper disable once InconsistentNaming
+ public static string yyyyMM(this DateTime me)
+ {
+ return me.ToString("yyyy-MM");
+ }
+
+ // ReSharper disable once InconsistentNaming
+ public static string yyyyMMdd(this DateTime me)
+ {
+ return me.ToString("yyyy-MM-dd");
+ }
+
+ // ReSharper disable once InconsistentNaming
+ public static string yyyyMMddHHmm(this DateTime me)
+ {
+ return me.ToString("yyyy-MM-dd HH:mm");
+ }
+
+
+ // ReSharper disable once InconsistentNaming
+ public static string yyyyMMddHHmmss(this DateTime me)
+ {
+ return me.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ public static string yyyyMMddHHmmssfff(this DateTime me)
+ {
+ return me.ToString("yyyy-MM-dd HH:mm:ss.fff");
+ }
+}
diff --git a/src/NSExt/DecimalExtensions.cs b/src/NSExt/DecimalExtensions.cs
new file mode 100644
index 0000000..d6fe176
--- /dev/null
+++ b/src/NSExt/DecimalExtensions.cs
@@ -0,0 +1,22 @@
+// @program: NSExt
+// @file: DecimalExtensions.cs
+// @author: tao ke
+// @mailto: taokeu@gmail.com
+// @created: 07/15/2022 16:49
+
+namespace NSExt;
+
+public static class DecimalExtensions
+{
+ ///
+ /// 四舍五入后的近似值
+ ///
+ /// 数字
+ /// 小数点位数
+ /// 处理后的值
+ public static decimal Round(this decimal me, int place)
+ {
+ var dec = Math.Round(me, place);
+ return dec;
+ }
+}
diff --git a/src/NSExt/EnumExtensions.cs b/src/NSExt/EnumExtensions.cs
new file mode 100644
index 0000000..f3b7221
--- /dev/null
+++ b/src/NSExt/EnumExtensions.cs
@@ -0,0 +1,25 @@
+// @program: NSExt
+// @file: EnumExtensions.cs
+// @author: tao ke
+// @mailto: taokeu@gmail.com
+// @created: 07/15/2022 16:49
+
+using System.ComponentModel;
+
+namespace NSExt;
+
+public static class EnumExtensions
+{
+ ///
+ /// 获取枚举的description属性
+ ///
+ /// 枚举对象
+ /// description属性
+ public static string Desc(this Enum e)
+ {
+ var t = e.GetType();
+ var fi = t.GetField(Enum.GetName(t, e)!);
+ var attrs = (DescriptionAttribute[])fi!.GetCustomAttributes(typeof(DescriptionAttribute), false);
+ return (attrs.Length != 0 ? attrs[0].Description : Enum.GetName(t, e)) ?? "";
+ }
+}
diff --git a/src/NSExt/EnumerableExtensions.cs b/src/NSExt/EnumerableExtensions.cs
new file mode 100644
index 0000000..69462fa
--- /dev/null
+++ b/src/NSExt/EnumerableExtensions.cs
@@ -0,0 +1,32 @@
+// @program: NSExt
+// @file: EnumerableExtensions.cs
+// @author: tao ke
+// @mailto: taokeu@gmail.com
+// @created: 07/15/2022 16:49
+
+namespace NSExt;
+
+public static class EnumerableExtensions
+{
+ ///
+ /// 将列表转成分隔符分隔的字符串
+ ///
+ ///
+ ///
+ ///
+ public static string Join(this IEnumerable