├── Docs
├── media
│ └── PayPal.gif
├── Content
│ ├── VersionHistory
│ │ ├── v2019.10.27.0.md
│ │ ├── v2021.7.5.0.md
│ │ ├── v2023.2.12.0.md
│ │ ├── v2022.7.29.0.md
│ │ ├── VersionHistory.md
│ │ └── v2025.9.12.0.md
│ ├── KnownIssues.md
│ ├── Installation.md
│ ├── SystemRequirements.md
│ ├── Contributing.md
│ └── Welcome.md
├── ContentLayout.content
└── ExtendedDocCommentsProviderDocs.shfbproj
├── Source
├── VSIXPackage.png
├── VSIXPreview.png
├── ExtendedDocCommentsProvider.snk
├── GlobalSuppressions.cs
├── ElementUsage.cs
├── source.extension.vsixmanifest
├── Properties
│ └── AssemblyInfo.cs
├── ElementAttribute.cs
├── SyntaxExtensions.cs
├── ExtendedDocCommentsProvider.csproj
├── CommentsElement.cs
├── CSharpXmlDocCommentsCompletionProvider.cs
└── License.rtf
├── ExtendedDocCommentsProvider.slnx
├── .github
└── FUNDING.yml
├── README.md
├── .gitignore
├── LICENSE
└── .editorconfig
/Docs/media/PayPal.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Docs/media/PayPal.gif
--------------------------------------------------------------------------------
/Source/VSIXPackage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Source/VSIXPackage.png
--------------------------------------------------------------------------------
/Source/VSIXPreview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Source/VSIXPreview.png
--------------------------------------------------------------------------------
/Source/ExtendedDocCommentsProvider.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Source/ExtendedDocCommentsProvider.snk
--------------------------------------------------------------------------------
/Docs/Content/VersionHistory/v2019.10.27.0.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: 34d99bb4-76e2-4f02-b2e4-1feaab4dbba8
3 | alt-uid: v2019-10-27-0
4 | title: Version 2019.10.27.0
5 | keywords: "versions, 2019.10.27.0"
6 | ---
7 |
8 | Initial release.
9 |
10 |
11 |
12 | ## See Also
13 |
14 |
15 | **Other Resources**
16 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7)
17 |
--------------------------------------------------------------------------------
/Docs/Content/VersionHistory/v2021.7.5.0.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: 16fd137b-699a-4260-906f-59d94818ff7a
3 | alt-uid: v2021-7-5-0
4 | title: Version 2021.7.5.0
5 | keywords: "versions, 2021.7.5.0"
6 | ---
7 |
8 | Changes made in this release:
9 |
10 |
11 | - Added support for Visual Studio 2022.
12 |
13 |
14 |
15 | ## See Also
16 |
17 |
18 | **Other Resources**
19 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7)
20 |
--------------------------------------------------------------------------------
/Docs/Content/VersionHistory/v2023.2.12.0.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: 6857ece7-59b8-4ad0-86bd-ae7453b97faf
3 | alt-uid: v2023-2-12-0
4 | title: Version 2023.2.12.0
5 | keywords: "versions, 2023.2.12.0"
6 | ---
7 |
8 | Changes made in this release:
9 |
10 |
11 | - Added the self-closing option to the `see` and `seealso`
12 | elements.
13 |
14 |
15 |
16 | ## See Also
17 |
18 |
19 | **Other Resources**
20 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7)
21 |
--------------------------------------------------------------------------------
/Docs/Content/VersionHistory/v2022.7.29.0.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: 23ea721a-0a75-48c7-8457-7614bf3c4926
3 | alt-uid: v2022-7-29-0
4 | title: Version 2022.7.29.0
5 | keywords: "versions, 2022.7.29.0"
6 | ---
7 |
8 | Changes made in this release:
9 |
10 |
11 | - Added support for the `title` attribute and the `todo`
12 | note type for the `note` XML comments element.
13 |
14 |
15 |
16 | ## See Also
17 |
18 |
19 | **Other Resources**
20 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7)
21 |
--------------------------------------------------------------------------------
/ExtendedDocCommentsProvider.slnx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Docs/Content/VersionHistory/VersionHistory.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: caa20db4-521f-4c4c-8399-aea8a81ae6a7
3 | alt-uid: VersionHistory
4 | title: Version History
5 | keywords: "version, history"
6 | ---
7 |
8 | This topic describes the various changes made to the Extended XML Documentation Comments Provider
9 | over the life of the project. Select a version below to see a description of its changes.
10 |
11 |
12 |
13 | - [](@f05af659-63c9-439b-8e07-3105f10cfb4a)
14 | - [](@6857ece7-59b8-4ad0-86bd-ae7453b97faf)
15 | - [](@23ea721a-0a75-48c7-8457-7614bf3c4926)
16 | - [](@16fd137b-699a-4260-906f-59d94818ff7a)
17 | - [](@34d99bb4-76e2-4f02-b2e4-1feaab4dbba8)
18 |
19 |
20 |
21 | ## See Also
22 |
23 |
24 | **Other Resources**
25 | [](@141160ac-ba6a-4f6d-a802-1110aadea932)
26 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ewsoftware]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 |
--------------------------------------------------------------------------------
/Docs/Content/VersionHistory/v2025.9.12.0.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: f05af659-63c9-439b-8e07-3105f10cfb4a
3 | alt-uid: v2025-9-12-0
4 | title: Version 2025.9.12.0
5 | keywords: "versions, 2025.9.12.0"
6 | ---
7 |
8 | Changes made in this release:
9 |
10 |
11 | > [!IMPORTANT]
12 | > As of this release, only Visual Studio 2022 and later are supported. Support for Visual Studio
13 | > 2019 has been dropped. I do not use the older versions anymore, it will allow me to simplify the extension
14 | > projects and keep the package references more up to date without the risk of breaking the build, and implement
15 | > future features without regard to maintaining backward compatibility with the older versions.
16 | >
17 | >
18 |
19 | - Enabled installation on ARM64 PCs.
20 | - Enabled installation in Visual Studio 2026.
21 |
22 |
23 |
24 | ## See Also
25 |
26 |
27 | **Other Resources**
28 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7)
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Welcome to the **Extended XML Documentation Comments Completion Provider** project.
2 |
3 | * [Get the current release](https://github.com/EWSoftware/ExtendedDocCommentsProvider/releases)
4 | * [Ask a question or open an issue](https://github.com/EWSoftware/ExtendedDocCommentsProvider/issues)
5 | * [Getting Started](https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/141160ac-ba6a-4f6d-a802-1110aadea932.htm)
6 | * [System Requirements and Building the Code](https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/3BBB6221-417C-4F5C-B89A-563A8052CE35.htm)
7 | * [Contributing](https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/C60519F2-A2F7-4EB1-883F-96C51073CEB3.htm)
8 |
9 | This project is an editor extension that augments the standard C# XML documentation comments elements with
10 | custom elements, attributes, and attribute values supported by the Sandcastle Help File Builder and other
11 | documentation tools.
12 |
--------------------------------------------------------------------------------
/Docs/ContentLayout.content:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Source/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
1 | // This file is used by Code Analysis to maintain SuppressMessage
2 | // attributes that are applied to this project.
3 | // Project-level suppressions either have no target or are given
4 | // a specific target and scoped to a namespace, type, member, etc.
5 |
6 | using System.Diagnostics.CodeAnalysis;
7 |
8 | [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:EWSoftware.CompletionProviders.CSharpXmlDocCommentsCompletionProvider.TriggerOnTypingLetters(Microsoft.CodeAnalysis.Options.OptionSet)~System.Boolean")]
9 | [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:EWSoftware.CompletionProviders.CSharpXmlDocCommentsCompletionProvider.GetItemsAsync(Microsoft.CodeAnalysis.Document,System.Int32,Microsoft.CodeAnalysis.Completion.CompletionTrigger,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Completion.CompletionItem}}")]
10 |
--------------------------------------------------------------------------------
/Docs/Content/KnownIssues.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: b146cb94-e594-4462-9262-d5cdba76c331
3 | alt-uid: KnownIssues
4 | title: Known Issues
5 | keywords: known issues
6 | ---
7 | The following are some known issues.
8 |
9 | - Completion providers are additive. Each one returns a set of items to add to the completion list based on the
10 | current editor context. The providers are unaware of other providers and the items added by them. They cannot
11 | remove items from other providers or make decisions about what to add based on other items that may appear.
12 |
13 | As such, you will see completion items from the built-in XML comments completion provider that may not be
14 | appropriate. For example, you will see the standard set of inline elements inside of the `revisionHistory`
15 | element. The same issue can be seen with standard elements such as `list`. This provider does allow the
16 | definition of valid parent elements so it will not present the custom child elements in inappropriate contexts.
17 | - Only C# is supported right now. A provider for Visual Basic is planned for a later release.
18 | - The current set of extended elements, attributes, and values is currently fixed and cannot be
19 | changed. A future release will allow the items to be customized and additional user-defined elements to be
20 | added.
21 |
22 | ## See Also
23 | **Other Resources**
24 | [](@141160ac-ba6a-4f6d-a802-1110aadea932)
25 |
--------------------------------------------------------------------------------
/Docs/Content/Installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: 102EF998-5094-482A-B708-9DA64C04C859
3 | alt-uid: Installation
4 | title: Installation Instructions and Usage Notes
5 | keywords: installation, usage
6 | ---
7 |
8 | To install this package:
9 |
10 |
11 | - Download the latest release of the VSIX installer for your version of Visual Studio from the
12 | [Releases](https://GitHub.com/EWSoftware/ExtendedDocCommentsProvider/releases) page of the project site. The package can be installed in Visual Studio 2019 or Visual Studio
13 | 2022 or later.
14 | - Close all open instances of Visual Studio before installing the package.
15 | - Run the downloaded package and follow the prompts to install it.
16 |
17 |
18 | This package can also be installed from within Visual Studio from the Visual Studio Marketplace
19 | ([Visual Studio 2019](https://marketplace.visualstudio.com/items?itemName=EWoodruff.ExtendedDocCommentsProvider) or
20 | [Visual Studio 2022 or later](https://marketplace.visualstudio.com/items?itemName=EWoodruff.ExtendedDocCommentsProvider2022)) using the **Tools | Extension and Updates** option. Select the online marketplace and
21 | search for "doc comments provider". Include the quote marks for an exact match and find the one created by
22 | *EWSoftware*. Once found, you can click the **Download** button to download and
23 | install it.
24 |
25 |
26 | Once installed, the extended elements, attributes, and attribute values will be provided in the
27 | completion popup list in the source code editor when entering XML comments.
28 |
29 |
30 |
31 | ## See Also
32 |
33 |
34 | **Other Resources**
35 | [](@141160ac-ba6a-4f6d-a802-1110aadea932)
36 |
--------------------------------------------------------------------------------
/Source/ElementUsage.cs:
--------------------------------------------------------------------------------
1 | //===============================================================================================================
2 | // System : Extended Doc Comments Completion Provider Package
3 | // File : ElementUsage.cs
4 | // Author : Eric Woodruff (Eric@EWoodruff.us)
5 | // Updated : 10/21/2019
6 | // Note : Copyright 2019, Eric Woodruff, All rights reserved
7 | //
8 | // This file contains the enumerated type that defines comment element usage types
9 | //
10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
11 | // distributed with the code and can be found at the project website:
12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright
13 | // notices must remain intact in all applications, documentation, and source files.
14 | //
15 | // Date Who Comments
16 | // ==============================================================================================================
17 | // 10/18/2019 EFW Created the code
18 | //===============================================================================================================
19 |
20 | using System;
21 |
22 | namespace EWSoftware.CompletionProviders
23 | {
24 | ///
25 | /// This enumerated type defines comment element usage types
26 | ///
27 | [Serializable]
28 | public enum ElementUsage
29 | {
30 | ///
31 | /// Top-level only
32 | ///
33 | TopLevel = 0,
34 | ///
35 | /// Nested only
36 | ///
37 | Nested = 1,
38 | ///
39 | /// Can be top-level or nested
40 | ///
41 | Both = 2
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 | StyleCop.Cache
10 | _ReSharper*/
11 | *.[Rr]e[Ss]harper
12 | *.DotSettings.user
13 | launchSettings.json
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | build/
23 | bld/
24 | [Bb]in/
25 | [Oo]bj/
26 |
27 | # Roslyn cache directories
28 | *.vs/
29 |
30 | # Visual Studio profiler
31 | *.psess
32 | *.vsp
33 | *.vspx
34 |
35 | # Sandcastle Help File Builder is a documentation generator add-in
36 | Documentation/**/Help/
37 | Documentation/WebHelp/
38 | **/Doc/Help/
39 | **/Docs/Help/
40 | *.shfbproj_*
41 |
42 | # Publish Web Output
43 | *.[Pp]ublish.xml
44 | *.pubxml
45 | *.publishproj
46 | **/PrecompiledWeb
47 |
48 | # NuGet Packages
49 | *.nupkg
50 | # The packages folder can be ignored because of Package Restore
51 | **/packages/*
52 | *.lock.json
53 |
54 | # Others
55 | ~$*
56 | *~
57 | *.publishsettings
58 | *CodeAnalysisLog.xml
59 | WebProject.lastcodeanalysissucceeded
60 |
61 | # Backup & report files from converting an old project file
62 | # to a newer Visual Studio version. Backup files are not needed,
63 | # because we have git ;-)
64 | _UpgradeReport_Files/
65 | Backup*/
66 | UpgradeLog*.XML
67 | UpgradeLog*.htm
68 |
69 | # Non-distributable and private local stuff
70 | Deployment/
71 | NonDist/
72 |
73 | # =========================
74 | # Operating System Files
75 | # =========================
76 |
77 | # Windows
78 | # =========================
79 |
80 | # Windows image file caches
81 | Thumbs.db
82 | ehthumbs.db
83 |
84 | # Folder config file
85 | Desktop.ini
86 |
87 | # Recycle Bin used on file shares
88 | $RECYCLE.BIN/
89 |
90 | # Windows Installer files
91 | *.cab
92 | *.msi
93 | *.msm
94 | *.msp
95 |
96 | # Windows shortcuts
97 | *.lnk
98 |
--------------------------------------------------------------------------------
/Docs/Content/SystemRequirements.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: 3BBB6221-417C-4F5C-B89A-563A8052CE35
3 | alt-uid: SystemRequirements
4 | title: System Requirements and Building the Code
5 | keywords: system requirements
6 | ---
7 | The master branch is for Visual Studio 2019 and later and is the default branch for all current and future
8 | development. In order to build the projects you will need Visual Studio 2019 or later.
9 |
10 | ## Folder Layout
11 | *.\Source* - This folder contains the source code for all of the projects.
12 |
13 | *.\Docs* - The [Sandcastle Help File Builder](https://GitHub.com/EWSoftware/SHFB) project used to manage the
14 | extended documentation comments provider project's documentation.
15 |
16 | *.\Deployment* - This folder contains the deployment resources (the installer and all related files) generated
17 | by building the projects.
18 |
19 | ## Building and Debugging the Projects
20 | To build the projects, open the solution file (*\*.sln*) for your version of Visual Studio (currently 2019 or
21 | 2022) found in the *Source\\* folder and build it. You can also run the *MasterBuild.bat* script from a command
22 | prompt to build the projects.
23 |
24 | In order to debug the projects:
25 |
26 | - Set the *ExtendedDocCommentsProvider* project as the default project and then open its project properties.
27 | - Go to the **Debug** category.
28 | - For the **Start Action** option, set it to **Start external program**, click the "..." button after the text
29 | box, navigate to the installation folder for your version of Visual Studio and select the *devenv.exe* file in
30 | that folder (i.e. *C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe*).
31 | - For the **Command line arguments** option, enter the value `/rootsuffix Exp`.
32 | - When you run the project, it should start a new instance of Visual Studio using the experimental instance
33 | settings.
34 |
35 | ## See Also
36 | **Other Resources**
37 | [](@141160ac-ba6a-4f6d-a802-1110aadea932)
38 | [License Agreement](https://github.com/EWSoftware/ExtendedDocCommentsProvider/blob/master/LICENSE)
39 |
--------------------------------------------------------------------------------
/Source/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Extended XML Doc Comments Provider (VS2022+)
6 | An editor extension that augments the standard C# XML documentation comments elements with custom elements, attributes, and attribute values supported by the Sandcastle Help File Builder and other documentation tools.
7 | https://github.com/EWSoftware/ExtendedDocCommentsProvider
8 | License.rtf
9 | https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/102EF998-5094-482A-B708-9DA64C04C859.htm
10 | https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/caa20db4-521f-4c4c-8399-aea8a81ae6a7.htm
11 | VSIXPackage.png
12 | VSIXPreview.png
13 | documentation;comments;completion provider;sandcastle;shfb;help file builder
14 |
15 |
16 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Microsoft Public License (Ms-PL)
2 |
3 | This license governs use of the accompanying software. If you use the
4 | software, you accept this license. If you do not accept the license, do not
5 | use the software.
6 |
7 | 1. Definitions
8 |
9 | The terms "reproduce," "reproduction," "derivative works," and "distribution"
10 | have the same meaning here as under U.S. copyright law.
11 |
12 | A "contribution" is the original software, or any additions or changes to the
13 | software.
14 |
15 | A "contributor" is any person that distributes its contribution under this
16 | license.
17 |
18 | "Licensed patents" are a contributor's patent claims that read directly on its
19 | contribution.
20 |
21 | 2. Grant of Rights
22 |
23 | (A) Copyright Grant- Subject to the terms of this license, including the
24 | license conditions and limitations in section 3, each contributor grants you a
25 | non-exclusive, worldwide, royalty-free copyright license to reproduce its
26 | contribution, prepare derivative works of its contribution, and distribute its
27 | contribution or any derivative works that you create.
28 |
29 | (B) Patent Grant- Subject to the terms of this license, including the license
30 | conditions and limitations in section 3, each contributor grants you a
31 | non-exclusive, worldwide, royalty-free license under its licensed patents to
32 | make, have made, use, sell, offer for sale, import, and/or otherwise dispose
33 | of its contribution in the software or derivative works of the contribution in
34 | the software.
35 |
36 | 3. Conditions and Limitations
37 |
38 | (A) No Trademark License- This license does not grant you rights to use any
39 | contributors' name, logo, or trademarks.
40 |
41 | (B) If you bring a patent claim against any contributor over patents that you
42 | claim are infringed by the software, your patent license from such contributor
43 | to the software ends automatically.
44 |
45 | (C) If you distribute any portion of the software, you must retain all
46 | copyright, patent, trademark, and attribution notices that are present in the
47 | software.
48 |
49 | (D) If you distribute any portion of the software in source code form, you may
50 | do so only under this license by including a complete copy of this license
51 | with your distribution. If you distribute any portion of the software in
52 | compiled or object code form, you may only do so under a license that complies
53 | with this license.
54 |
55 | (E) The software is licensed "as-is." You bear the risk of using it. The
56 | contributors give no express warranties, guarantees or conditions. You may
57 | have additional consumer rights under your local laws which this license
58 | cannot change. To the extent permitted under your local laws, the contributors
59 | exclude the implied warranties of merchantability, fitness for a particular
60 | purpose and non-infringement.
61 |
--------------------------------------------------------------------------------
/Docs/Content/Contributing.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: C60519F2-A2F7-4EB1-883F-96C51073CEB3
3 | alt-uid: Contributing
4 | title: Contributing
5 | keywords: Contributing
6 | ---
7 |
8 |
9 |
10 |
11 | ## Issues
12 | If you don't feel like working on the code yourself,
13 | [filing an issue](https://github.com/EWSoftware/ExtendedDocCommentsProvider/issues "Extended Doc Comments Provider Issues")
14 | and letting me handle the change is fine. You don't need to file an issue for trivial changes (i.e. typos, minor
15 | fixes, etc.). Just send a pull request if it's small.
16 |
17 | If an issue is complex, adds or removes functionality, changes existing behavior, etc. consider filing an issue
18 | and giving me time to respond before sending a corresponding pull request. If you want to work on the issue,
19 | just let it be known on the issue thread. Giving me a chance to review the issue will help save time and
20 | prevents you from wasting time on something that cannot be implemented. For example, I might let you know why
21 | existing behavior cannot be changed or about particular implementation constraints you need to keep in mind, etc.
22 |
23 | ## Contributing to the Project
24 | 1. Unless it is a trivial change such as a typo or minor fix, make sure that there is a corresponding issue for
25 | your change first. If there isn't, create one.
26 | 2. Create a fork in GitHub
27 | 3. Create a branch off the master branch. Name it something that makes sense, such as *issue-123* or
28 | *githubUserID-issue*. This makes it easy for everyone to figure out what the branch is used for. It also
29 | makes it easier to isolate your changes from incoming changes from the origin.
30 | 4. Commit your changes and push your changes to GitHub.
31 | 5. Create a pull request against the origin's master branch.
32 |
33 | ## Coding Style
34 | In general, use the Visual Studio defaults. Take a look at the existing code to see the styles in use. The
35 | *.editorconfig* file defines the preferred style defaults.
36 |
37 | 1. In source code, use four spaces for indentation, no tabs.
38 | 2. For XML, XAML, HTML, and similar file types, use two spaces for indentation and do use tabs.
39 | 3. Namespace imports should be specified at the top of the file, outside of the `namespace` declaration, and
40 | should be sorted alphabetically. Place `System.` namespaces at the top and blank lines between different top
41 | level groups. Remove any unused namespaces to avoid unnecessary clutter.
42 | 4. Use Allman style braces where each brace begins on a new line. A single line statement block can go without
43 | braces but the block must be properly indented on its own line.
44 | 5. Do not insert spaces after keywords in control flow statements (use `if(a < b)` instead of `if (a < b)`).
45 | 6. Use `camelCase` private members without leading underscores or other such prefixes like `m_`.
46 | 7. Always specify the visibility even if it is the default (i.e. `private string foo` not `string foo`).
47 |
48 | ## See Also
49 | **Other Resources**
50 | [](@141160ac-ba6a-4f6d-a802-1110aadea932)
51 | [License Agreement](https://github.com/EWSoftware/ExtendedDocCommentsProvider/blob/master/LICENSE)
52 |
--------------------------------------------------------------------------------
/Source/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | //===============================================================================================================
2 | // System : Extended Doc Comments Completion Provider Package
3 | // File : AssemblyInfo.cs
4 | // Author : Eric Woodruff (Eric@EWoodruff.us)
5 | // Updated : 09/12/2025
6 | // Note : Copyright 2019-2025, Eric Woodruff, All rights reserved
7 | //
8 | // Extended documentation comments completion provider package attributes
9 | //
10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
11 | // distributed with the code and can be found at the project website:
12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright
13 | // notices must remain intact in all applications, documentation, and source files.
14 | //
15 | // Date Who Comments
16 | // ==============================================================================================================
17 | // 10/22/2019 EFW Created the code
18 | //===============================================================================================================
19 |
20 | using System;
21 | using System.Reflection;
22 | using System.Resources;
23 | using System.Runtime.InteropServices;
24 |
25 | // General assembly information
26 | [assembly: AssemblyProduct("Extended Doc Comments Completion Provider Package")]
27 | [assembly: AssemblyTitle("Extended Doc Comments Completion Provider Package")]
28 | [assembly: AssemblyDescription("An editor extension that augments the standard C# XML documentation comments " +
29 | "elements with custom elements, attributes, and attribute values supported by the Sandcastle Help File " +
30 | "Builder and other documentation tools")]
31 | [assembly: AssemblyCompany("Eric Woodruff")]
32 | [assembly: AssemblyCopyright("Copyright \xA9 2019-2025, Eric Woodruff, All Rights Reserved")]
33 | [assembly: AssemblyCulture("")]
34 | #if DEBUG
35 | [assembly: AssemblyConfiguration("Debug")]
36 | #else
37 | [assembly: AssemblyConfiguration("Release")]
38 | #endif
39 |
40 | // This assembly is not CLS compliant
41 | [assembly: CLSCompliant(false)]
42 |
43 | // Not visible to COM
44 | [assembly: ComVisible(false)]
45 |
46 | // Resources contained within the assembly are English
47 | [assembly: NeutralResourcesLanguage("en")]
48 |
49 | // Version numbers. All version numbers for an assembly consists of the following four values:
50 | //
51 | // Year of release
52 | // Month of release
53 | // Day of release
54 | // Revision (typically zero unless multiple releases are made on the same day)
55 | //
56 |
57 | // Common assembly strong name version - Typically not change unless necessary but doesn't apply to this project
58 | // as it is self-contained and is not referenced by anything else. Keep it in sync with the versions below.
59 | [assembly: AssemblyVersion("2025.9.12.0")]
60 |
61 | // Common assembly file version
62 | //
63 | // This is used to set the assembly file version. This will change with each new release. MSIs only support a
64 | // Major value between 0 and 255 so we drop the century from the year on this one.
65 | [assembly: AssemblyFileVersion("25.9.12.0")]
66 |
67 | // Common product version
68 | //
69 | // This may contain additional text to indicate Alpha or Beta states. The version number will always match the
70 | // file version above but includes the century on the year.
71 | [assembly: AssemblyInformationalVersion("2025.9.12.0")]
72 |
--------------------------------------------------------------------------------
/Docs/Content/Welcome.md:
--------------------------------------------------------------------------------
1 | ---
2 | uid: 141160ac-ba6a-4f6d-a802-1110aadea932
3 | alt-uid: Welcome
4 | title: Welcome
5 | keywords: Welcome
6 | ---
7 |
8 |
9 | Welcome to the **Extended XML Documentation Comments Completion Provider** project.
10 |
11 | This project is a Visual Studio editor extension that augments the standard C# XML documentation comments
12 | elements with custom elements, attributes, and attribute values supported by the Sandcastle Help File Builder and
13 | other documentation tools. The following elements, attributes, and attribute values are provided:
14 |
15 | | Elements | Attributes | Attribute Values |
16 | | --- | --- | --- |
17 | | AttachedEventComments | | |
18 | | AttachedPropertyComments | | |
19 | | code | language | cs, cpp, c, fs, javascript, vb, vbnet, html, xml, xsl, xaml, sql, py, pshell, bat, none |
20 | | | title | |
21 | | | source | |
22 | | | region | |
23 | | | removeRegionMarkers | true, false |
24 | | | tabSize | |
25 | | | numberLines | true, false |
26 | | | outlining | true, false |
27 | | | keepSeeTags | true, false |
28 | | conceptualLink | | |
29 | | event | | |
30 | | list | type | definition |
31 | | | start | |
32 | | note | type | note, tip, implement, caller, inherit, caution, warning, important, security, cs, cpp, vb, todo |
33 | | | title | |
34 | | overloads | | |
35 | | preliminary | | |
36 | | revisionHistory | visible | true, false |
37 | | revision | date | |
38 | | | version | |
39 | | | author | |
40 | | | visible | true, false |
41 | | see/seealso | qualifyHint | true, false |
42 | | | autoUpgrade | true, false |
43 | | | href | |
44 | | | alt | |
45 | | | target | _blank, _self, _parent, _top |
46 | | threadsafety | static | true, false |
47 | | | instance | true, false |
48 | | token | | |
49 |
50 | For information on the above elements and all other XML comments elements, see the
51 | [Sandcastle XML Comments Guide](https://EWSoftware.github.io/XMLCommentsGuide/index.html "Sandcastle XML Comments Guide").
52 |
53 | ## Making a Donation
54 | If you would like to support this project, you can make a donation of any amount you like by clicking on the
55 | PayPal donation button below. Another option is to click the **Sponsor** button in the page footer to sponsor
56 | the project on GitHub with either a one-time or monthly amount.
57 |
58 | [](https://www.paypal.com/donate/?hosted_button_id=QK8P2B8B5WBJ2 "Make a donation")
59 |
60 | Thanks to those of you that have made a donation. It is much appreciated!
61 |
62 | ## See Also
63 | **Other Resources**
64 | [](@102EF998-5094-482A-B708-9DA64C04C859)
65 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7)
66 | [License Agreement](https://github.com/EWSoftware/ExtendedDocCommentsProvider/blob/master/LICENSE)
67 |
--------------------------------------------------------------------------------
/Source/ElementAttribute.cs:
--------------------------------------------------------------------------------
1 | //===============================================================================================================
2 | // System : Extended Doc Comments Completion Provider Package
3 | // File : ElementAttribute.cs
4 | // Author : Eric Woodruff (Eric@EWoodruff.us)
5 | // Updated : 10/21/2019
6 | // Note : Copyright 2019, Eric Woodruff, All rights reserved
7 | //
8 | // This file contains the class used to define XML documentation comments element attributes and their values
9 | //
10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
11 | // distributed with the code and can be found at the project website:
12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright
13 | // notices must remain intact in all applications, documentation, and source files.
14 | //
15 | // Date Who Comments
16 | // ==============================================================================================================
17 | // 10/18/2019 EFW Created the code
18 | //===============================================================================================================
19 |
20 | using System;
21 | using System.Collections.Generic;
22 | using System.Linq;
23 |
24 | namespace EWSoftware.CompletionProviders
25 | {
26 | ///
27 | /// This is used to define element attributes and their values
28 | ///
29 | public class ElementAttribute
30 | {
31 | #region Properties
32 | //=====================================================================
33 |
34 | ///
35 | /// The attribute name
36 | ///
37 | public string Name { get; set; }
38 |
39 | ///
40 | /// An optional description to show when the completion item is selected in the completion popup list
41 | ///
42 | /// If not set, no description will be shown
43 | public string Description { get; set; }
44 |
45 | public IEnumerable Values { get; }
46 |
47 | #endregion
48 |
49 | #region Constructors
50 | //=====================================================================
51 |
52 | ///
53 | /// Constructor for an attribute with no provided attribute values
54 | ///
55 | /// There are two overloads for the constructor
56 | public ElementAttribute() : this(null)
57 | {
58 | }
59 |
60 | ///
61 | /// Constructor for an attribute with provided attribute values
62 | ///
63 | /// An enumerable list of values or null if there are none
64 | public ElementAttribute(IEnumerable values)
65 | {
66 | this.Values = values ?? Enumerable.Empty();
67 | }
68 | #endregion
69 |
70 | #region Method overrides
71 | //=====================================================================
72 |
73 | ///
74 | /// This is overridden to compare element attributes by name
75 | ///
76 | /// The object to compare
77 | /// True if equal by attribute name, false if not
78 | public override bool Equals(object obj)
79 | {
80 | return (obj is ElementAttribute attr && attr.Name.Equals(this.Name, StringComparison.Ordinal));
81 | }
82 |
83 | ///
84 | public override int GetHashCode()
85 | {
86 | return this.Name.GetHashCode();
87 | }
88 | #endregion
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Source/SyntaxExtensions.cs:
--------------------------------------------------------------------------------
1 | //===============================================================================================================
2 | // System : Extended Doc Comments Completion Provider Package
3 | // File : SyntaxExtensions.cs
4 | // Author : Eric Woodruff (Eric@EWoodruff.us)
5 | // Updated : 10/21/2019
6 | // Note : Copyright 2019, Eric Woodruff, All rights reserved
7 | //
8 | // This file contains various syntax element extension methods
9 | //
10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
11 | // distributed with the code and can be found at the project website:
12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright
13 | // notices must remain intact in all applications, documentation, and source files.
14 | //
15 | // Date Who Comments
16 | // ==============================================================================================================
17 | // 10/09/2019 EFW Created the code
18 | //===============================================================================================================
19 |
20 | using System.Threading;
21 |
22 | using Microsoft.CodeAnalysis;
23 |
24 | namespace EWSoftware.CompletionProviders
25 | {
26 | ///
27 | /// This class contains various syntax element extension methods
28 | ///
29 | internal static class SyntaxExtensions
30 | {
31 | ///
32 | /// If the position is inside of a token, return that token. Otherwise, return the token to the left.
33 | ///
34 | /// The syntax tree to search
35 | /// The position to find
36 | /// A cancellation token used to cancel the operation
37 | public static SyntaxToken FindTokenOnLeftOfPosition(this SyntaxTree syntaxTree, int position,
38 | CancellationToken cancellationToken)
39 | {
40 | var root = syntaxTree.GetRoot(cancellationToken);
41 | var token = (position < root.FullSpan.End || !(root is ICompilationUnitSyntax)) ? root.FindToken(position, true) :
42 | root.GetLastToken(true, true, true, true).GetPreviousToken(false, true, false, false);
43 |
44 | if(position <= token.SpanStart)
45 | {
46 | do
47 | {
48 | var skippedToken = FindSkippedTokenBackward(token.LeadingTrivia, position);
49 | token = skippedToken.RawKind != 0 ? skippedToken : token.GetPreviousToken(false, true, false, false);
50 |
51 | } while(position <= token.SpanStart && root.FullSpan.Start < token.SpanStart);
52 | }
53 | else
54 | if(token.Span.End < position)
55 | {
56 | var skippedToken = FindSkippedTokenBackward(token.TrailingTrivia, position);
57 | token = skippedToken.RawKind != 0 ? skippedToken : token;
58 | }
59 |
60 | if(token.Span.Length == 0)
61 | token = token.GetPreviousToken();
62 |
63 | return token;
64 | }
65 |
66 | ///
67 | /// Look inside a trivia list for a skipped token that contains the given position
68 | ///
69 | /// The syntax trivia list to search
70 | /// The position to find
71 | private static SyntaxToken FindSkippedTokenBackward(SyntaxTriviaList triviaList, int position)
72 | {
73 | foreach(var trivia in triviaList.Reverse())
74 | {
75 | if(trivia.HasStructure && trivia.GetStructure() is ISkippedTokensTriviaSyntax skippedTokensTrivia)
76 | {
77 | foreach(var token in skippedTokensTrivia.Tokens)
78 | {
79 | if(token.Span.Length > 0 && token.SpanStart <= position)
80 | return token;
81 | }
82 | }
83 | }
84 |
85 | return default;
86 | }
87 |
88 | ///
89 | /// This is used to get the ancestor or a syntax node matching a specified type
90 | ///
91 | /// The node type to match
92 | /// The starting node
93 | /// The ancestor node of the specified type if found, null if not found
94 | public static TNode GetAncestor(this SyntaxNode node) where TNode : SyntaxNode
95 | {
96 | var current = node.Parent;
97 |
98 | while(current != null)
99 | {
100 | if(current is TNode tNode)
101 | return tNode;
102 |
103 | var parent = current.Parent;
104 |
105 | if(parent == null && current is IStructuredTriviaSyntax structuredTrivia)
106 | parent = structuredTrivia.ParentTrivia.Token.Parent;
107 |
108 | current = parent;
109 | }
110 |
111 | return null;
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/Source/ExtendedDocCommentsProvider.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 | true
9 |
10 |
11 | ExtendedDocCommentsProvider.snk
12 |
13 |
14 | true
15 | bin\Debug\
16 | DEBUG;TRACE
17 | full
18 | AnyCPU
19 | 7.3
20 | prompt
21 |
22 |
23 |
24 | Debug
25 | AnyCPU
26 | 2.0
27 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
28 | {AC787F6B-6FB3-4F84-B8AE-26252450F07C}
29 | Library
30 | Properties
31 | EWSoftware.CompletionProviders
32 | ExtendedDocCommentsProvider
33 | v4.7.2
34 | false
35 | true
36 | false
37 | false
38 | true
39 | true
40 | Program
41 | $(DevEnvDir)devenv.exe
42 | /rootsuffix Exp
43 | true
44 | AllEnabledByDefault
45 |
46 |
47 | true
48 | full
49 | false
50 | bin\Debug\
51 | DEBUG;TRACE
52 | prompt
53 | 4
54 | False
55 |
56 |
57 | pdbonly
58 | true
59 | bin\Release\
60 | TRACE
61 | prompt
62 | 4
63 | False
64 |
65 |
66 |
67 | PreserveNewest
68 | true
69 |
70 |
71 |
72 | Designer
73 |
74 |
75 |
76 |
77 | 4.14.0
78 |
79 |
80 | 4.14.0
81 |
82 |
83 | 4.14.0
84 |
85 |
86 | compile; build; native; contentfiles; analyzers; buildtransitive
87 |
88 |
89 | runtime; build; native; contentfiles; analyzers; buildtransitive
90 | all
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | true
106 | PreserveNewest
107 |
108 |
109 | true
110 | PreserveNewest
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | IF NOT "$(ConfigurationName)"=="Release" Goto Exit
120 |
121 | IF NOT EXIST "$(SolutionDir)..\Deployment\" MD "$(SolutionDir)..\Deployment\"
122 |
123 | Copy "$(TargetDir)$(TargetName).vsix" "$(SolutionDir)Deployment\$(TargetName).vsix"
124 |
125 | :Exit
126 |
127 |
128 |
135 |
--------------------------------------------------------------------------------
/Docs/ExtendedDocCommentsProviderDocs.shfbproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | v4.7.2
6 |
8 | Debug
9 | AnyCPU
10 | 2.0
11 | a405f2b6-a092-4dea-bc1e-4b9435e1b94f
12 | 2017.9.26.0
13 |
14 | ExtendedDocCommentsProviderDocs
15 | ExtendedDocCommentsProviderDocs
16 | ExtendedDocCommentsProviderDocs
17 |
18 | .NET Framework 4.8
19 | .\Help\
20 | ExtendedDocCommentsProvider
21 | en-US
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | Website
87 | Standard
88 | Default2022
89 | True
90 | True
91 | False
92 | False
93 | OnlyWarningsAndErrors
94 | 100
95 | Extended XML Documentation Comments Provider
96 | 2025.9.12.0
97 | Guid
98 | AboveNamespaces
99 | False
100 | False
101 | 2
102 | False
103 | https://GitHub.com/EWSoftware/ExtendedDocCommentsProvider
104 | Copyright \xA9 2019-2025, Eric Woodruff, All rights reserved
105 | Eric%40EWoodruff.us
106 | Blank
107 | Msdn
108 | True
109 | False
110 | Msdn
111 | <%3biframe src="%3bhttps://github.com/sponsors/EWSoftware/button"%3b title="%3bSponsor EWSoftware"%3b height="%3b32"%3b width="%3b114"%3b style="%3bborder: 0%3b border-radius: 6px%3b"%3b>%3b<%3b/iframe>%3b
112 |
113 | False
114 |
115 |
116 |
117 |
118 |
119 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 | PayPal
161 | Pay Pal
162 | True
163 |
164 |
165 |
166 |
167 |
169 |
170 |
171 |
172 |
173 |
174 | OnBuildSuccess
175 |
176 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | # Don't use tabs for indentation unless otherwise overridden
3 | indent_style = space
4 | end_of_line = crlf
5 | guidelines = 80 dotted, 114 dotted
6 | # (Please don't specify an indent_size here; that has too many unintended consequences.)
7 |
8 | # VSSPELL: Spell checker settings for all files
9 | vsspell_code_analyzer_ignore_identifier_if_private = true
10 | vsspell_code_analyzer_ignore_identifier_if_internal = true
11 | vsspell_code_analyzer_ignore_identifier_if_all_uppercase = true
12 | vsspell_code_analyzer_ignore_identifiers_within_member_bodies = true
13 | vsspell_code_analyzer_ignore_if_compiler_generated = true
14 | vsspell_code_analyzer_ignore_delimited_comments = true
15 | vsspell_code_analyzer_ignore_quadruple_slash_comments = true
16 | vsspell_code_analyzer_apply_to_all_c_style_languages = true
17 |
18 | [*.{aml,asax,ascx,asmx,asp,aspx,axml,config,content,cshtml,csproj,database,datasource,dbml,disco,discomap,dtsx,edmx,exclude,fxcop,htm,html,items,layout,maml,manifest,master,msha,myapp,nunit,nuspec,proj,projitems,props,publishproj,pubxml,rdl,rdlc,resx,ruleset,settings,shfbproj,shproj,sitemap,snippets,soap,svc,svcinfo,svcmap,targets,tasks,tokens,vbhtml,vbproj,vcxproj,vcxproj.filters,vsct,vsixmanifest,vstemplate,webinfo,wsdl,xaml,xamlcfg,xml,xsd,xsl,xslt,xsx}]
19 | # XML files of various types
20 | indent_style = tab
21 | indent_size = 2
22 | tab_width = 2
23 |
24 | [*.{cs,vb}]
25 | # C#/VB settings
26 | indent_size = 4
27 | tab_width = 4
28 |
29 | dotnet_sort_system_directives_first = true
30 |
31 | # Naming rules
32 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
33 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
34 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
35 |
36 | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
37 | dotnet_naming_rule.types_should_be_pascal_case.symbols = types
38 | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
39 |
40 | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
41 | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
42 | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
43 |
44 | # Symbol specifications
45 | dotnet_naming_symbols.interface.applicable_kinds = interface
46 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
47 | dotnet_naming_symbols.interface.required_modifiers =
48 |
49 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
50 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
51 | dotnet_naming_symbols.types.required_modifiers =
52 |
53 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
54 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
55 | dotnet_naming_symbols.non_field_members.required_modifiers =
56 |
57 | # Naming styles
58 | dotnet_naming_style.begins_with_i.required_prefix = I
59 | dotnet_naming_style.begins_with_i.required_suffix =
60 | dotnet_naming_style.begins_with_i.word_separator =
61 | dotnet_naming_style.begins_with_i.capitalization = pascal_case
62 |
63 | dotnet_naming_style.pascal_case.required_prefix =
64 | dotnet_naming_style.pascal_case.required_suffix =
65 | dotnet_naming_style.pascal_case.word_separator =
66 | dotnet_naming_style.pascal_case.capitalization = pascal_case
67 |
68 | dotnet_naming_style.pascal_case.required_prefix =
69 | dotnet_naming_style.pascal_case.required_suffix =
70 | dotnet_naming_style.pascal_case.word_separator =
71 | dotnet_naming_style.pascal_case.capitalization = pascal_case
72 |
73 | # Code style settings
74 | dotnet_style_predefined_type_for_locals_parameters_members = true:none
75 | dotnet_style_predefined_type_for_member_access = false:error
76 | dotnet_style_coalesce_expression = true:suggestion
77 | dotnet_style_collection_initializer = true:suggestion
78 | dotnet_style_explicit_tuple_names = true:error
79 | dotnet_style_null_propagation = true:suggestion
80 | dotnet_style_object_initializer = true:suggestion
81 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
82 | dotnet_style_prefer_auto_properties = true:silent
83 | dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
84 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent
85 | dotnet_style_prefer_conditional_expression_over_return = true:silent
86 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
87 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
88 | dotnet_style_prefer_compound_assignment = true:suggestion
89 | dotnet_style_prefer_simplified_interpolation = true:suggestion
90 | dotnet_style_namespace_match_folder = true:suggestion
91 | dotnet_style_operator_placement_when_wrapping = beginning_of_line
92 |
93 | # "This." and "Me." qualification. Use is preferred where true but the lightbulbs tend to show up in places
94 | # they aren't wanted (within static methods and nameof parameters etc.) so no suggestions are enabled.
95 | dotnet_style_qualification_for_event = true:none
96 | dotnet_style_qualification_for_field = false:none
97 | dotnet_style_qualification_for_method = true:none
98 | dotnet_style_qualification_for_property = true:none
99 |
100 | # Code analyzer settings
101 | # CA1303: Do not pass literals as localized parameters
102 | dotnet_diagnostic.CA1303.severity = none
103 |
104 | # IDE0010: Add missing cases
105 | dotnet_diagnostic.IDE0010.severity = none
106 |
107 | # IDE1006: Naming Styles
108 | dotnet_diagnostic.IDE1006.severity = none
109 |
110 | # These are disabled as we're still targeting .NET Framework as well and I don't want a lot of conditional code
111 | # to suppress these or I'm not ready to use them just yet.
112 | # IDE0056: Use index operator
113 | dotnet_diagnostic.IDE0056.severity = none
114 |
115 | # IDE0057: Use range operator
116 | dotnet_diagnostic.IDE0057.severity = none
117 |
118 | # IDE0066: Convert switch statement to expression
119 | dotnet_diagnostic.IDE0066.severity = none
120 |
121 | # CA1510: Use ArgumentNullException throw helper
122 | dotnet_diagnostic.CA1510.severity = none
123 |
124 | # CA1845: Use span-based 'string.Concat'
125 | dotnet_diagnostic.CA1845.severity = none
126 |
127 | # CA1846: Prefer 'AsSpan' over 'Substring'
128 | dotnet_diagnostic.CA1846.severity = none
129 |
130 | # CA1863: Use 'CompositeFormat'
131 | dotnet_diagnostic.CA1863.severity = none
132 |
133 | # CA1865: Use char overload
134 | dotnet_diagnostic.CA1865.severity = none
135 |
136 | # CA2249: Consider using 'string.Contains' instead of 'string.IndexOf'
137 | dotnet_diagnostic.CA2249.severity = none
138 |
139 | # SYSLIB1045: Convert to 'GeneratedRegexAttribute'.
140 | dotnet_diagnostic.SYSLIB1045.severity = none
141 |
142 | # SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time
143 | dotnet_diagnostic.SYSLIB1054.severity = none
144 |
145 | [*.cs]
146 | # CSharp code style settings
147 | csharp_style_var_elsewhere = false:none
148 | csharp_style_var_for_built_in_types = false:none
149 | csharp_style_var_when_type_is_apparent = false:none
150 | csharp_style_prefer_primary_constructors = false:none
151 |
152 | csharp_style_expression_bodied_accessors = true:suggestion
153 | csharp_style_expression_bodied_constructors = false:none
154 | csharp_style_expression_bodied_indexers = true:suggestion
155 | csharp_style_expression_bodied_methods = false:none
156 | csharp_style_expression_bodied_operators = false:none
157 | csharp_style_expression_bodied_properties = true:suggestion
158 |
159 | csharp_style_conditional_delegate_call = true:suggestion
160 | csharp_style_deconstructed_variable_declaration = false:none
161 | csharp_style_inlined_variable_declaration = true:suggestion
162 | csharp_style_pattern_local_over_anonymous_function = true:suggestion
163 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
164 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
165 | csharp_style_throw_expression = true:suggestion
166 | csharp_style_namespace_declarations = block_scoped:silent
167 | csharp_style_prefer_method_group_conversion = true:silent
168 | csharp_style_prefer_top_level_statements = true:silent
169 | csharp_style_expression_bodied_lambdas = true:silent
170 | csharp_style_expression_bodied_local_functions = false:silent
171 | csharp_style_prefer_null_check_over_type_check = true:suggestion
172 | csharp_style_prefer_local_over_anonymous_function = true:suggestion
173 | csharp_style_prefer_index_operator = true:suggestion
174 | csharp_style_prefer_range_operator = true:suggestion
175 | csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
176 | csharp_style_prefer_tuple_swap = true:suggestion
177 | csharp_style_prefer_utf8_string_literals = true:suggestion
178 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion
179 | csharp_style_unused_value_expression_statement_preference = discard_variable:silent
180 |
181 | csharp_prefer_braces = when_multiline:none
182 | csharp_prefer_simple_default_expression = true:suggestion
183 | csharp_prefer_simple_using_statement = true:suggestion
184 | csharp_preserve_single_line_blocks = true
185 | csharp_using_directive_placement = outside_namespace:silent
186 |
187 | # Indentation options
188 | csharp_indent_block_contents = true
189 | csharp_indent_braces = false
190 | csharp_indent_case_contents = true
191 | csharp_indent_labels = no_change
192 |
193 | # New line options
194 | csharp_new_line_before_catch = true
195 | csharp_new_line_before_else = true
196 | csharp_new_line_before_finally = true
197 | csharp_new_line_before_members_in_anonymous_types = true
198 | csharp_new_line_before_members_in_object_initializers = true
199 | csharp_new_line_before_open_brace = all
200 | csharp_new_line_between_query_expression_clauses = true
201 |
202 | # Spacing options
203 | csharp_space_after_cast = false
204 | csharp_space_after_colon_in_inheritance_clause = true
205 | csharp_space_after_comma = true
206 | csharp_space_after_dot = false
207 | csharp_space_after_keywords_in_control_flow_statements = false
208 | csharp_space_after_semicolon_in_for_statement = true
209 | csharp_space_around_binary_operators = before_and_after
210 | csharp_space_before_colon_in_inheritance_clause = true
211 | csharp_space_before_comma = false
212 | csharp_space_before_dot = false
213 | csharp_space_before_open_square_brackets = false
214 | csharp_space_before_semicolon_in_for_statement = false
215 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
216 | csharp_space_between_method_call_name_and_opening_parenthesis = false
217 | csharp_space_between_method_call_parameter_list_parentheses = false
218 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
219 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
220 | csharp_space_between_method_declaration_parameter_list_parentheses = false
221 |
--------------------------------------------------------------------------------
/Source/CommentsElement.cs:
--------------------------------------------------------------------------------
1 | //===============================================================================================================
2 | // System : Extended Doc Comments Completion Provider Package
3 | // File : CommentsElement.cs
4 | // Author : Eric Woodruff (Eric@EWoodruff.us)
5 | // Updated : 02/10/2023
6 | // Note : Copyright 2019-2023, Eric Woodruff, All rights reserved
7 | //
8 | // This file contains the class used to define an XML documentation comments element
9 | //
10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
11 | // distributed with the code and can be found at the project website:
12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright
13 | // notices must remain intact in all applications, documentation, and source files.
14 | //
15 | // Date Who Comments
16 | // ==============================================================================================================
17 | // 10/18/2019 EFW Created the code
18 | //===============================================================================================================
19 |
20 | // Ignore Spelling: cpp fs javascript vbnet html xml xsl xaml sql py pshell cref threadsafety href seealso todo
21 |
22 | using System;
23 | using System.Collections.Generic;
24 | using System.Collections.Immutable;
25 | using System.Linq;
26 |
27 | using Microsoft.CodeAnalysis.Completion;
28 |
29 | namespace EWSoftware.CompletionProviders
30 | {
31 | ///
32 | /// This is used to define an XML documentation comments element
33 | ///
34 | public class CommentsElement
35 | {
36 | #region Private data members
37 | //=====================================================================
38 |
39 | private static readonly CompletionItemRules defaultRules = CompletionItemRules.Create(
40 | ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Add, '!', '-', '[')),
41 | ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Add, '>', '\t')),
42 | EnterKeyRule.Never);
43 | private static readonly CharacterSetModificationRule withoutQuoteRule =
44 | CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, '"');
45 | private static readonly CharacterSetModificationRule withoutSpaceRule =
46 | CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, ' ');
47 |
48 | private readonly HashSet attributes;
49 | private readonly HashSet childOf;
50 |
51 | private string displayText;
52 |
53 | #endregion
54 |
55 | #region Properties
56 | //=====================================================================
57 |
58 | ///
59 | /// This static read-only property returns a dictionary containing the current set of custom element
60 | /// definitions.
61 | ///
62 | public static Dictionary CustomElements { get; } = CreateDefaultCommentElements();
63 |
64 | ///
65 | /// The element name
66 | ///
67 | public string Name { get; set; }
68 |
69 | ///
70 | /// Optional display text to show in the completion popup
71 | ///
72 | /// If not set, the is used. This allows alternate text to be shown in place
73 | /// or the element name or to allow multiple instances of a particular element with different before and
74 | /// after text for example.
75 | public string DisplayText
76 | {
77 | get => displayText ?? this.Name;
78 | set
79 | {
80 | if(String.IsNullOrWhiteSpace(value))
81 | displayText = null;
82 | else
83 | displayText = value.Trim();
84 | }
85 | }
86 |
87 | ///
88 | /// An optional description to show when the completion item is selected in the completion popup list
89 | ///
90 | /// If not set, no description will be shown
91 | public string Description { get; set; }
92 |
93 | ///
94 | /// Additional text to include after the element name and before the caret if the element is inserted
95 | ///
96 | /// This is typically a default attribute name, the equals sign, and the opening quote mark
97 | public string TextBeforeCaret { get; set; }
98 |
99 | ///
100 | /// Additional text to include after the caret if the element is inserted
101 | ///
102 | /// When is specified, this is typically a closing quote mark
103 | public string TextAfterCaret { get; set; }
104 |
105 | ///
106 | /// This indicates how the element is used
107 | ///
108 | /// If , this element cannot be nested within other elements.
109 | /// If or , it can. If
110 | /// is empty, it can appear within any element. If specific parent elements are
111 | /// specified, it can only appear within them.
112 | public ElementUsage ElementUsage { get; set; }
113 |
114 | ///
115 | /// This indicates whether or not the top-level element is single-use or can appear multiple times
116 | ///
117 | public bool IsSingleUse { get; set; }
118 |
119 | ///
120 | /// This is used to indicate whether or not the element is inserted as a self-closing element or if it
121 | /// is left open.
122 | ///
123 | public bool IsSelfClosing { get; set; }
124 |
125 | ///
126 | /// This returns a collection of attributes supported by the element, if any
127 | ///
128 | public IReadOnlyCollection Attributes => attributes;
129 |
130 | ///
131 | /// This returns a collection of parent element names of which this element can be a child
132 | ///
133 | /// If empty and not a top-level element, this element can appear in any other element. If not
134 | /// empty, it can only appear within the specified elements.
135 | public IReadOnlyCollection ChildOf => childOf;
136 |
137 | #endregion
138 |
139 | #region Constructor
140 | //=====================================================================
141 |
142 | ///
143 | /// Constructor
144 | ///
145 | public CommentsElement()
146 | {
147 | attributes = new HashSet();
148 | childOf = new HashSet();
149 | }
150 | #endregion
151 |
152 | #region Methods
153 | //=====================================================================
154 |
155 | ///
156 | /// Add supported attribute information to the element
157 | ///
158 | /// An enumerable list of attribute information to add
159 | /// A reference to the comment element instance
160 | public CommentsElement AddAttributes(IEnumerable elementNames)
161 | {
162 | attributes.UnionWith(elementNames);
163 | return this;
164 | }
165 |
166 | ///
167 | /// Add parent element information to the element
168 | ///
169 | /// An enumerable list of parent element names
170 | /// A reference to the comment element instance
171 | public CommentsElement AddChildOfElements(IEnumerable parentElements)
172 | {
173 | childOf.UnionWith(parentElements);
174 | return this;
175 | }
176 |
177 | ///
178 | /// Convert the element to a
179 | ///
180 | /// The element information as a
181 | public CompletionItem ToCompletionItem()
182 | {
183 | var rules = defaultRules;
184 |
185 | if(this.DisplayText.IndexOfAny(new[] { '"', ' ' }) != -1)
186 | {
187 | var commitRules = defaultRules.CommitCharacterRules;
188 |
189 | if(this.DisplayText.IndexOf('"') != -1)
190 | commitRules = commitRules.Add(withoutQuoteRule);
191 |
192 | if(this.DisplayText.IndexOf(' ') != -1)
193 | commitRules = commitRules.Add(withoutSpaceRule);
194 |
195 | rules = defaultRules.WithCommitCharacterRules(commitRules);
196 | }
197 |
198 | string beforeCaret = "<" + this.Name, afterCaret = this.TextAfterCaret;
199 |
200 | if(!String.IsNullOrWhiteSpace(this.TextBeforeCaret))
201 | beforeCaret += " " + this.TextBeforeCaret;
202 |
203 | if(this.IsSelfClosing)
204 | afterCaret += "/>";
205 |
206 | var properties = new Dictionary { { nameof(TextBeforeCaret), beforeCaret } };
207 |
208 | if(!String.IsNullOrWhiteSpace(afterCaret))
209 | properties.Add(nameof(TextAfterCaret), afterCaret);
210 |
211 | if(!String.IsNullOrWhiteSpace(this.Description))
212 | properties.Add(nameof(Description), this.Description);
213 |
214 | return CompletionItem.Create(this.DisplayText, null, null, ImmutableDictionary.CreateRange(properties),
215 | ImmutableArray.Create("Keyword"), rules);
216 | }
217 |
218 | ///
219 | /// Convert an attribute to a
220 | ///
221 | /// The attribute to use
222 | /// The attribute as a
223 | public static CompletionItem AttributeToCompletionItem(ElementAttribute attribute)
224 | {
225 | if(attribute == null)
226 | throw new ArgumentNullException(nameof(attribute));
227 |
228 | var properties = new Dictionary
229 | {
230 | { nameof(TextBeforeCaret), attribute.Name + "=\"" },
231 | { nameof(TextAfterCaret), "\"" }
232 | };
233 |
234 | if(!String.IsNullOrWhiteSpace(attribute.Description))
235 | properties.Add(nameof(Description), attribute.Description);
236 |
237 | return CompletionItem.Create(attribute.Name, null, null, ImmutableDictionary.CreateRange(properties),
238 | ImmutableArray.Create("Keyword"), defaultRules);
239 | }
240 |
241 | ///
242 | /// Convert an attribute value to a
243 | ///
244 | /// The attribute value to use
245 | /// The attribute value as a
246 | public static CompletionItem AttributeValueToCompletionItem(string value)
247 | {
248 | return CompletionItem.Create(value, null, null, ImmutableDictionary.Empty,
249 | ImmutableArray.Create("Keyword"), defaultRules);
250 | }
251 |
252 | ///
253 | /// Create the default comment element dictionary
254 | ///
255 | /// A dictionary containing the default comment element information
256 | private static Dictionary CreateDefaultCommentElements()
257 | {
258 | return new List
259 | {
260 | new CommentsElement
261 | {
262 | Name = "AttachedEventComments",
263 | ElementUsage = ElementUsage.TopLevel,
264 | Description = "Define the content that should appear on the auto-generated attached event " +
265 | "member topic for a given WPF routed event member."
266 | },
267 | new CommentsElement
268 | {
269 | Name = "AttachedPropertyComments",
270 | ElementUsage = ElementUsage.TopLevel,
271 | Description = "Define the content that should appear on the auto-generated attached " +
272 | "property member topic for a given WPF dependency property member."
273 | },
274 | new CommentsElement
275 | {
276 | Name = "code",
277 | ElementUsage = ElementUsage.Nested,
278 | TextBeforeCaret="language=\"",
279 | TextAfterCaret="\"",
280 | Description = "Format a multi-line section of text as source code.",
281 | }.AddAttributes(new[] {
282 | new ElementAttribute(new[] { "cs", "cpp", "c", "fs", "javascript", "vb", "vbnet",
283 | "html", "xml", "xsl", "xaml", "sql", "py", "pshell", "bat", "none" }) {
284 | Name = "language", Description = "Specify the code language." },
285 | new ElementAttribute { Name = "title", Description = "An optional title or a space to " +
286 | "suppress the title." },
287 | new ElementAttribute { Name = "source", Description = "Specify a source code file from " +
288 | "which this element's content will be imported." },
289 | new ElementAttribute { Name = "region", Description = "Limit the imported code to a " +
290 | "specific named region within it." },
291 | new ElementAttribute(new[] { "true", "false" }) {
292 | Name = "removeRegionMarkers", Description = "Indicate whether or not region markers " +
293 | "within the imported code file or region are removed." },
294 | new ElementAttribute { Name = "tabSize", Description = "Override the default tab size " +
295 | "setting for the language which is defined by the code colorizer." },
296 | new ElementAttribute(new[] { "true", "false" }) {
297 | Name = "numberLines", Description = "Override the default line numbering setting in " +
298 | "the code colorizer." },
299 | new ElementAttribute(new[] { "true", "false" }) {
300 | Name = "outlining", Description = "Override the default outlining setting in the " +
301 | "code colorizer." },
302 | new ElementAttribute(new[] { "true", "false" }) {
303 | Name = "keepSeeTags", Description = "Override the default setting in the code " +
304 | "colorizer that determines whether or not elements in the code are " +
305 | "rendered as clickable links or are rendered as literal text."}
306 | }),
307 | new CommentsElement
308 | {
309 | Name = "conceptualLink",
310 | ElementUsage = ElementUsage.Both,
311 | TextBeforeCaret = "target=\"",
312 | TextAfterCaret = "\"",
313 | IsSelfClosing = true,
314 | Description = "Create a link to a MAML topic within the See Also section of a topic or an " +
315 | "inline link to a MAML topic within one of the other XML comments elements."
316 | },
317 | new CommentsElement
318 | {
319 | Name = "event",
320 | ElementUsage = ElementUsage.TopLevel,
321 | TextBeforeCaret = "cref=\"",
322 | TextAfterCaret = "\"",
323 | Description = "List events that can be raised by a type's member."
324 | },
325 | new CommentsElement
326 | {
327 | Name = "list",
328 | ElementUsage = ElementUsage.Nested,
329 | TextBeforeCaret = "type=\"",
330 | TextAfterCaret = "\"",
331 | Description = "Specify content that should be displayed as a list or a table."
332 | }.AddAttributes(new[] {
333 | new ElementAttribute(new[] { "definition" }) {
334 | Name="type", Description = "The list type" },
335 | new ElementAttribute { Name = "start", Description = "The starting number for numbered lists." }
336 | }),
337 | new CommentsElement
338 | {
339 | Name = "note",
340 | ElementUsage = ElementUsage.Nested,
341 | TextBeforeCaret = "type=\"",
342 | TextAfterCaret = "\"",
343 | Description = "Create a note within a topic to draw attention to some important information."
344 | }.AddAttributes(new [] {
345 | new ElementAttribute(new[] { "note", "tip", "implement", "caller", "inherit", "caution",
346 | "warning", "important", "security", "cs", "cpp", "vb", "todo" }) {
347 | Name = "type", Description = "Specifies the note type." },
348 | new ElementAttribute { Name = "title", Description = "An optional title override" }
349 | }),
350 | new CommentsElement
351 | {
352 | Name = "overloads",
353 | ElementUsage = ElementUsage.TopLevel,
354 | Description = "Define the content that should appear on the auto-generated overloads topic " +
355 | "for a given set of member overloads."
356 | },
357 | new CommentsElement
358 | {
359 | Name = "preliminary",
360 | ElementUsage = ElementUsage.TopLevel,
361 | IsSelfClosing = true,
362 | Description = "Indicate that a particular type or member is preliminary and is subject to change."
363 | },
364 | new CommentsElement
365 | {
366 | Name = "revisionHistory",
367 | ElementUsage = ElementUsage.TopLevel,
368 | TextBeforeCaret = "visible=\"",
369 | TextAfterCaret = "true\"",
370 | Description = "Display revision history for a type or its members."
371 | }.AddAttributes(new[] {
372 | new ElementAttribute(new[] { "true", "false" }) {
373 | Name = "visible",
374 | Description = "Indicate whether or not the revision history is included in the help topic." },
375 | }),
376 | new CommentsElement
377 | {
378 | Name = "revision",
379 | ElementUsage = ElementUsage.Nested,
380 | TextBeforeCaret = "date=\"",
381 | TextAfterCaret = "\" version=\"\"",
382 | Description = "Describe a revision to the type or member."
383 | }.AddAttributes(new[] {
384 | new ElementAttribute{ Name = "date", Description = "The revision date." },
385 | new ElementAttribute{ Name = "version", Description = "The version in which the revision was made." },
386 | new ElementAttribute{ Name = "author", Description = "The name of the person that made the revision." },
387 | new ElementAttribute(new[] { "true", "false" }) {
388 | Name = "visible",
389 | Description = "Indicate whether or not the revision is included in the help topic." },
390 | }).AddChildOfElements(
391 | new[] { "revisionHistory" }),
392 | new CommentsElement
393 | {
394 | Name = "see",
395 | ElementUsage = ElementUsage.Nested,
396 | TextBeforeCaret = "cref=\"",
397 | TextAfterCaret = "\"",
398 | IsSelfClosing = true,
399 | Description = "Create an inline link to another API topic or an external website."
400 | }.AddAttributes(new[] {
401 | new ElementAttribute(new[] { "true", "false" }) {
402 | Name = "qualifyHint",
403 | Description = "Indicate whether or not the type or member name should be qualified." },
404 | new ElementAttribute(new[] { "true", "false" }) {
405 | Name = "autoUpgrade",
406 | Description = "Indicate whether or not the link should go to the method overloads topic." },
407 | new ElementAttribute { Name = "href", Description = "Specify a URL to which the link should go." },
408 | new ElementAttribute { Name = "alt", Description = "Specify alternate text for a URL link." },
409 | new ElementAttribute(new[] { "_blank", "_self", "_parent", "_top" }) {
410 | Name = "target", Description = "Specify where a URL link will be opened." },
411 | }),
412 | new CommentsElement
413 | {
414 | Name = "seealso",
415 | ElementUsage = ElementUsage.Nested,
416 | TextBeforeCaret = "cref=\"",
417 | TextAfterCaret = "\"",
418 | IsSelfClosing = true,
419 | Description = "Create an link to another API topic or an external website in the See Also " +
420 | "section of a help topic."
421 | }.AddAttributes(new[] {
422 | new ElementAttribute(new[] { "true", "false" }) {
423 | Name = "qualifyHint",
424 | Description = "Indicate whether or not the type or member name should be qualified." },
425 | new ElementAttribute(new[] { "true", "false" }) {
426 | Name = "autoUpgrade",
427 | Description = "Indicate whether or not the link should go to the method overloads topic." },
428 | new ElementAttribute { Name = "href", Description = "Specify a URL to which the link should go." },
429 | new ElementAttribute { Name = "alt", Description = "Specify alternate text for a URL link." },
430 | new ElementAttribute(new[] { "_blank", "_self", "_parent", "_top" }) {
431 | Name = "target", Description = "Specify where a URL link will be opened." },
432 | }),
433 | new CommentsElement
434 | {
435 | Name = "threadsafety",
436 | ElementUsage = ElementUsage.TopLevel,
437 | TextBeforeCaret = "static=\"",
438 | TextAfterCaret = "true\" instance=\"false\"",
439 | IsSelfClosing = true,
440 | Description = "Indicate whether or not a class or structure's static and instance members " +
441 | "are safe for use in multi-threaded scenarios."
442 | }.AddAttributes(new[] {
443 | new ElementAttribute(new[] { "true", "false" }) {
444 | Name = "static", Description = "The thread safety of static members." },
445 | new ElementAttribute(new[] { "true", "false" }) {
446 | Name = "instance", Description = "The thread safety of instance member." }
447 | }),
448 | new CommentsElement
449 | {
450 | Name = "token",
451 | ElementUsage = ElementUsage.Both,
452 | Description = "Insert a replaceable tag within a topic."
453 | }
454 | }.ToDictionary(k => k.DisplayText, v => v);
455 | }
456 | #endregion
457 | }
458 | }
459 |
--------------------------------------------------------------------------------
/Source/CSharpXmlDocCommentsCompletionProvider.cs:
--------------------------------------------------------------------------------
1 | //===============================================================================================================
2 | // System : Extended Doc Comments Completion Provider Package
3 | // File : CSharpXmlDocCommentsCompletionProvider.cs
4 | // Author : Eric Woodruff (Eric@EWoodruff.us)
5 | // Updated : 09/12/2025
6 | // Note : Copyright 2019-2025, Eric Woodruff, All rights reserved
7 | //
8 | // This file contains the extended documentation comments completion provider for C#
9 | //
10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
11 | // distributed with the code and can be found at the project website:
12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright
13 | // notices must remain intact in all applications, documentation, and source files.
14 | //
15 | // Date Who Comments
16 | // ==============================================================================================================
17 | // 10/09/2019 EFW Created the code
18 | //===============================================================================================================
19 |
20 | // Ignore Spelling: lexer attr cref
21 |
22 | using System;
23 | using System.Collections.Generic;
24 | using System.Collections.Immutable;
25 | using System.Linq;
26 | using System.Reflection;
27 | using System.Threading;
28 | using System.Threading.Tasks;
29 |
30 | using Microsoft.CodeAnalysis;
31 | using Microsoft.CodeAnalysis.Completion;
32 | using Microsoft.CodeAnalysis.CSharp;
33 | using Microsoft.CodeAnalysis.CSharp.Syntax;
34 | using Microsoft.CodeAnalysis.Options;
35 | using Microsoft.CodeAnalysis.Text;
36 |
37 | namespace EWSoftware.CompletionProviders
38 | {
39 | ///
40 | /// This completion provider augments the standard XML documentation comments elements with custom elements,
41 | /// attributes, and attribute values supported by the Sandcastle Help File Builder and other documentation
42 | /// tools.
43 | ///
44 | /// The core logic used to determine which completion items to return based on the current context
45 | /// is based largely on the Roslyn XML comments completion providers. This runs after the built in C#
46 | /// comments provider so that our extensions override the ones provided by it such as code. This
47 | /// allows our before/after text options to work properly. The built in provider is internal so we need to
48 | /// specify it's name as a literal string in the attribute.
49 | [ExportCompletionProvider(nameof(CSharpXmlDocCommentsCompletionProvider), LanguageNames.CSharp)]
50 | [ExtensionOrder(After = "XmlDocCommentCompletionProvider")]
51 | internal sealed class CSharpXmlDocCommentsCompletionProvider : CompletionProvider
52 | {
53 | #region CompletionProvider abstract method implementation
54 | //=====================================================================
55 |
56 | ///
57 | public override async Task GetChangeAsync(Document document, CompletionItem item,
58 | char? commitChar, CancellationToken cancellationToken)
59 | {
60 | var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
61 |
62 | if(!item.Properties.TryGetValue(nameof(CommentsElement.TextBeforeCaret), out string replacementText))
63 | replacementText = item.DisplayText;
64 |
65 | var itemSpan = item.Span;
66 | var replacementSpan = TextSpan.FromBounds(text[itemSpan.Start - 1] == '<' && replacementText.Length > 0 &&
67 | replacementText[0] == '<' ? itemSpan.Start - 1 : itemSpan.Start, itemSpan.End);
68 |
69 | int newPosition = replacementSpan.Start + replacementText.Length;
70 |
71 | // Include the commit character?
72 | if(commitChar != null && !Char.IsWhiteSpace(commitChar.Value) &&
73 | commitChar.Value != replacementText[replacementText.Length - 1])
74 | {
75 | replacementText += commitChar.Value;
76 | newPosition++;
77 | }
78 |
79 | if(item.Properties.TryGetValue(nameof(CommentsElement.TextAfterCaret), out string afterCaretText))
80 | replacementText += afterCaretText;
81 |
82 | return CompletionChange.Create(new TextChange(replacementSpan, replacementText), newPosition, true);
83 | }
84 |
85 | ///
86 | public override Task GetDescriptionAsync(
87 | Document document, CompletionItem item, CancellationToken cancellationToken)
88 | {
89 | if(!item.Properties.TryGetValue(nameof(CommentsElement.Description), out string description))
90 | return Task.FromResult(CompletionDescription.Empty);
91 |
92 | return Task.FromResult(CompletionDescription.Create(ImmutableArray.Create(new TaggedText[] {
93 | new TaggedText(TextTags.Text, description) })));
94 | }
95 |
96 | ///
97 | public override async Task ProvideCompletionsAsync(CompletionContext context)
98 | {
99 | var items = await GetItemsAsync(context.Document, context.Position, context.Trigger,
100 | context.CancellationToken).ConfigureAwait(false);
101 |
102 | if(items != null)
103 | context.AddItems(items);
104 | }
105 |
106 | ///
107 | public override bool ShouldTriggerCompletion(SourceText text, int position, CompletionTrigger trigger,
108 | OptionSet options)
109 | {
110 | if(trigger.Kind != CompletionTriggerKind.Insertion || position < 1)
111 | return false;
112 |
113 | // Trigger it on an open bracket, quote, or at the start of a word
114 | char ch = text[position - 1];
115 |
116 | if(ch == '<' || ch == '"' || (ch == ' ' && (position == text.Length ||
117 | !SyntaxFacts.IsIdentifierStartCharacter(text[position]))))
118 | {
119 | return true;
120 | }
121 |
122 | position--;
123 |
124 | // We only want to trigger if we're the first character in an identifier. If there's a character
125 | // before or after us, then we don't want to trigger.
126 | if(!SyntaxFacts.IsIdentifierStartCharacter(text[position]) ||
127 | (position > 0 && SyntaxFacts.IsIdentifierPartCharacter(text[position - 1])) ||
128 | (position < text.Length - 1 && SyntaxFacts.IsIdentifierPartCharacter(text[position + 1])))
129 | {
130 | return false;
131 | }
132 |
133 | // Try to honor the "Show completion list after a character is typed" option
134 | return TriggerOnTypingLetters(options);
135 | }
136 | #endregion
137 |
138 | #region Helper methods
139 | //=====================================================================
140 |
141 | ///
142 | /// This is used to get the TriggerOnTypingLetters option from the option set
143 | ///
144 | /// The option set from which to get the option
145 | /// The per-language options are passed to but Roslyn
146 | /// implements a majority of that stuff internally so it's inaccessible to us publicly. As such, we
147 | /// resort to Reflection to get at it. If there's a better way to do this, I can't find it.
148 | private static bool TriggerOnTypingLetters(OptionSet options)
149 | {
150 | try
151 | {
152 | FieldInfo fi = options.GetType().GetField("_values", BindingFlags.NonPublic |
153 | BindingFlags.Instance);
154 |
155 | if(fi != null)
156 | {
157 | if(fi.GetValue(options) is ImmutableDictionary optionValues && optionValues.Count != 0)
158 | {
159 | var key = optionValues.Keys.FirstOrDefault(k => k.Language == LanguageNames.CSharp &&
160 | k.Option.Name == nameof(TriggerOnTypingLetters) && k.Option.Type == typeof(bool));
161 |
162 | if(key.Language != null)
163 | return (bool)optionValues[key];
164 | }
165 | }
166 | }
167 | catch(Exception ex)
168 | {
169 | // Ignore exceptions, we'll just use the default
170 | System.Diagnostics.Debug.WriteLine(ex);
171 |
172 | if(System.Diagnostics.Debugger.IsAttached)
173 | System.Diagnostics.Debugger.Break();
174 | }
175 |
176 | // If we couldn't get it, use the default value which assumes it is enabled
177 | return true;
178 | }
179 |
180 | ///
181 | /// This is used to determine which completion items should appear, if any
182 | ///
183 | /// The document for which to provide completions
184 | /// The position of the caret within the document
185 | /// The action that triggered the completion to start
186 | /// A cancellation token used to cancel the operation
187 | /// An enumerable set of completion items if any are determined to be relevant
188 | private static async Task> GetItemsAsync(Document document, int position,
189 | CompletionTrigger trigger, CancellationToken cancellationToken)
190 | {
191 | try
192 | {
193 | var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
194 | var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
195 | var parentTrivia = token.Parent?.FirstAncestorOrSelf();
196 |
197 | if(parentTrivia == null || parentTrivia.ParentTrivia.Token.IsKind(SyntaxKind.None))
198 | return null;
199 |
200 | // Offer attribute names based on the element
201 | if(IsAttributeNameContext(token, position, out string elementName, out var existingAttributes))
202 | {
203 | if(CommentsElement.CustomElements.TryGetValue(elementName, out CommentsElement ce) &&
204 | ce.Attributes.Count != 0)
205 | {
206 | return ce.Attributes.Where(attr => !existingAttributes.Contains(attr.Name)).Select(
207 | attr => CommentsElement.AttributeToCompletionItem(attr));
208 | }
209 |
210 | return null;
211 | }
212 |
213 | // Only attribute names should be triggered by a space. Nothing past this point should be.
214 | if(trigger.Kind == CompletionTriggerKind.Insertion && trigger.Character == ' ')
215 | return null;
216 |
217 | // Offer attribute values based on the element and attribute names
218 | if(IsAttributeValueContext(token, out elementName, out string attributeName))
219 | {
220 | if(CommentsElement.CustomElements.TryGetValue(elementName, out CommentsElement ce))
221 | {
222 | var attr = ce.Attributes.FirstOrDefault(a => a.Name == attributeName);
223 |
224 | if(attr != null)
225 | return attr.Values.Select(v => CommentsElement.AttributeValueToCompletionItem(v));
226 | }
227 |
228 | return null;
229 | }
230 |
231 | // Everything below this point should only be offered if triggered by an opening bracket
232 | if(trigger.Kind == CompletionTriggerKind.Insertion && trigger.Character != '<')
233 | return null;
234 |
235 | var elementNames = new HashSet();
236 |
237 | if(token.Parent.IsKind(SyntaxKind.XmlEmptyElement) || token.Parent.IsKind(SyntaxKind.XmlText) ||
238 | (token.Parent.IsKind(SyntaxKind.XmlElementEndTag) && token.IsKind(SyntaxKind.GreaterThanToken)) ||
239 | (token.Parent.IsKind(SyntaxKind.XmlName) && token.Parent.Parent.IsKind(SyntaxKind.XmlEmptyElement)))
240 | {
241 | // Add child elements with no defined parentage
242 | if(token.Parent.Parent.IsKind(SyntaxKind.XmlElement) ||
243 | token.Parent.Parent.Parent.IsKind(SyntaxKind.XmlElement))
244 | {
245 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(
246 | el => el.ElementUsage != ElementUsage.TopLevel && !el.ChildOf.Any()).Select(
247 | el => el.DisplayText));
248 | }
249 |
250 | // Add child elements based on the parent element's name
251 | if(token.Parent.Parent is XmlElementSyntax xmlElement)
252 | {
253 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(el => el.ChildOf.Contains(
254 | xmlElement.StartTag.Name.LocalName.ValueText)).Select(el => el.DisplayText));
255 | }
256 |
257 | if(token.Parent.Parent.IsKind(SyntaxKind.XmlEmptyElement) &&
258 | token.Parent.Parent.Parent is XmlElementSyntax nestedXmlElement)
259 | {
260 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(el => el.ChildOf.Contains(
261 | nestedXmlElement.StartTag.Name.LocalName.ValueText)).Select(el => el.DisplayText));
262 | }
263 |
264 | // Add top-level elements
265 | if(token.Parent.Parent is DocumentationCommentTriviaSyntax ||
266 | (token.Parent.Parent.IsKind(SyntaxKind.XmlEmptyElement) &&
267 | token.Parent.Parent.Parent is DocumentationCommentTriviaSyntax))
268 | {
269 | var existingTopLevelElements = new HashSet(parentTrivia.Content.Select(
270 | n => GetElementNameAndAttributes(n).Name).Where(el => el != null));
271 |
272 | // Top-level single-use elements
273 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(
274 | el => el.ElementUsage == ElementUsage.TopLevel && el.IsSingleUse &&
275 | !existingTopLevelElements.Contains(el.Name)).Select(el => el.DisplayText));
276 |
277 | // Top-level repeatable elements
278 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(
279 | el => el.ElementUsage == ElementUsage.TopLevel && !el.IsSingleUse).Select(el => el.DisplayText));
280 | }
281 | }
282 |
283 | // This case only appears to happen if using the shortcut key to invoke completion and the caret
284 | // is at the end of a start tag: |. In such cases, add child elements with no defined
285 | // parentage and child elements based on the start tag's name.
286 | if(token.Parent is XmlElementStartTagSyntax startTag && token == startTag.GreaterThanToken)
287 | {
288 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(
289 | el => el.ElementUsage != ElementUsage.TopLevel && !el.ChildOf.Any()).Select(
290 | el => el.DisplayText));
291 |
292 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(el => el.ChildOf.Contains(
293 | startTag.Name.LocalName.ValueText)).Select(el => el.DisplayText));
294 | }
295 |
296 | // Add use anywhere elements
297 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(
298 | el => el.ElementUsage == ElementUsage.Both).Select(el => el.DisplayText));
299 |
300 | if(elementNames.Any())
301 | return elementNames.Select(el => CommentsElement.CustomElements[el].ToCompletionItem());
302 | }
303 | catch(Exception ex)
304 | {
305 | // Ignore any exceptions. We just won't offer any completions.
306 | if(!(ex is OperationCanceledException))
307 | System.Diagnostics.Debug.WriteLine(ex);
308 |
309 | if(System.Diagnostics.Debugger.IsAttached)
310 | System.Diagnostics.Debugger.Break();
311 | }
312 |
313 | return null;
314 | }
315 |
316 | ///
317 | /// Get the element name and attributes from the current syntax node
318 | ///
319 | /// The syntax node to use
320 | /// A tuple containing the element name and the attributes
321 | private static (string Name, IEnumerable Attributes) GetElementNameAndAttributes(
322 | SyntaxNode node)
323 | {
324 | switch(node)
325 | {
326 | // Self-closing or incomplete element: or
331 | case XmlElementSyntax nonEmptyElement:
332 | return GetElementNameAndAttributes(nonEmptyElement.StartTag);
333 |
334 | // Start tag:
335 | case XmlElementStartTagSyntax startTag:
336 | return (startTag.Name.LocalName.ValueText, startTag.Attributes);
337 |
338 | default:
339 | return (null, null);
340 | }
341 | }
342 |
343 | ///
344 | /// This is used to determine whether or not the current caret location is in an attribute name context
345 | ///
346 | /// The token to check.
347 | /// The position of the caret.
348 | /// On return, this will contain the element name if it is an attribute name
349 | /// context, null if not.
350 | /// On return, this will contain an enumerable list of the current
351 | /// attribute names for the element if it is an attribute name context, null if not.
352 | /// True if it is within the attribute name context, false if not.
353 | private static bool IsAttributeNameContext(SyntaxToken token, int position, out string elementName,
354 | out IEnumerable attributeNames)
355 | {
356 | elementName = null;
357 |
358 | // Unlike VB, the C# lexer has a preference for leading trivia. In cases such as " attributes = null;
374 |
375 | if(token.IsKind(SyntaxKind.IdentifierToken) && token.Parent.IsKind(SyntaxKind.XmlName))
376 | {
377 | // "(attributes.Select(attr => attr.Name.LocalName.ValueText));
398 | else
399 | attributeNames = null;
400 |
401 | return elementName != null;
402 | }
403 |
404 | ///
405 | /// This is used to determine whether or not the current caret location is in an attribute value context
406 | ///
407 | /// The token to check
408 | /// On return, this will contain the element name if it is an attribute value
409 | /// context, null if not.
410 | /// On return, this will contain the attribute name if it is an attribute
411 | /// value context, null if not.
412 | /// True if it is within the attribute value context, false if not.
413 | private static bool IsAttributeValueContext(SyntaxToken token, out string elementName, out string attributeName)
414 | {
415 | XmlAttributeSyntax attributeSyntax = null;
416 |
417 | if(token.IsKind(SyntaxKind.XmlTextLiteralToken) && token.Parent.IsKind(SyntaxKind.XmlTextAttribute))
418 | {
419 | // General attribute: attr="value|
420 | attributeSyntax = (XmlTextAttributeSyntax)token.Parent;
421 | }
422 | else
423 | {
424 | if(token.Parent.IsKind(SyntaxKind.XmlNameAttribute) || token.Parent.IsKind(SyntaxKind.XmlTextAttribute))
425 | {
426 | // Return the parent attribute if there is no value yet: attr="|
427 | attributeSyntax = (XmlAttributeSyntax)token.Parent;
428 |
429 | if(token != attributeSyntax.StartQuoteToken)
430 | attributeSyntax = null;
431 | }
432 | }
433 |
434 | if(attributeSyntax != null)
435 | {
436 | attributeName = attributeSyntax.Name.LocalName.ValueText;
437 |
438 | var emptyElement = attributeSyntax.GetAncestor();
439 |
440 | if(emptyElement != null)
441 | {
442 | // Self-closing or incomplete element: or ();
448 |
449 | if(startTag != null)
450 | {
451 | // Start tag:
452 | elementName = startTag.Name.LocalName.Text;
453 | return true;
454 | }
455 | }
456 |
457 | attributeName = elementName = null;
458 | return false;
459 | }
460 | #endregion
461 | }
462 | }
463 |
--------------------------------------------------------------------------------
/Source/License.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
2 | {\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
3 | {\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
4 | {\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
5 | {\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
6 | {\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f44\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
7 | {\f46\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f47\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f48\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f49\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
8 | {\f50\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f51\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f53\fbidi \fswiss\fcharset238\fprq2 Arial CE;}{\f54\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;}
9 | {\f56\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f57\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f58\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f59\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}
10 | {\f60\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f61\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f383\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f384\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}
11 | {\f386\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f387\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f390\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f391\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}
12 | {\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
13 | {\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
14 | {\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
15 | {\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
16 | {\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
17 | {\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}
18 | {\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}
19 | {\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}
20 | {\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
21 | {\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
22 | {\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
23 | {\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
24 | {\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
25 | {\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
26 | {\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
27 | {\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
28 | {\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
29 | {\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
30 | {\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
31 | {\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
32 | {\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
33 | {\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
34 | \red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap
35 | \ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1
36 | \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
37 | \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
38 | \widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused
39 | Normal Table;}}{\*\rsidtbl \rsid10425903\rsid13042251\rsid13172878}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator Eric Woodruff}
40 | {\creatim\yr2019\mo4\dy14\hr13\min31}{\revtim\yr2019\mo10\dy27\hr13\min10}{\version3}{\edmins1}{\nofpages1}{\nofwords390}{\nofchars2226}{\nofcharsws2611}{\vern113}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}
41 | \paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
42 | \widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701
43 | \dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot13042251 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2
44 | \pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6
45 | \pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang
46 | {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
47 | \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\ul\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 Microsoft Public License (Ms-PL)}{
48 | \rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878
49 | \par \hich\af1\dbch\af31505\loch\f1 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
50 | \par }{\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 1. Definitions}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878
51 | \par \hich\af1\dbch\af31505\loch\f1 The terms "reproduce," "reproduction," "derivative works," and "distribution"\hich\af1\dbch\af31505\loch\f1 have the same meaning here as under U.S. copyright law.
52 | \par \hich\af1\dbch\af31505\loch\f1 A "contribution" is the original software, or any additions or changes to the software.
53 | \par \hich\af1\dbch\af31505\loch\f1 A "contributor" is any person that distributes its contribution under this license.
54 | \par \hich\af1\dbch\af31505\loch\f1 "Licensed patents" are a co\hich\af1\dbch\af31505\loch\f1 ntributor's patent claims that read directly on its contribution.
55 | \par }{\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 2. Grant of Rights}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878
56 | \par \hich\af1\dbch\af31505\loch\f1 (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worl\hich\af1\dbch\af31505\loch\f1
57 | dwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
58 | \par \hich\af1\dbch\af31505\loch\f1 (B) Patent Grant- Subject to the terms of this license, including th\hich\af1\dbch\af31505\loch\f1
59 | e license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution
60 | \hich\af1\dbch\af31505\loch\f1 i\hich\af1\dbch\af31505\loch\f1 n the software or derivative works of the contribution in the software.
61 | \par }{\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 3. Conditions and Limitations}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878
62 | \par \hich\af1\dbch\af31505\loch\f1 (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
63 | \par \hich\af1\dbch\af31505\loch\f1 (B) If you bring a patent claim again\hich\af1\dbch\af31505\loch\f1 st any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
64 |
65 | \par \hich\af1\dbch\af31505\loch\f1 (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark,\hich\af1\dbch\af31505\loch\f1 and attribution notices that are present in the software.
66 | \par \hich\af1\dbch\af31505\loch\f1 (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute a
67 | \hich\af1\dbch\af31505\loch\f1 ny portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
68 | \par \hich\af1\dbch\af31505\loch\f1 (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or \hich\af1\dbch\af31505\loch\f1
69 | conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose
70 | \hich\af1\dbch\af31505\loch\f1 \hich\af1\dbch\af31505\loch\f1 and non-infringement.
71 | \par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid10425903
72 | \par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
73 | 9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
74 | 5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
75 | b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
76 | 0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
77 | a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
78 | c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
79 | 0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
80 | a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
81 | 6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
82 | 4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
83 | 4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100aa5225dfc60600008b1a0000160000007468656d652f7468656d652f
84 | 7468656d65312e786d6cec595d8bdb46147d2ff43f08bd3bfe92fcb1c41b6cd9ceb6d94d42eca4e4716c8fadc98e344633de8d0981923c160aa569e943037deb
85 | 43691b48a02fe9afd936a54d217fa17746b63c638fbb9b2585a5640d8b343af7ce997bafce1d4997afdc8fa87384134e58dc708b970aae83e3211b9178d2706f
86 | f7bbb99aeb7081e211a22cc60d778eb97b65f7c30f2ea31d11e2083b601ff31dd4704321a63bf93c1fc230e297d814c7706dcc920809384d26f951828ec16f44
87 | f3a542a1928f10895d274611b8bd311e932176fad2a5bbbb74dea1701a0b2e078634e949d7d8b050d8d1615122f89c0734718e106db830cf881df7f17de13a14
88 | 7101171a6e41fdb9f9ddcb79b4b330a2628bad66d7557f0bbb85c1e8b0a4e64c26836c52cff3bd4a33f3af00546ce23ad54ea553c9fc29001a0e61a52917dda7
89 | dfaab7dafe02ab81d2438bef76b55d2e1a78cd7f798373d3973f03af40a97f6f03dfed06104503af4029dedfc07b5eb51478065e81527c65035f2d34db5ed5c0
90 | 2b5048497cb8812ef89572b05c6d061933ba6785d77daf5b2d2d9caf50500d5975c929c62c16db6a2d42f758d2058004522448ec88f9148fd110aa3840940c12
91 | e2ec93490885374531e3305c2815ba8532fc973f4f1da988a01d8c346bc90b98f08d21c9c7e1c3844c45c3fd18bcba1ae4cdcb1fdfbc7cee9c3c7a71f2e89793
92 | c78f4f1efd9c3a32acf6503cd1ad5e7fffc5df4f3f75fe7afeddeb275fd9f15cc7fffed367bffdfaa51d082b5d85e0d5d7cffe78f1ecd5379ffff9c3130bbc99
93 | a0810eef930873e73a3e766eb10816a6426032c783e4ed2cfa2122ba45339e701423398bc57f478406fafa1c5164c1b5b019c13b09488c0d787576cf20dc0b93
94 | 9920168fd7c2c8001e30465b2cb146e19a9c4b0b737f164fec9327331d770ba123dbdc018a8dfc766653d05662731984d8a07993a258a0098eb170e4357688b1
95 | 6575770931e27a408609e36c2c9cbbc46921620d499f0c8c6a5a19ed9108f232b711847c1bb139b8e3b418b5adba8d8f4c24dc15885ac8f73135c27815cd048a
96 | 6c2efb28a27ac0f791086d247bf364a8e33a5c40a6279832a733c29cdb6c6e24b05e2de9d7405eec693fa0f3c84426821cda7cee23c674649b1d06218aa6366c
97 | 8fc4a18efd881f428922e7261336f80133ef10790e7940f1d674df21d848f7e96a701b9455a7b42a107965965872791533a37e7b733a4658490d08bfa1e71189
98 | 4f15f73559f7ff5b5907217df5ed53cbaa2eaaa0371362bda3f6d6647c1b6e5dbc03968cc8c5d7ee369ac53731dc2e9b0decbd74bf976ef77f2fdddbeee7772f
99 | d82b8d06f9965bc574abae36eed1d67dfb9850da13738af7b9daba73e84ca32e0c4a3bf5cc8ab3e7b8690887f24e86090cdc2441cac64998f88488b017a229ec
100 | ef8bae7432e10bd713ee4c19876dbf1ab6fa96783a8b0ed8287d5c2d16e5a3692a1e1c89d578c1cfc6e15143a4e84a75f50896b9576c27ea51794940dabe0d09
101 | 6d329344d942a2ba1c9441520fe610340b09b5b277c2a26e615193ee97a9da6001d4b2acc0d6c9810d57c3f53d30012378a242148f649ed2542fb3ab92f92e33
102 | bd2d984605c03e625901ab4cd725d7adcb93ab4b4bed0c99364868e566925091513d8c87688417d52947cf42e36d735d5fa5d4a02743a1e683d25ad1a8d6fe8d
103 | c579730d76ebda40635d2968ec1c37dc4ad9879219a269c31dc3633f1c4653a81d2eb7bc884ee0ddd95024e90d7f1e6599265cb4110fd3802bd149d520220227
104 | 0e2551c395cbcfd24063a5218a5bb104827061c9d541562e1a3948ba99643c1ee3a1d0d3ae8dc848a7a7a0f0a95658af2af3f383a5259b41ba7be1e8d819d059
105 | 720b4189f9d5a20ce0887078fb534ca33922f03a3313b255fdad35a685eceaef13550da5e3884e43b4e828ba98a77025e5191d7596c5403b5bac1902aa8564d1
106 | 080713d960f5a01add34eb1a2987ad5df7742319394d34573dd35015d935ed2a66ccb06c036bb13c5f93d7582d430c9aa677f854bad725b7bed4bab57d42d625
107 | 20e059fc2c5df70c0d41a3b69acca026196fcab0d4ecc5a8d93b960b3c85da599a84a6fa95a5dbb5b8653dc23a1d0c9eabf383dd7ad5c2d078b9af549156df3d
108 | f44f136c700fc4a30d2f81675470954af8f09020d810f5d49e24950db845ee8bc5ad0147ce2c210df741c16f7a41c90f72859adfc97965af90abf9cd72aee9fb
109 | e562c72f16daadd243682c228c8a7efacda50bafa2e87cf1e5458d6f7c7d89966fdb2e0d599467eaeb4a5e11575f5f8aa5ed5f5f1c02a2f3a052ead6cbf55625
110 | 572f37bb39afddaae5ea41a5956b57826abbdb0efc5abdfbd0758e14d86b9603afd2a9e52ac520c8799582a45fabe7aa5ea9d4f4aacd5ac76b3e5c6c6360e5a9
111 | 7c2c6201e155bc76ff010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f
112 | 7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be
113 | 9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980
114 | ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5b
115 | babac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f6e74656e
116 | 745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f
117 | 2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000190200007468656d652f7468656d652f74
118 | 68656d654d616e616765722e786d6c504b01022d0014000600080000002100aa5225dfc60600008b1a00001600000000000000000000000000d6020000746865
119 | 6d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000000000000000000000d00900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000cb0a00000000}
120 | {\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
121 | 617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
122 | 6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
123 | 656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
124 | {\*\latentstyles\lsdstimax377\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
125 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
126 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
127 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
128 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
129 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
130 | \lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
131 | \lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
132 | \lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
133 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
134 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
135 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
136 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
137 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
138 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
139 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
140 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
141 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
142 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
143 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
144 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
145 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
146 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
147 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
148 | \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
149 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
150 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
151 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
152 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
153 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
154 | \lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
155 | \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
156 | \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
157 | \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
158 | \lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
159 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
160 | \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;
161 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
162 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;
163 | \lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;
164 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;
165 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
166 | \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;
167 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
168 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
169 | \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5;
170 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
171 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
172 | \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
173 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
174 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
175 | \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
176 | \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
177 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
178 | \lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
179 | \lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
180 | \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
181 | \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
182 | \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
183 | \lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
184 | \lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
185 | \lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
186 | \lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
187 | \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
188 | \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
189 | \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
190 | \lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
191 | \lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
192 | \lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
193 | \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
194 | \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
195 | \lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
196 | \lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
197 | \lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
198 | \lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
199 | \lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
200 | \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
201 | \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
202 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;
203 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link Error;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
204 | d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
205 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
206 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
207 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
208 | fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
209 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
210 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
211 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
212 | ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000e0f5
213 | e5a5028dd501feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
214 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
215 | 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
216 | 0000000000000000000000000000000000000000000000000105000000000000}}
--------------------------------------------------------------------------------