[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: If you believe something is not working well\ntitle: \"[BUG] Brief description\"\nlabels: need to test\nassignees: KoenZomers\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Versions (please complete the following information):**\n- KeePass [e.g. 2.45]:\n- KeePass OneDriveSync Plugin [e.g. 2.1.1.2]:\n\n**Authentication method**\n- [ ] Microsoft Graph (any browser)\n- [ ] Microsoft Graph (built in browser)\n- [ ] OneDrive\n- [ ] OneDrive for Business\n- [ ] SharePoint 2013/2016/2019\n\n**KeePass database synced with**\n- [ ] OneDrive for Business\n- [ ] OneDrive Personal\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Author\n    url: koen@zomers.eu\n    about: If you want to share feedback which you rather don't want to be public, share it via e-mail\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for the plugin\ntitle: \"[FEATURE REQUEST] Brief description\"\nlabels: need to test\nassignees: KoenZomers\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "content": "---\nname: Question\nabout: If you have a question regarding this project\ntitle: \"[QUESTION] Brief description\"\nlabels: need to test\nassignees: KoenZomers\n\n---\n\n**Describe your question**\nA clear and concise description of what your question is about.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your question.\n\n**Versions (please complete the following information):**\n- KeePass [e.g. 2.45]:\n- KeePass OneDriveSync Plugin [e.g. 2.1.1.2]:\n\n**Authentication method**\n- [ ] Microsoft Graph (any browser)\n- [ ] Microsoft Graph (built in browser)\n- [ ] OneDrive\n- [ ] OneDrive for Business\n- [ ] SharePoint 2013/2016/2019\n\n**KeePass database synced with**\n- [ ] OneDrive for Business\n- [ ] OneDrive Personal\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md",
    "content": "## Type ##\n- [ ] Bug Fix\n- [ ] New Feature\n- [ ] Sample\n\n## Related Issues? ##\nFixes #X, partially fixes #Y, mentioned in #Z, etc.\n\n## What is in this Pull Request ? ##\nPlease describe the changes you are proposing through this PR\n"
  },
  {
    "path": ".github/auto_assign.yml",
    "content": "# Set to true to add reviewers to pull requests\naddReviewers: true\n\n# Set to true to add assignees to pull requests\naddAssignees: false\n\n# A list of reviewers to be added to pull requests (GitHub user name)\nreviewers:\n  - koenzomers\n\n# A number of reviewers added to the pull request\n# Set 0 to add all the reviewers (default: 0)\nnumberOfReviewers: 0\n\n# A list of assignees, overrides reviewers if set\n# assignees:\n#   - assigneeA\n\n# A number of assignees to add to the pull request\n# Set to 0 to add all of the assignees.\n# Uses numberOfReviewers if unset.\n# numberOfAssignees: 2\n\n# A list of keywords to be skipped the process that add reviewers if pull requests include it\n# skipKeywords:\n#   - wip\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\nx64/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Roslyn cache directories\n*.ide/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n#NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding addin-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n## TODO: Comment the next line if you want to checkin your\n## web deploy settings but do note that will include unencrypted\n## passwords\n#*.pubxml\n\n# NuGet Packages Directory\npackages/*\n## TODO: If the tool you use requires repositories.config\n## uncomment the next line\n#!packages/repositories.config\n\n# Enable \"build/\" folder in the NuGet Packages folder since\n# NuGet packages use it for MSBuild targets.\n# This line needs to be after the ignore of the build folder\n# (and the packages folder if the line above has been uncommented)\n!packages/build/\n\n# Windows Azure Build Output\ncsx/\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\nKoenZomers.KeePass.OneDriveSync/Packages/\n\n# Others\nsql/\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# LightSwitch generated files\nGeneratedArtifacts/\n_Pvt_Extensions/\nModelManifest.xml\n/.vs/config\n/.vs/KoenZomers.KeePass.OneDriveSync/v15/Server/sqlite3\n/.vs/KoenZomers.KeePass.OneDriveSync/v15/sqlite3/db.lock\n/.vs/KoenZomers.KeePass.OneDriveSync/v15/sqlite3/storage.ide-wal\n/.vs/KoenZomers.KeePass.OneDriveSync/v15/sqlite3/storage.ide-shm\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Configuration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.Serialization;\nusing System.Windows.Forms;\nusing KoenZomersKeePassOneDriveSync;\nusing Newtonsoft.Json;\n\nnamespace KoenZomers.KeePass.OneDriveSync\n{\n    /// <summary>\n    /// Plugin configuration class. Contains functions to serialize/deserialize to/from JSON.\n    /// </summary>\n    [DataContract]\n    public class Configuration : ICloneable\n    {\n        #region Constants\n\n        /// <summary>\n        /// Name under which to store these settings in the KeePass configuration store\n        /// </summary>\n        private const string ConfigurationKey = \"KeeOneDrive\";\n\n        #endregion\n\n        #region Non serializable Properties\n\n        /// <summary>\n        /// Dictionary with configuration settings for all password databases. Key is the local database path, value is the configuration belonging to it.\n        /// </summary>\n        private static IDictionary<string, Configuration> PasswordDatabases = new Dictionary<string, Configuration>();\n\n        /// <summary>\n        /// Boolean indicating if the syncing of this database is allowed\n        /// </summary>\n        public bool SyncingEnabled = true;\n\n        /// <summary>\n        /// The KeePass database to which these settings belong\n        /// </summary>\n        public KeePassLib.PwDatabase KeePassDatabase { get; set; }\n\n        /// <summary>\n        /// Boolean indicating if this database is currently synchronizing\n        /// </summary>\n        public bool IsCurrentlySyncing { get; set; }\n\n        #endregion\n\n        #region Serializable Properties\n\n        /// <summary>\n        /// Gets or sets refresh token that can be used to get an Access Token for OneDrive access. Will be set to ClientId;ClientSecret in the case of a SharePoint configuration.\n        /// </summary>\n        [DataMember]\n        public string RefreshToken { get; set; }\n\n        /// <summary>\n        /// Gets or sets the location where the refresh token will be stored\n        /// </summary>\n        [DataMember]\n        public Enums.OneDriveRefreshTokenStorage? RefreshTokenStorage { get; set; } \n\n        /// <summary>\n        /// Gets or sets the name of the OneDrive the KeePass database is synchronized with. Will be set to the SharePoint site title in the scenario of a SharePoint configuration.\n        /// </summary>\n        [DataMember]\n        public string OneDriveName { get; set; }\n\n        /// <summary>\n        /// Gets or sets database file path on OneDrive relative to the user. Will be set to the site URL in the case of a SharePoint configuration.\n        /// </summary>\n        [DataMember]\n        public string RemoteDatabasePath { get; set; }\n\n        /// <summary>\n        /// Gets or sets the unique identifier of the folder on OneDrive in which the file is stored. Will be set to the Document Library server relative URL in the case of a SharePoint configuration.\n        /// </summary>\n        [DataMember]\n        public string RemoteFolderId { get; set; }\n\n        /// <summary>\n        /// Gets or sets the unique identifier of the drive on OneDrive in which the file is stored. If NULL then the drive of the current user will be used.\n        /// </summary>\n        [DataMember]\n        public string RemoteDriveId { get; set; }\n\n        /// <summary>\n        /// Gets or sets the unique identifier of the file on OneDrive\n        /// </summary>\n        [DataMember]\n        public string RemoteItemId { get; set; }\n\n        /// <summary>\n        /// Gets or sets the filename under which the database is stored on OneDrive\n        /// </summary>\n        [DataMember]\n        public string RemoteFileName { get; set; }\n\n        /// <summary>\n        /// Gets or sets a boolean to indicate if the database should be synced with OneDrive\n        /// </summary>\n        [DataMember]\n        public bool DoNotSync { get; set; }\n\n        /// <summary>\n        /// The SHA1 hash of the local KeePass database\n        /// </summary>\n        [DataMember]\n        public string LocalFileHash { get; set; }\n\n        /// <summary>\n        /// The ETag of the KeePass database on OneDrive\n        /// </summary>\n        [DataMember]\n        public string ETag { get; set; }\n\n        /// <summary>\n        /// Date and time at which the database last synced with OneDrive\n        /// </summary>\n        [DataMember]\n        public DateTime? LastSyncedAt { get; set; }\n\n        /// <summary>\n        /// Date and time at which the database has last been compared with its equivallent on OneDrive\n        /// </summary>\n        [DataMember]\n        public DateTime? LastCheckedAt { get; set; }\n\n        /// <summary>\n        /// Type of cloud storage used for storing the database\n        /// </summary>\n        [DataMember]\n        public Enums.CloudStorageType? CloudStorageType { get; set; }\n\n        #endregion\n\n        #region Methods\n\n        /// <summary>\n        /// Gets the KeePass database configuration for KeePassOneDriveSync for the KeePass database of which the local path is provided\n        /// </summary>\n        /// <param name=\"localPasswordDatabasePath\">Full path to where the KeePass database resides locally</param>\n        /// <returns>KeePassOneDriveSync settings for the provided database. If no configuration exists yet for the database, it will provide a new empty configuration set.</returns>\n        public static Configuration GetPasswordDatabaseConfiguration(string localPasswordDatabasePath)\n        {\n            localPasswordDatabasePath = NormalizePath(localPasswordDatabasePath);\n\n            if (!PasswordDatabases.ContainsKey(localPasswordDatabasePath))\n            {\n                PasswordDatabases.Add(new KeyValuePair<string, Configuration>(localPasswordDatabasePath, new Configuration()));\n            }\n            return PasswordDatabases[localPasswordDatabasePath];\n        }\n\n        /// <summary>\n        /// Sets the KeePass database configuration for KeePassOneDriveSync for the KeePass database of which the local path is provided to the configuration that is provided\n        /// </summary>\n        /// <param name=\"localPasswordDatabasePath\">Full path to where the KeePass database resides locally</param>\n        /// <param name=\"configuration\">Configuration that should be set for the KeePass database. If configuration already existed for the same database, it will be overwritten. If it didn't exist yet, it will be added.</param>\n        public static void SetPasswordDatabaseConfiguration(string localPasswordDatabasePath, Configuration configuration)\n        {\n            localPasswordDatabasePath = NormalizePath(localPasswordDatabasePath);\n            PasswordDatabases[localPasswordDatabasePath] = configuration;\n        }\n\n        /// <summary>\n        /// Loads the configuration stored in KeePass\n        /// </summary>\n        public static void Load()\n        {\n            // Retrieve the stored configuration from KeePass\n            var value = KoenZomersKeePassOneDriveSyncExt.Host.CustomConfig.GetString(ConfigurationKey, null);\n\n            if (string.IsNullOrEmpty(value))\n            {\n                return;\n            }\n\n            try\n            {\n                // Convert the retrieved JSON to a typed entity\n                PasswordDatabases = JsonConvert.DeserializeObject<Dictionary<string, Configuration>>(value);\n            }\n            catch (JsonSerializationException)\n            {                \n                MessageBox.Show(\"Unable to parse the plugin configuration for the KeePass OneDriveSync plugin. If this happens again, please let me know. Sorry for the inconvinience. Koen Zomers <koen@zomers.eu>\", \"KeePass OneDriveSync Plugin\", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);\n\n                // Reset the configuration so at least it works again next time, all be it that all configuration will be lost\n                PasswordDatabases = new Dictionary<string, Configuration>();\n                Save();\n            }\n\n            // Get all database configurations which have their OneDrive Refresh Token stored in the Windows Credential Manager and retrieve them\n            var windowsCredentialManagerDatabaseConfigs = PasswordDatabases.Where(pwdDb => pwdDb.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager);\n            foreach (var windowsCredentialManagerDatabaseConfig in windowsCredentialManagerDatabaseConfigs)\n            {\n                windowsCredentialManagerDatabaseConfig.Value.RefreshToken = Utilities.GetRefreshTokenFromWindowsCredentialManager(windowsCredentialManagerDatabaseConfig.Key);\n            }\n\n            // Decrypt all database configurations which have their OneDrive Refresh Token stored encrypted in the config file\n            var encryptedDatabaseConfigs = PasswordDatabases.Where(pwdDb => pwdDb.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.DiskEncrypted);\n            foreach (var encryptedDatabaseConfig in encryptedDatabaseConfigs)\n            {\n                encryptedDatabaseConfig.Value.RefreshToken = string.IsNullOrWhiteSpace(encryptedDatabaseConfig.Value.RefreshToken) ? null : Utilities.Unprotect(encryptedDatabaseConfig.Value.RefreshToken);\n            }\n        }\n\n        /// <summary>\n        /// Saves the current configuration\n        /// </summary>\n        public static void Save()\n        {\n            // Create a new dictionary with the information to store in KeePass.config.xml\n            var passwordDatabasesForStoring = new Dictionary<string, Configuration>();\n\n            // Loop through the entries to store\n            foreach (var passwordDatabase in PasswordDatabases)\n            {\n                switch (passwordDatabase.Value.RefreshTokenStorage)\n                {\n                    case Enums.OneDriveRefreshTokenStorage.Disk:\n                    case Enums.OneDriveRefreshTokenStorage.DiskEncrypted:\n                        // Enforce encryption of tokens previously stored in plain text\n                        passwordDatabase.Value.RefreshTokenStorage = Enums.OneDriveRefreshTokenStorage.DiskEncrypted;\n\n                        // Refresh token will be stored encrypted on disk, we create a copy of the configuration and encrypt the refresh token\n                        var diskConfiguration = (Configuration)passwordDatabase.Value.Clone();\n                        diskConfiguration.RefreshToken = string.IsNullOrWhiteSpace(diskConfiguration.RefreshToken) ? null : Utilities.Protect(diskConfiguration.RefreshToken);\n                        passwordDatabasesForStoring.Add(passwordDatabase.Key, diskConfiguration);\n                        break;\n\n                    case Enums.OneDriveRefreshTokenStorage.KeePassDatabase:\n                    case Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager:\n                        // Refresh token will not be stored on disk, we create a copy of the configuration and remove the refresh token from it so it will not be stored on disk\n                        var tempConfiguration = (Configuration) passwordDatabase.Value.Clone();\n                        tempConfiguration.RefreshToken = null;\n                        passwordDatabasesForStoring.Add(passwordDatabase.Key, tempConfiguration);\n\n                        if (passwordDatabase.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.KeePassDatabase && passwordDatabase.Value.KeePassDatabase != null && !string.IsNullOrEmpty(passwordDatabase.Value.RefreshToken))\n                        {\n                            Utilities.SaveRefreshTokenInKeePassDatabase(passwordDatabase.Value.KeePassDatabase, passwordDatabase.Value.RefreshToken);\n                        }\n                        if (passwordDatabase.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager)\n                        {\n                            Utilities.SaveRefreshTokenInWindowsCredentialManager(passwordDatabase.Key, passwordDatabase.Value.RefreshToken);\n                        }\n                        break;\n                    default:\n                        // Hit when user selected the do not sync database option. In that case just store the config on disk as it doesn't contain any tokens.\n                        passwordDatabasesForStoring.Add(passwordDatabase.Key, passwordDatabase.Value);\n                        break;\n                }\n            }\n\n            // Serialize the configuration to JSON\n            var json = JsonConvert.SerializeObject(passwordDatabasesForStoring);\n\n            // Store the configuration in KeePass.config.xml\n            KoenZomersKeePassOneDriveSyncExt.Host.CustomConfig.SetString(ConfigurationKey, json);\n        }\n\n        /// <summary>\n        /// Returns a copy of the current instance\n        /// </summary>\n        public object Clone()\n        {\n            return MemberwiseClone();\n        }\n\n        /// <summary>\n        /// Deletes the complete configuration of the KeePass database on the provided local path\n        /// </summary>\n        /// <param name=\"localPasswordDatabasePath\">Full local path to a KeePass database of which to delete the configuration</param>\n        public static void DeleteConfig(string localPasswordDatabasePath)\n        {\n            localPasswordDatabasePath = NormalizePath(localPasswordDatabasePath);\n\n            // Verify if we have configuration available of a KeePass database stored on the provided full local path\n            if (!PasswordDatabases.ContainsKey(localPasswordDatabasePath)) return;\n            \n            // Retrieve the configuration we have available about the KeePass database\n            var config = PasswordDatabases[localPasswordDatabasePath];\n            \n            // Take cleanup actions based on where the OneDrive Refresh Token is stored\n            switch (config.RefreshTokenStorage)\n            {\n                case Enums.OneDriveRefreshTokenStorage.Disk:\n                case Enums.OneDriveRefreshTokenStorage.DiskEncrypted:\n                    // No action required as it will be removed as part of removing the complete configuration\n                    break;\n\n                case Enums.OneDriveRefreshTokenStorage.KeePassDatabase:\n                    // There's no way to remove it from the KeePass database without having the database open, so we'll have to leave it there\n                    break;\n\n                case Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager:\n                    Utilities.DeleteRefreshTokenFromWindowsCredentialManager(localPasswordDatabasePath);\n                    break;\n            }\n\n            // Remove the configuration we have available\n            PasswordDatabases.Remove(localPasswordDatabasePath);\n\n            // Initiate a save to write the results\n            Save();\n        }\n\n        /// <summary>\n        /// Get the full PasswordDatabases object list, used by the configuration form\n        /// </summary>\n        /// <returns></returns>\n        internal static IDictionary<string, Configuration> GetAllConfigurations()\n        {\n            return PasswordDatabases;\n        }\n\n        /// <summary>\n        /// Boolean to indicate if some process is still running that we need to wait for before we shut down KeePass\n        /// </summary>\n        internal static bool IsSomethingStillRunning\n        {\n            get\n            {\n                return PasswordDatabases.Any(db => db.Value.IsCurrentlySyncing);\n            }\n        }\n\n        /// <summary>\n        /// Normalize database path - if located under the KeePass folder (portable install) then use a relative path, otherwise use the original (absolute)\n        /// </summary>\n        /// <param name=\"localPasswordDatabasePath\">Full path to a KeePass database</param>\n        /// <returns>If the path resides under the folder where KeePass runs from, it will return a relative path, otherwise the full path will be returned</returns>\n        private static string NormalizePath(string localPasswordDatabasePath)\n        {\n            if (localPasswordDatabasePath.StartsWith(AppDomain.CurrentDomain.BaseDirectory))\n            {\n                localPasswordDatabasePath = localPasswordDatabasePath.Remove(0, AppDomain.CurrentDomain.BaseDirectory.Length);\n            }\n\n            return localPasswordDatabasePath;\n        }\n\n        #endregion\n    }\n}\n\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Enums/CloudStorageType.cs",
    "content": "﻿namespace KoenZomers.KeePass.OneDriveSync.Enums\n{\n    /// <summary>\n    /// Defines the types of cloud storage that can be used\n    /// </summary>\n    public enum CloudStorageType : short\n    {\n        /// <summary>\n        /// Consumer OneDrive\n        /// </summary>\n        OneDriveConsumer = 0,\n\n        /// <summary>\n        /// Microsoft Graph API\n        /// </summary>\n        MicrosoftGraph = 2,\n\n        /// <summary>\n        /// Microsoft SharePoint\n        /// </summary>\n        SharePoint = 3,\n\n        /// <summary>\n        /// Microsoft Graph API Device Login\n        /// </summary>\n        MicrosoftGraphDeviceLogin = 4,\n\n        /// <summary>\n        /// Do not sync\n        /// </summary>\n        None = 99\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Enums/OneDriveRefreshTokenStorage.cs",
    "content": "﻿namespace KoenZomers.KeePass.OneDriveSync.Enums\n{\n    /// <summary>\n    /// Defines the possible storage locations for the OneDrive Refresh Token\n    /// </summary>\n    public enum OneDriveRefreshTokenStorage : short\n    {\n        /// <summary>\n        /// Saves the RefreshToken plain text in KeePass.config.xml located in %APPDATA%\\KeePass \n        /// </summary>\n        Disk = 0,\n\n        /// <summary>\n        /// Saves the RefreshToken encrypted in the Windows Credential Manager\n        /// </summary>\n        WindowsCredentialManager = 1,\n\n        /// <summary>\n        /// Saves the RefreshToken in the encrypted KeePass database\n        /// </summary>\n        KeePassDatabase = 2,\n\n        /// <summary>\n        /// Saves the RefreshToken encrypted with DPAPI in KeePass.config.xml located in %APPDATA%\\KeePass \n        /// </summary>\n        DiskEncrypted = 3,\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class AboutForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.NameLabel = new System.Windows.Forms.Label();\n            this.CloseButton = new System.Windows.Forms.Button();\n            this.HeaderLabel = new System.Windows.Forms.Label();\n            this.SuspendLayout();\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(23, 73);\n            this.ExplanationLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(608, 72);\n            this.ExplanationLabel.TabIndex = 11;\n            this.ExplanationLabel.Text = \"This KeePass plugin allows synchronizing your KeePass databases with one or multiple OneDrive accounts. It is inspired by KeeSkyDrive by Oleksandr Senyuk. It is free to use and open source. Please leave these credits in place if you decide to use my source code. Feel free to contact me in case of questions or suggestions.\";\n            // \n            // NameLabel\n            // \n            this.NameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.NameLabel.Location = new System.Drawing.Point(23, 158);\n            this.NameLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);\n            this.NameLabel.Name = \"NameLabel\";\n            this.NameLabel.Size = new System.Drawing.Size(608, 27);\n            this.NameLabel.TabIndex = 10;\n            this.NameLabel.Text = \"Koen Zomers <mail@koenzomers.nl>\";\n            this.NameLabel.UseMnemonic = false;\n            // \n            // CloseButton\n            // \n            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;\n            this.CloseButton.Location = new System.Drawing.Point(455, 190);\n            this.CloseButton.Margin = new System.Windows.Forms.Padding(5);\n            this.CloseButton.Name = \"CloseButton\";\n            this.CloseButton.Size = new System.Drawing.Size(176, 50);\n            this.CloseButton.TabIndex = 9;\n            this.CloseButton.Text = \"&Close\";\n            this.CloseButton.UseVisualStyleBackColor = true;\n            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);\n            // \n            // HeaderLabel\n            // \n            this.HeaderLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.HeaderLabel.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.HeaderLabel.Location = new System.Drawing.Point(21, 16);\n            this.HeaderLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);\n            this.HeaderLabel.Name = \"HeaderLabel\";\n            this.HeaderLabel.Size = new System.Drawing.Size(610, 34);\n            this.HeaderLabel.TabIndex = 8;\n            this.HeaderLabel.Text = \"KeePass OneDriveSync\";\n            this.HeaderLabel.UseMnemonic = false;\n            // \n            // AboutForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(645, 254);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Controls.Add(this.NameLabel);\n            this.Controls.Add(this.CloseButton);\n            this.Controls.Add(this.HeaderLabel);\n            this.Margin = new System.Windows.Forms.Padding(4);\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(410, 280);\n            this.Name = \"AboutForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"About KeePass OneDriveSync\";\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.Label NameLabel;\n        private System.Windows.Forms.Button CloseButton;\n        private System.Windows.Forms.Label HeaderLabel;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.cs",
    "content": "﻿using System.Reflection;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partial class AboutForm : Form\n    {\n        public AboutForm()\n        {\n            InitializeComponent();\n\n            var assemblyVersion = Assembly.GetCallingAssembly().GetName().Version;\n\n            HeaderLabel.Text = string.Format(\"KeePass OneDriveSync v{0}.{1}.{2}\", assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build);\n        }\n\n        private void CloseButton_Click(object sender, System.EventArgs e)\n        {\n            Close();\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveAboutForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.HeaderLabel = new System.Windows.Forms.Label();\n            this.CloseButton = new System.Windows.Forms.Button();\n            this.NameLabel = new System.Windows.Forms.Label();\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.WebsiteLinkLabel = new System.Windows.Forms.LinkLabel();\n            this.SuspendLayout();\n            // \n            // HeaderLabel\n            // \n            this.HeaderLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.HeaderLabel.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.HeaderLabel.Location = new System.Drawing.Point(18, 14);\n            this.HeaderLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.HeaderLabel.Name = \"HeaderLabel\";\n            this.HeaderLabel.Size = new System.Drawing.Size(561, 35);\n            this.HeaderLabel.TabIndex = 2;\n            this.HeaderLabel.Text = \"KeePass OneDriveSync\";\n            this.HeaderLabel.UseMnemonic = false;\n            // \n            // CloseButton\n            // \n            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;\n            this.CloseButton.Location = new System.Drawing.Point(431, 194);\n            this.CloseButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);\n            this.CloseButton.Name = \"CloseButton\";\n            this.CloseButton.Size = new System.Drawing.Size(148, 51);\n            this.CloseButton.TabIndex = 5;\n            this.CloseButton.Text = \"&Close\";\n            this.CloseButton.UseVisualStyleBackColor = true;\n            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);\n            // \n            // NameLabel\n            // \n            this.NameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.NameLabel.Location = new System.Drawing.Point(20, 194);\n            this.NameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.NameLabel.Name = \"NameLabel\";\n            this.NameLabel.Size = new System.Drawing.Size(405, 28);\n            this.NameLabel.TabIndex = 6;\n            this.NameLabel.Text = \"Koen Zomers (koen@zomers.eu)\";\n            this.NameLabel.UseMnemonic = false;\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(19, 71);\n            this.ExplanationLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.ExplanationLabel.MinimumSize = new System.Drawing.Size(558, 118);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(558, 118);\n            this.ExplanationLabel.TabIndex = 7;\n            this.ExplanationLabel.Text = \"This KeePass plugin allows synchronizing your KeePass databases with one or multiple OneDrive accounts. It is inspired by KeeSkyDrive by Oleksandr Senyuk. It is free to use and open source. Please leave these credits in place if you decide to use my source code. Feel free to contact me in case of questions or suggestions.\";\n            // \n            // WebsiteLinkLabel\n            // \n            this.WebsiteLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.WebsiteLinkLabel.AutoSize = true;\n            this.WebsiteLinkLabel.Location = new System.Drawing.Point(19, 222);\n            this.WebsiteLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.WebsiteLinkLabel.Name = \"WebsiteLinkLabel\";\n            this.WebsiteLinkLabel.Size = new System.Drawing.Size(398, 20);\n            this.WebsiteLinkLabel.TabIndex = 9;\n            this.WebsiteLinkLabel.TabStop = true;\n            this.WebsiteLinkLabel.Text = \"https://github.com/KoenZomers/KeePassOneDriveSync\";\n            this.WebsiteLinkLabel.Click += new System.EventHandler(this.WebsiteLinkLabel_Click);\n            // \n            // OneDriveAboutForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(597, 262);\n            this.Controls.Add(this.CloseButton);\n            this.Controls.Add(this.WebsiteLinkLabel);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Controls.Add(this.NameLabel);\n            this.Controls.Add(this.HeaderLabel);\n            this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(619, 250);\n            this.Name = \"OneDriveAboutForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"About KeePass OneDriveSync\";\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label HeaderLabel;\n        private System.Windows.Forms.Button CloseButton;\n        private System.Windows.Forms.Label NameLabel;\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.LinkLabel WebsiteLinkLabel;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.cs",
    "content": "﻿using System;\nusing System.Reflection;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    /// <summary>\n    /// About Form\n    /// </summary>\n    public partial class OneDriveAboutForm : Form\n    {\n        public OneDriveAboutForm()\n        {\n            InitializeComponent();\n\n            var assemblyVersion = Assembly.GetCallingAssembly().GetName().Version;\n\n            HeaderLabel.Text = string.Format(\"KeePass OneDriveSync v{0}.{1}.{2}.{3}\", assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build, assemblyVersion.Revision);\n        }\n\n        private void CloseButton_Click(object sender, EventArgs e)\n        {\n\n        }\n\n        private void WebsiteLinkLabel_Click(object sender, EventArgs e)\n        {\n            System.Diagnostics.Process.Start(WebsiteLinkLabel.Text);\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ExplanationLabel.Text\" xml:space=\"preserve\">\n    <value>This KeePass plugin allows synchronizing your KeePass databases with one or multiple OneDrive accounts. It is inspired by KeeSkyDrive by Oleksandr Senyuk. It is free to use and open source. Please leave these credits in place if you decide to use my source code. Feel free to contact me in case of questions or suggestions.</value>\n  </data>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.Designer.cs",
    "content": "﻿﻿namespace KoenZomersKeePassOneDriveSync\n {\n     partial class OneDriveAskToStartSyncingDialog\n     {\n         /// <summary>\n         /// Required designer variable.\n         /// </summary>\n         private System.ComponentModel.IContainer components = null;\n\n         /// <summary>\n         /// Clean up any resources being used.\n         /// </summary>\n         /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n         protected override void Dispose(bool disposing)\n         {\n             if (disposing && (components != null))\n             {\n                 components.Dispose();\n             }\n             base.Dispose(disposing);\n         }\n\n         #region Windows Form Designer generated code\n\n         /// <summary>\n         /// Required method for Designer support - do not modify\n         /// the contents of this method with the code editor.\n         /// </summary>\n         private void InitializeComponent()\n         {\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.YesRadio = new System.Windows.Forms.RadioButton();\n            this.NotNowRadio = new System.Windows.Forms.RadioButton();\n            this.NoNeverAskAgainRadio = new System.Windows.Forms.RadioButton();\n            this.OKButton = new System.Windows.Forms.Button();\n            this.CancelButton = new System.Windows.Forms.Button();\n            this.OneDriveDatabasePath = new System.Windows.Forms.TextBox();\n            this.SuspendLayout();\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(9, 7);\n            this.ExplanationLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(375, 35);\n            this.ExplanationLabel.TabIndex = 0;\n            this.ExplanationLabel.Text = \"The following KeePass database is not being synced with OneDrive. Would you like \" +\n    \"to set up a synchronization connection now?\";\n            // \n            // YesRadio\n            // \n            this.YesRadio.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.YesRadio.AutoSize = true;\n            this.YesRadio.Checked = true;\n            this.YesRadio.Location = new System.Drawing.Point(11, 75);\n            this.YesRadio.Margin = new System.Windows.Forms.Padding(2);\n            this.YesRadio.Name = \"YesRadio\";\n            this.YesRadio.Size = new System.Drawing.Size(43, 17);\n            this.YesRadio.TabIndex = 1;\n            this.YesRadio.TabStop = true;\n            this.YesRadio.Text = \"Yes\";\n            this.YesRadio.UseVisualStyleBackColor = true;\n            // \n            // NotNowRadio\n            // \n            this.NotNowRadio.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.NotNowRadio.AutoSize = true;\n            this.NotNowRadio.Location = new System.Drawing.Point(11, 97);\n            this.NotNowRadio.Margin = new System.Windows.Forms.Padding(2);\n            this.NotNowRadio.Name = \"NotNowRadio\";\n            this.NotNowRadio.Size = new System.Drawing.Size(65, 17);\n            this.NotNowRadio.TabIndex = 2;\n            this.NotNowRadio.Text = \"Not now\";\n            this.NotNowRadio.UseVisualStyleBackColor = true;\n            // \n            // NoNeverAskAgainRadio\n            // \n            this.NoNeverAskAgainRadio.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.NoNeverAskAgainRadio.AutoSize = true;\n            this.NoNeverAskAgainRadio.Location = new System.Drawing.Point(11, 118);\n            this.NoNeverAskAgainRadio.Margin = new System.Windows.Forms.Padding(2);\n            this.NoNeverAskAgainRadio.Name = \"NoNeverAskAgainRadio\";\n            this.NoNeverAskAgainRadio.Size = new System.Drawing.Size(220, 17);\n            this.NoNeverAskAgainRadio.TabIndex = 3;\n            this.NoNeverAskAgainRadio.Text = \"No and never ask again for this database\";\n            this.NoNeverAskAgainRadio.UseVisualStyleBackColor = true;\n            // \n            // OKButton\n            // \n            this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.OKButton.Location = new System.Drawing.Point(127, 154);\n            this.OKButton.Margin = new System.Windows.Forms.Padding(2);\n            this.OKButton.Name = \"OKButton\";\n            this.OKButton.Size = new System.Drawing.Size(74, 41);\n            this.OKButton.TabIndex = 5;\n            this.OKButton.Text = \"&OK\";\n            this.OKButton.UseVisualStyleBackColor = true;\n            this.OKButton.Click += new System.EventHandler(this.OKButton_Click);\n            // \n            // CancelButton\n            // \n            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.CancelButton.Location = new System.Drawing.Point(206, 154);\n            this.CancelButton.Margin = new System.Windows.Forms.Padding(2);\n            this.CancelButton.Name = \"CancelButton\";\n            this.CancelButton.Size = new System.Drawing.Size(74, 41);\n            this.CancelButton.TabIndex = 6;\n            this.CancelButton.Text = \"&Cancel\";\n            this.CancelButton.UseVisualStyleBackColor = true;\n            // \n            // OneDriveDatabasePath\n            // \n            this.OneDriveDatabasePath.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.OneDriveDatabasePath.BackColor = System.Drawing.SystemColors.Control;\n            this.OneDriveDatabasePath.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.OneDriveDatabasePath.Location = new System.Drawing.Point(12, 45);\n            this.OneDriveDatabasePath.Name = \"OneDriveDatabasePath\";\n            this.OneDriveDatabasePath.ReadOnly = true;\n            this.OneDriveDatabasePath.Size = new System.Drawing.Size(369, 13);\n            this.OneDriveDatabasePath.TabIndex = 7;\n            this.OneDriveDatabasePath.Text = \"?\";\n            // \n            // OneDriveAskToStartSyncingDialog\n            // \n            this.AcceptButton = this.OKButton;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(393, 205);\n            this.Controls.Add(this.OneDriveDatabasePath);\n            this.Controls.Add(this.CancelButton);\n            this.Controls.Add(this.OKButton);\n            this.Controls.Add(this.NoNeverAskAgainRadio);\n            this.Controls.Add(this.NotNowRadio);\n            this.Controls.Add(this.YesRadio);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Margin = new System.Windows.Forms.Padding(2);\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(409, 244);\n            this.Name = \"OneDriveAskToStartSyncingDialog\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Start syncing with OneDrive\";\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n         }\n\n         #endregion\n\n         private System.Windows.Forms.Label ExplanationLabel;\n         private System.Windows.Forms.Button OKButton;\n         private System.Windows.Forms.Button CancelButton;\n         private System.Windows.Forms.RadioButton YesRadio;\n         private System.Windows.Forms.RadioButton NotNowRadio;\n         private System.Windows.Forms.RadioButton NoNeverAskAgainRadio;\n        private System.Windows.Forms.TextBox OneDriveDatabasePath;\n    }\n }"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.cs",
    "content": "﻿﻿using System;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partial class OneDriveAskToStartSyncingDialog : Form\n    {\n        /// <summary>\n        /// Configuration of the database for which this question is being asked for\n        /// </summary>\n        private readonly Configuration _configuration;\n\n        public OneDriveAskToStartSyncingDialog(Configuration configuration)\n        {\n            InitializeComponent();\n\n            _configuration = configuration;\n\n            OneDriveDatabasePath.Text = configuration.KeePassDatabase.IOConnectionInfo.Path;\n        }\n\n        private void OKButton_Click(object sender, EventArgs e)\n        {\n            if (NotNowRadio.Checked)\n            {\n                DialogResult = DialogResult.Cancel;\n            }\n            if (YesRadio.Checked)\n            {\n                DialogResult = DialogResult.OK;\n            }\n            if (NoNeverAskAgainRadio.Checked)\n            {\n                _configuration.DoNotSync = NoNeverAskAgainRadio.Checked;\n                Configuration.Save();\n                DialogResult = DialogResult.OK;\n            }\n\n            Close();\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveAuthenticateForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.WebBrowser = new System.Windows.Forms.WebBrowser();\n            this.SuspendLayout();\n            // \n            // WebBrowser\n            // \n            this.WebBrowser.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.WebBrowser.Location = new System.Drawing.Point(-2, 0);\n            this.WebBrowser.MinimumSize = new System.Drawing.Size(22, 25);\n            this.WebBrowser.Name = \"WebBrowser\";\n            this.WebBrowser.ScriptErrorsSuppressed = true;\n            this.WebBrowser.Size = new System.Drawing.Size(664, 828);\n            this.WebBrowser.TabIndex = 0;\n            this.WebBrowser.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.WebBrowser_Navigated);\n            // \n            // OneDriveAuthenticateForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(664, 826);\n            this.Controls.Add(this.WebBrowser);\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(438, 390);\n            this.Name = \"OneDriveAuthenticateForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Authenticate to OneDrive\";\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.WebBrowser WebBrowser;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.cs",
    "content": "﻿using System.Windows.Forms;\nusing KoenZomers.OneDrive.Api;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partial class OneDriveAuthenticateForm : Form\n    {\n        /// <summary>\n        /// OneDrive API instance\n        /// </summary>\n        public OneDriveApi OneDriveApi { get; private set; }\n\n        public OneDriveAuthenticateForm(OneDriveApi oneDriveApi)\n        {\n            InitializeComponent();\n\n            OneDriveApi = oneDriveApi;\n            Utilities.ApplyProxySettings(OneDriveApi);\n\n            SignOut();\n        }\n\n        /// <summary>\n        /// Sign the current user out of OneDrive\n        /// </summary>\n        public void SignOut()\n        {\n            // First sign the current user out to make sure he/she needs to authenticate again\n            var signoutUri = OneDriveApi.GetSignOutUri();\n            WebBrowser.Navigate(signoutUri);\n        }\n\n        private async void WebBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)\n        {\n            // Check if the current URL contains the authorization token\n            var authorizationCode = OneDriveApi.GetAuthorizationTokenFromUrl(e.Url.ToString());\n\n            // Verify if an authorization token was successfully extracted\n            if (!string.IsNullOrEmpty(authorizationCode))\n            {\n                // Get an access token based on the authorization token that we now have\n                await OneDriveApi.GetAccessToken();\n                if (OneDriveApi.AccessToken != null)\n                {\n                    DialogResult = DialogResult.OK;\n                    Close();\n                    return;\n                }\n            }\n\n            // If we're on this page, but we didn't get an authorization token, it means that we just signed out, proceed with signing in again\n            if (e.Url.ToString().StartsWith(OneDriveApi.SignoutUri))\n            {\n                var authenticateUri = OneDriveApi.GetAuthenticationUri();\n                WebBrowser.Navigate(authenticateUri);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveCloudTypeForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.CancelButton = new System.Windows.Forms.Button();\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.CloudPlatformTabs = new System.Windows.Forms.TabControl();\n            this.OneDriveTab = new System.Windows.Forms.TabPage();\n            this.GraphDeviceLoginPictureButton = new System.Windows.Forms.Button();\n            this.GraphPictureButton = new System.Windows.Forms.Button();\n            this.SharePointTab = new System.Windows.Forms.TabPage();\n            this.SharePointPictureButton = new System.Windows.Forms.Button();\n            this.CloudPlatformTabs.SuspendLayout();\n            this.OneDriveTab.SuspendLayout();\n            this.SharePointTab.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // CancelButton\n            // \n            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.CancelButton.Location = new System.Drawing.Point(200, 432);\n            this.CancelButton.Name = \"CancelButton\";\n            this.CancelButton.Size = new System.Drawing.Size(168, 43);\n            this.CancelButton.TabIndex = 1;\n            this.CancelButton.Text = \"Cancel\";\n            this.CancelButton.UseVisualStyleBackColor = true;\n            this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click);\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(22, 9);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(531, 37);\n            this.ExplanationLabel.TabIndex = 0;\n            this.ExplanationLabel.Text = \"Choose the cloud service you wish to store the KeePass database on:\";\n            // \n            // CloudPlatformTabs\n            // \n            this.CloudPlatformTabs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloudPlatformTabs.Controls.Add(this.OneDriveTab);\n            this.CloudPlatformTabs.Controls.Add(this.SharePointTab);\n            this.CloudPlatformTabs.Location = new System.Drawing.Point(26, 48);\n            this.CloudPlatformTabs.Name = \"CloudPlatformTabs\";\n            this.CloudPlatformTabs.SelectedIndex = 0;\n            this.CloudPlatformTabs.Size = new System.Drawing.Size(514, 378);\n            this.CloudPlatformTabs.TabIndex = 0;\n            // \n            // OneDriveTab\n            // \n            this.OneDriveTab.Controls.Add(this.GraphDeviceLoginPictureButton);\n            this.OneDriveTab.Controls.Add(this.GraphPictureButton);\n            this.OneDriveTab.Location = new System.Drawing.Point(4, 29);\n            this.OneDriveTab.Name = \"OneDriveTab\";\n            this.OneDriveTab.Size = new System.Drawing.Size(506, 345);\n            this.OneDriveTab.TabIndex = 0;\n            this.OneDriveTab.Text = \"OneDrive\";\n            this.OneDriveTab.UseVisualStyleBackColor = true;\n            // \n            // GraphDeviceLoginPictureButton\n            // \n            this.GraphDeviceLoginPictureButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.GraphDeviceLoginPictureButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));\n            this.GraphDeviceLoginPictureButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;\n            this.GraphDeviceLoginPictureButton.Location = new System.Drawing.Point(10, 15);\n            this.GraphDeviceLoginPictureButton.Name = \"GraphDeviceLoginPictureButton\";\n            this.GraphDeviceLoginPictureButton.Size = new System.Drawing.Size(483, 151);\n            this.GraphDeviceLoginPictureButton.TabIndex = 0;\n            this.GraphDeviceLoginPictureButton.Text = \"&Any browser (recommended)\";\n            this.GraphDeviceLoginPictureButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;\n            this.GraphDeviceLoginPictureButton.UseVisualStyleBackColor = false;\n            this.GraphDeviceLoginPictureButton.Click += new System.EventHandler(this.GraphDeviceLoginPictureButton_Click);\n            // \n            // GraphPictureButton\n            // \n            this.GraphPictureButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.GraphPictureButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));\n            this.GraphPictureButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;\n            this.GraphPictureButton.Location = new System.Drawing.Point(10, 175);\n            this.GraphPictureButton.Name = \"GraphPictureButton\";\n            this.GraphPictureButton.Size = new System.Drawing.Size(483, 151);\n            this.GraphPictureButton.TabIndex = 1;\n            this.GraphPictureButton.Text = \"&Built-in browser\";\n            this.GraphPictureButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;\n            this.GraphPictureButton.UseVisualStyleBackColor = false;\n            this.GraphPictureButton.Click += new System.EventHandler(this.GraphPictureButton_Click);\n            // \n            // SharePointTab\n            // \n            this.SharePointTab.Controls.Add(this.SharePointPictureButton);\n            this.SharePointTab.Location = new System.Drawing.Point(4, 29);\n            this.SharePointTab.Name = \"SharePointTab\";\n            this.SharePointTab.Size = new System.Drawing.Size(506, 345);\n            this.SharePointTab.TabIndex = 1;\n            this.SharePointTab.Text = \"SharePoint\";\n            this.SharePointTab.UseVisualStyleBackColor = true;\n            // \n            // SharePointPictureButton\n            // \n            this.SharePointPictureButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.SharePointPictureButton.BackColor = System.Drawing.Color.White;\n            this.SharePointPictureButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;\n            this.SharePointPictureButton.ForeColor = System.Drawing.SystemColors.ControlText;\n            this.SharePointPictureButton.Location = new System.Drawing.Point(12, 17);\n            this.SharePointPictureButton.Name = \"SharePointPictureButton\";\n            this.SharePointPictureButton.Size = new System.Drawing.Size(483, 129);\n            this.SharePointPictureButton.TabIndex = 8;\n            this.SharePointPictureButton.Text = \"SharePoint 2013, 2016, 2019 & Online\";\n            this.SharePointPictureButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;\n            this.SharePointPictureButton.UseMnemonic = false;\n            this.SharePointPictureButton.UseVisualStyleBackColor = false;\n            this.SharePointPictureButton.Click += new System.EventHandler(this.SharePointPictureButton_Click);\n            // \n            // OneDriveCloudTypeForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(564, 489);\n            this.Controls.Add(this.CloudPlatformTabs);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Controls.Add(this.CancelButton);\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"OneDriveCloudTypeForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Choose Cloud Platform\";\n            this.CloudPlatformTabs.ResumeLayout(false);\n            this.OneDriveTab.ResumeLayout(false);\n            this.SharePointTab.ResumeLayout(false);\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Button CancelButton;\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.TabControl CloudPlatformTabs;\n        private System.Windows.Forms.TabPage OneDriveTab;\n        private System.Windows.Forms.Button GraphPictureButton;\n        private System.Windows.Forms.TabPage SharePointTab;\n        private System.Windows.Forms.Button SharePointPictureButton;\n        private System.Windows.Forms.Button GraphDeviceLoginPictureButton;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partial class OneDriveCloudTypeForm : Form\n    {\n        /// <summary>\n        /// The cloud storage provider that was chosen in this dialog\n        /// </summary>\n        public CloudStorageType ChosenCloudStorageType { get; private set; }\n\n        /// <summary>\n        /// Gets or sets the explanation text in the dialog\n        /// </summary>\n        public string ExplanationText\n        {\n            get { return ExplanationLabel.Text; }\n            set { ExplanationLabel.Text = value; }\n        }\n\n        public OneDriveCloudTypeForm()\n        {\n            InitializeComponent();\n\n            GraphPictureButton.BackgroundImage = Resources.OneDriveBothClouds;\n            GraphDeviceLoginPictureButton.BackgroundImage = Resources.OneDriveBothClouds;\n            SharePointPictureButton.BackgroundImage = Resources.SharePoint;\n        }\n\n        private void OneDriveConsumerPicture_Click(object sender, EventArgs e)\n        {\n            ChosenCloudStorageType = CloudStorageType.OneDriveConsumer;\n            DialogResult = DialogResult.OK;\n\n            Close();\n        }\n\n        private void OneDriveConsumerPictureButton_Click(object sender, EventArgs e)\n        {\n            ChosenCloudStorageType = CloudStorageType.OneDriveConsumer;\n            DialogResult = DialogResult.OK;\n\n            Close();\n        }\n\n        private void GraphPictureButton_Click(object sender, EventArgs e)\n        {\n            ChosenCloudStorageType = CloudStorageType.MicrosoftGraph;\n            DialogResult = DialogResult.OK;\n\n            Close();\n        }\n\n        private void SharePointPictureButton_Click(object sender, EventArgs e)\n        {\n            ChosenCloudStorageType = CloudStorageType.SharePoint;\n            DialogResult = DialogResult.OK;\n\n            Close();\n        }\n\n        private void CancelButton_Click(object sender, EventArgs e)\n        {\n\n        }\n\n        private void GraphDeviceLoginPictureButton_Click(object sender, EventArgs e)\n        {\n            ChosenCloudStorageType = CloudStorageType.MicrosoftGraphDeviceLogin;\n            DialogResult = DialogResult.OK;\n\n            Close();\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveConfigDetailsForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.LocationNameLabel = new System.Windows.Forms.Label();\n            this.LocalKeePassPathLabel = new System.Windows.Forms.Label();\n            this.RemoteKeePassPathLabel = new System.Windows.Forms.Label();\n            this.OneDriveRefreshTokenLabel = new System.Windows.Forms.Label();\n            this.RemoteKeePassPathTextbox = new System.Windows.Forms.TextBox();\n            this.OneDriveRefreshTokenTextbox = new System.Windows.Forms.TextBox();\n            this.OneDriveNameTextbox = new System.Windows.Forms.TextBox();\n            this.CloseButton = new System.Windows.Forms.Button();\n            this.DeleteButton = new System.Windows.Forms.Button();\n            this.LastSyncedLabel = new System.Windows.Forms.Label();\n            this.LastSyncedTextbox = new System.Windows.Forms.TextBox();\n            this.LocalKeePassFileHashLabel = new System.Windows.Forms.Label();\n            this.LocalKeePassFileHashTextbox = new System.Windows.Forms.TextBox();\n            this.ForceSyncButton = new System.Windows.Forms.Button();\n            this.LastVerifiedLabel = new System.Windows.Forms.Label();\n            this.LastVerifiedTextbox = new System.Windows.Forms.TextBox();\n            this.StatusLabel = new System.Windows.Forms.Label();\n            this.RefreshTokenStorageTextBox = new System.Windows.Forms.TextBox();\n            this.RefreshTokenStorageLabel = new System.Windows.Forms.Label();\n            this.CloudStorageTypeTextBox = new System.Windows.Forms.TextBox();\n            this.CloudStorageTypeLabel = new System.Windows.Forms.Label();\n            this.OneDriveEtagTextBox = new System.Windows.Forms.TextBox();\n            this.OneDriveEtagLabel = new System.Windows.Forms.Label();\n            this.LocalDatabasePathLinkLabel = new System.Windows.Forms.LinkLabel();\n            this.ItemIdTextBox = new System.Windows.Forms.TextBox();\n            this.ItemIdLabel = new System.Windows.Forms.Label();\n            this.FolderIdTextBox = new System.Windows.Forms.TextBox();\n            this.FolderIdLabel = new System.Windows.Forms.Label();\n            this.DriveIdTextBox = new System.Windows.Forms.TextBox();\n            this.DriveIdLabel = new System.Windows.Forms.Label();\n            this.SuspendLayout();\n            // \n            // LocationNameLabel\n            // \n            this.LocationNameLabel.Location = new System.Drawing.Point(16, 11);\n            this.LocationNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.LocationNameLabel.Name = \"LocationNameLabel\";\n            this.LocationNameLabel.Size = new System.Drawing.Size(236, 20);\n            this.LocationNameLabel.TabIndex = 0;\n            this.LocationNameLabel.Text = \"Location Name:\";\n            this.LocationNameLabel.UseMnemonic = false;\n            // \n            // LocalKeePassPathLabel\n            // \n            this.LocalKeePassPathLabel.Location = new System.Drawing.Point(16, 58);\n            this.LocalKeePassPathLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.LocalKeePassPathLabel.Name = \"LocalKeePassPathLabel\";\n            this.LocalKeePassPathLabel.Size = new System.Drawing.Size(236, 20);\n            this.LocalKeePassPathLabel.TabIndex = 2;\n            this.LocalKeePassPathLabel.Text = \"Local KeePass path:\";\n            this.LocalKeePassPathLabel.UseMnemonic = false;\n            // \n            // RemoteKeePassPathLabel\n            // \n            this.RemoteKeePassPathLabel.Location = new System.Drawing.Point(16, 83);\n            this.RemoteKeePassPathLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.RemoteKeePassPathLabel.Name = \"RemoteKeePassPathLabel\";\n            this.RemoteKeePassPathLabel.Size = new System.Drawing.Size(236, 20);\n            this.RemoteKeePassPathLabel.TabIndex = 4;\n            this.RemoteKeePassPathLabel.Text = \"Remote KeePass path:\";\n            this.RemoteKeePassPathLabel.UseMnemonic = false;\n            // \n            // OneDriveRefreshTokenLabel\n            // \n            this.OneDriveRefreshTokenLabel.Location = new System.Drawing.Point(16, 109);\n            this.OneDriveRefreshTokenLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.OneDriveRefreshTokenLabel.Name = \"OneDriveRefreshTokenLabel\";\n            this.OneDriveRefreshTokenLabel.Size = new System.Drawing.Size(236, 20);\n            this.OneDriveRefreshTokenLabel.TabIndex = 6;\n            this.OneDriveRefreshTokenLabel.Text = \"API Refresh Token:\";\n            this.OneDriveRefreshTokenLabel.UseMnemonic = false;\n            // \n            // RemoteKeePassPathTextbox\n            // \n            this.RemoteKeePassPathTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.RemoteKeePassPathTextbox.BackColor = System.Drawing.SystemColors.Control;\n            this.RemoteKeePassPathTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.RemoteKeePassPathTextbox.Location = new System.Drawing.Point(260, 83);\n            this.RemoteKeePassPathTextbox.Margin = new System.Windows.Forms.Padding(4);\n            this.RemoteKeePassPathTextbox.Name = \"RemoteKeePassPathTextbox\";\n            this.RemoteKeePassPathTextbox.ReadOnly = true;\n            this.RemoteKeePassPathTextbox.Size = new System.Drawing.Size(444, 15);\n            this.RemoteKeePassPathTextbox.TabIndex = 4;\n            this.RemoteKeePassPathTextbox.Text = \"?\";\n            // \n            // OneDriveRefreshTokenTextbox\n            // \n            this.OneDriveRefreshTokenTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.OneDriveRefreshTokenTextbox.BackColor = System.Drawing.SystemColors.Control;\n            this.OneDriveRefreshTokenTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.OneDriveRefreshTokenTextbox.Location = new System.Drawing.Point(260, 109);\n            this.OneDriveRefreshTokenTextbox.Margin = new System.Windows.Forms.Padding(4);\n            this.OneDriveRefreshTokenTextbox.Name = \"OneDriveRefreshTokenTextbox\";\n            this.OneDriveRefreshTokenTextbox.ReadOnly = true;\n            this.OneDriveRefreshTokenTextbox.Size = new System.Drawing.Size(444, 15);\n            this.OneDriveRefreshTokenTextbox.TabIndex = 5;\n            this.OneDriveRefreshTokenTextbox.Text = \"?\";\n            // \n            // OneDriveNameTextbox\n            // \n            this.OneDriveNameTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.OneDriveNameTextbox.BackColor = System.Drawing.SystemColors.Control;\n            this.OneDriveNameTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.OneDriveNameTextbox.Location = new System.Drawing.Point(260, 11);\n            this.OneDriveNameTextbox.Margin = new System.Windows.Forms.Padding(4);\n            this.OneDriveNameTextbox.Name = \"OneDriveNameTextbox\";\n            this.OneDriveNameTextbox.ReadOnly = true;\n            this.OneDriveNameTextbox.Size = new System.Drawing.Size(444, 15);\n            this.OneDriveNameTextbox.TabIndex = 2;\n            this.OneDriveNameTextbox.Text = \"?\";\n            // \n            // CloseButton\n            // \n            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;\n            this.CloseButton.Location = new System.Drawing.Point(572, 333);\n            this.CloseButton.Margin = new System.Windows.Forms.Padding(4);\n            this.CloseButton.Name = \"CloseButton\";\n            this.CloseButton.Size = new System.Drawing.Size(132, 41);\n            this.CloseButton.TabIndex = 1;\n            this.CloseButton.Text = \"&Close\";\n            this.CloseButton.UseVisualStyleBackColor = true;\n            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);\n            // \n            // DeleteButton\n            // \n            this.DeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.DeleteButton.Location = new System.Drawing.Point(20, 333);\n            this.DeleteButton.Margin = new System.Windows.Forms.Padding(4);\n            this.DeleteButton.Name = \"DeleteButton\";\n            this.DeleteButton.Size = new System.Drawing.Size(132, 41);\n            this.DeleteButton.TabIndex = 13;\n            this.DeleteButton.Text = \"&Delete\";\n            this.DeleteButton.UseVisualStyleBackColor = true;\n            this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click);\n            // \n            // LastSyncedLabel\n            // \n            this.LastSyncedLabel.Location = new System.Drawing.Point(16, 161);\n            this.LastSyncedLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.LastSyncedLabel.Name = \"LastSyncedLabel\";\n            this.LastSyncedLabel.Size = new System.Drawing.Size(236, 20);\n            this.LastSyncedLabel.TabIndex = 14;\n            this.LastSyncedLabel.Text = \"Last synced with {0}:\";\n            this.LastSyncedLabel.UseMnemonic = false;\n            // \n            // LastSyncedTextbox\n            // \n            this.LastSyncedTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.LastSyncedTextbox.BackColor = System.Drawing.SystemColors.Control;\n            this.LastSyncedTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.LastSyncedTextbox.Location = new System.Drawing.Point(260, 161);\n            this.LastSyncedTextbox.Margin = new System.Windows.Forms.Padding(4);\n            this.LastSyncedTextbox.Name = \"LastSyncedTextbox\";\n            this.LastSyncedTextbox.ReadOnly = true;\n            this.LastSyncedTextbox.Size = new System.Drawing.Size(444, 15);\n            this.LastSyncedTextbox.TabIndex = 15;\n            this.LastSyncedTextbox.Text = \"?\";\n            // \n            // LocalKeePassFileHashLabel\n            // \n            this.LocalKeePassFileHashLabel.Location = new System.Drawing.Point(16, 212);\n            this.LocalKeePassFileHashLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.LocalKeePassFileHashLabel.Name = \"LocalKeePassFileHashLabel\";\n            this.LocalKeePassFileHashLabel.Size = new System.Drawing.Size(236, 20);\n            this.LocalKeePassFileHashLabel.TabIndex = 16;\n            this.LocalKeePassFileHashLabel.Text = \"Local KeePass SHA1 hash:\";\n            this.LocalKeePassFileHashLabel.UseMnemonic = false;\n            // \n            // LocalKeePassFileHashTextbox\n            // \n            this.LocalKeePassFileHashTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.LocalKeePassFileHashTextbox.BackColor = System.Drawing.SystemColors.Control;\n            this.LocalKeePassFileHashTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.LocalKeePassFileHashTextbox.Location = new System.Drawing.Point(260, 212);\n            this.LocalKeePassFileHashTextbox.Margin = new System.Windows.Forms.Padding(4);\n            this.LocalKeePassFileHashTextbox.Name = \"LocalKeePassFileHashTextbox\";\n            this.LocalKeePassFileHashTextbox.ReadOnly = true;\n            this.LocalKeePassFileHashTextbox.Size = new System.Drawing.Size(444, 15);\n            this.LocalKeePassFileHashTextbox.TabIndex = 17;\n            this.LocalKeePassFileHashTextbox.Text = \"?\";\n            // \n            // ForceSyncButton\n            // \n            this.ForceSyncButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.ForceSyncButton.Location = new System.Drawing.Point(432, 333);\n            this.ForceSyncButton.Margin = new System.Windows.Forms.Padding(4);\n            this.ForceSyncButton.Name = \"ForceSyncButton\";\n            this.ForceSyncButton.Size = new System.Drawing.Size(132, 41);\n            this.ForceSyncButton.TabIndex = 18;\n            this.ForceSyncButton.Text = \"&Sync Now\";\n            this.ForceSyncButton.UseVisualStyleBackColor = true;\n            this.ForceSyncButton.Click += new System.EventHandler(this.ForceSyncButton_Click);\n            // \n            // LastVerifiedLabel\n            // \n            this.LastVerifiedLabel.Location = new System.Drawing.Point(16, 186);\n            this.LastVerifiedLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.LastVerifiedLabel.Name = \"LastVerifiedLabel\";\n            this.LastVerifiedLabel.Size = new System.Drawing.Size(236, 20);\n            this.LastVerifiedLabel.TabIndex = 19;\n            this.LastVerifiedLabel.Text = \"Last verified with {0}:\";\n            this.LastVerifiedLabel.UseMnemonic = false;\n            // \n            // LastVerifiedTextbox\n            // \n            this.LastVerifiedTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.LastVerifiedTextbox.BackColor = System.Drawing.SystemColors.Control;\n            this.LastVerifiedTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.LastVerifiedTextbox.Location = new System.Drawing.Point(260, 186);\n            this.LastVerifiedTextbox.Margin = new System.Windows.Forms.Padding(4);\n            this.LastVerifiedTextbox.Name = \"LastVerifiedTextbox\";\n            this.LastVerifiedTextbox.ReadOnly = true;\n            this.LastVerifiedTextbox.Size = new System.Drawing.Size(444, 15);\n            this.LastVerifiedTextbox.TabIndex = 20;\n            this.LastVerifiedTextbox.Text = \"?\";\n            // \n            // StatusLabel\n            // \n            this.StatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.StatusLabel.Location = new System.Drawing.Point(160, 333);\n            this.StatusLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.StatusLabel.Name = \"StatusLabel\";\n            this.StatusLabel.Size = new System.Drawing.Size(264, 44);\n            this.StatusLabel.TabIndex = 21;\n            this.StatusLabel.Text = \"Ready\";\n            this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            this.StatusLabel.UseMnemonic = false;\n            // \n            // RefreshTokenStorageTextBox\n            // \n            this.RefreshTokenStorageTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.RefreshTokenStorageTextBox.BackColor = System.Drawing.SystemColors.Control;\n            this.RefreshTokenStorageTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.RefreshTokenStorageTextBox.Location = new System.Drawing.Point(260, 135);\n            this.RefreshTokenStorageTextBox.Margin = new System.Windows.Forms.Padding(4);\n            this.RefreshTokenStorageTextBox.Name = \"RefreshTokenStorageTextBox\";\n            this.RefreshTokenStorageTextBox.ReadOnly = true;\n            this.RefreshTokenStorageTextBox.Size = new System.Drawing.Size(444, 15);\n            this.RefreshTokenStorageTextBox.TabIndex = 22;\n            this.RefreshTokenStorageTextBox.Text = \"?\";\n            // \n            // RefreshTokenStorageLabel\n            // \n            this.RefreshTokenStorageLabel.Location = new System.Drawing.Point(16, 135);\n            this.RefreshTokenStorageLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.RefreshTokenStorageLabel.Name = \"RefreshTokenStorageLabel\";\n            this.RefreshTokenStorageLabel.Size = new System.Drawing.Size(236, 20);\n            this.RefreshTokenStorageLabel.TabIndex = 23;\n            this.RefreshTokenStorageLabel.Text = \"Refresh Token Storage:\";\n            this.RefreshTokenStorageLabel.UseMnemonic = false;\n            // \n            // CloudStorageTypeTextBox\n            // \n            this.CloudStorageTypeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloudStorageTypeTextBox.BackColor = System.Drawing.SystemColors.Control;\n            this.CloudStorageTypeTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.CloudStorageTypeTextBox.Location = new System.Drawing.Point(260, 34);\n            this.CloudStorageTypeTextBox.Margin = new System.Windows.Forms.Padding(4);\n            this.CloudStorageTypeTextBox.Name = \"CloudStorageTypeTextBox\";\n            this.CloudStorageTypeTextBox.ReadOnly = true;\n            this.CloudStorageTypeTextBox.Size = new System.Drawing.Size(444, 15);\n            this.CloudStorageTypeTextBox.TabIndex = 25;\n            this.CloudStorageTypeTextBox.Text = \"?\";\n            // \n            // CloudStorageTypeLabel\n            // \n            this.CloudStorageTypeLabel.Location = new System.Drawing.Point(16, 34);\n            this.CloudStorageTypeLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.CloudStorageTypeLabel.Name = \"CloudStorageTypeLabel\";\n            this.CloudStorageTypeLabel.Size = new System.Drawing.Size(236, 20);\n            this.CloudStorageTypeLabel.TabIndex = 24;\n            this.CloudStorageTypeLabel.Text = \"Cloud storage type:\";\n            this.CloudStorageTypeLabel.UseMnemonic = false;\n            // \n            // OneDriveEtagTextBox\n            // \n            this.OneDriveEtagTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.OneDriveEtagTextBox.BackColor = System.Drawing.SystemColors.Control;\n            this.OneDriveEtagTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.OneDriveEtagTextBox.Location = new System.Drawing.Point(260, 238);\n            this.OneDriveEtagTextBox.Margin = new System.Windows.Forms.Padding(4);\n            this.OneDriveEtagTextBox.Name = \"OneDriveEtagTextBox\";\n            this.OneDriveEtagTextBox.ReadOnly = true;\n            this.OneDriveEtagTextBox.Size = new System.Drawing.Size(444, 15);\n            this.OneDriveEtagTextBox.TabIndex = 27;\n            this.OneDriveEtagTextBox.Text = \"?\";\n            // \n            // OneDriveEtagLabel\n            // \n            this.OneDriveEtagLabel.Location = new System.Drawing.Point(16, 238);\n            this.OneDriveEtagLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.OneDriveEtagLabel.Name = \"OneDriveEtagLabel\";\n            this.OneDriveEtagLabel.Size = new System.Drawing.Size(236, 20);\n            this.OneDriveEtagLabel.TabIndex = 26;\n            this.OneDriveEtagLabel.Text = \"ETag:\";\n            this.OneDriveEtagLabel.UseMnemonic = false;\n            // \n            // LocalDatabasePathLinkLabel\n            // \n            this.LocalDatabasePathLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.LocalDatabasePathLinkLabel.Location = new System.Drawing.Point(257, 58);\n            this.LocalDatabasePathLinkLabel.Name = \"LocalDatabasePathLinkLabel\";\n            this.LocalDatabasePathLinkLabel.Size = new System.Drawing.Size(447, 20);\n            this.LocalDatabasePathLinkLabel.TabIndex = 28;\n            this.LocalDatabasePathLinkLabel.TabStop = true;\n            this.LocalDatabasePathLinkLabel.Text = \"?\";\n            this.LocalDatabasePathLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LocalDatabasePathLinkLabel_LinkClicked);\n            // \n            // ItemIdTextBox\n            // \n            this.ItemIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ItemIdTextBox.BackColor = System.Drawing.SystemColors.Control;\n            this.ItemIdTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.ItemIdTextBox.Location = new System.Drawing.Point(260, 261);\n            this.ItemIdTextBox.Margin = new System.Windows.Forms.Padding(4);\n            this.ItemIdTextBox.Name = \"ItemIdTextBox\";\n            this.ItemIdTextBox.ReadOnly = true;\n            this.ItemIdTextBox.Size = new System.Drawing.Size(444, 15);\n            this.ItemIdTextBox.TabIndex = 30;\n            this.ItemIdTextBox.Text = \"?\";\n            this.ItemIdTextBox.TextChanged += new System.EventHandler(this.ItemIdTextBox_TextChanged);\n            // \n            // ItemIdLabel\n            // \n            this.ItemIdLabel.Location = new System.Drawing.Point(17, 261);\n            this.ItemIdLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.ItemIdLabel.Name = \"ItemIdLabel\";\n            this.ItemIdLabel.Size = new System.Drawing.Size(236, 20);\n            this.ItemIdLabel.TabIndex = 29;\n            this.ItemIdLabel.Text = \"Item Id:\";\n            this.ItemIdLabel.UseMnemonic = false;\n            this.ItemIdLabel.Click += new System.EventHandler(this.ItemIdLabel_Click);\n            // \n            // FolderIdTextBox\n            // \n            this.FolderIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.FolderIdTextBox.BackColor = System.Drawing.SystemColors.Control;\n            this.FolderIdTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.FolderIdTextBox.Location = new System.Drawing.Point(259, 284);\n            this.FolderIdTextBox.Margin = new System.Windows.Forms.Padding(4);\n            this.FolderIdTextBox.Name = \"FolderIdTextBox\";\n            this.FolderIdTextBox.ReadOnly = true;\n            this.FolderIdTextBox.Size = new System.Drawing.Size(444, 15);\n            this.FolderIdTextBox.TabIndex = 32;\n            this.FolderIdTextBox.Text = \"?\";\n            // \n            // FolderIdLabel\n            // \n            this.FolderIdLabel.Location = new System.Drawing.Point(16, 284);\n            this.FolderIdLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.FolderIdLabel.Name = \"FolderIdLabel\";\n            this.FolderIdLabel.Size = new System.Drawing.Size(236, 20);\n            this.FolderIdLabel.TabIndex = 31;\n            this.FolderIdLabel.Text = \"Folder Id:\";\n            this.FolderIdLabel.UseMnemonic = false;\n            // \n            // DriveIdTextBox\n            // \n            this.DriveIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.DriveIdTextBox.BackColor = System.Drawing.SystemColors.Control;\n            this.DriveIdTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.DriveIdTextBox.Location = new System.Drawing.Point(259, 307);\n            this.DriveIdTextBox.Margin = new System.Windows.Forms.Padding(4);\n            this.DriveIdTextBox.Name = \"DriveIdTextBox\";\n            this.DriveIdTextBox.ReadOnly = true;\n            this.DriveIdTextBox.Size = new System.Drawing.Size(444, 15);\n            this.DriveIdTextBox.TabIndex = 34;\n            this.DriveIdTextBox.Text = \"?\";\n            // \n            // DriveIdLabel\n            // \n            this.DriveIdLabel.Location = new System.Drawing.Point(16, 307);\n            this.DriveIdLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.DriveIdLabel.Name = \"DriveIdLabel\";\n            this.DriveIdLabel.Size = new System.Drawing.Size(236, 20);\n            this.DriveIdLabel.TabIndex = 33;\n            this.DriveIdLabel.Text = \"Drive Id:\";\n            this.DriveIdLabel.UseMnemonic = false;\n            // \n            // OneDriveConfigDetailsForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.CancelButton = this.CloseButton;\n            this.ClientSize = new System.Drawing.Size(720, 388);\n            this.Controls.Add(this.StatusLabel);\n            this.Controls.Add(this.ForceSyncButton);\n            this.Controls.Add(this.DeleteButton);\n            this.Controls.Add(this.CloseButton);\n            this.Controls.Add(this.DriveIdTextBox);\n            this.Controls.Add(this.DriveIdLabel);\n            this.Controls.Add(this.FolderIdTextBox);\n            this.Controls.Add(this.FolderIdLabel);\n            this.Controls.Add(this.ItemIdTextBox);\n            this.Controls.Add(this.ItemIdLabel);\n            this.Controls.Add(this.LocalDatabasePathLinkLabel);\n            this.Controls.Add(this.OneDriveEtagTextBox);\n            this.Controls.Add(this.OneDriveEtagLabel);\n            this.Controls.Add(this.CloudStorageTypeTextBox);\n            this.Controls.Add(this.CloudStorageTypeLabel);\n            this.Controls.Add(this.RefreshTokenStorageTextBox);\n            this.Controls.Add(this.RefreshTokenStorageLabel);\n            this.Controls.Add(this.LastVerifiedTextbox);\n            this.Controls.Add(this.LastVerifiedLabel);\n            this.Controls.Add(this.LocalKeePassFileHashTextbox);\n            this.Controls.Add(this.LocalKeePassFileHashLabel);\n            this.Controls.Add(this.LastSyncedTextbox);\n            this.Controls.Add(this.LastSyncedLabel);\n            this.Controls.Add(this.OneDriveNameTextbox);\n            this.Controls.Add(this.OneDriveRefreshTokenTextbox);\n            this.Controls.Add(this.RemoteKeePassPathTextbox);\n            this.Controls.Add(this.OneDriveRefreshTokenLabel);\n            this.Controls.Add(this.RemoteKeePassPathLabel);\n            this.Controls.Add(this.LocalKeePassPathLabel);\n            this.Controls.Add(this.LocationNameLabel);\n            this.KeyPreview = true;\n            this.Margin = new System.Windows.Forms.Padding(4);\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(680, 278);\n            this.Name = \"OneDriveConfigDetailsForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"OneDriveSync Configuration\";\n            this.Load += new System.EventHandler(this.OneDriveConfigDetailsForm_Load);\n            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OneDriveConfigDetailsForm_KeyUp);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label LocationNameLabel;\n        private System.Windows.Forms.Label LocalKeePassPathLabel;\n        private System.Windows.Forms.Label RemoteKeePassPathLabel;\n        private System.Windows.Forms.Label OneDriveRefreshTokenLabel;\n        private System.Windows.Forms.TextBox RemoteKeePassPathTextbox;\n        private System.Windows.Forms.TextBox OneDriveRefreshTokenTextbox;\n        private System.Windows.Forms.TextBox OneDriveNameTextbox;\n        private System.Windows.Forms.Button CloseButton;\n        private System.Windows.Forms.Button DeleteButton;\n        private System.Windows.Forms.Label LastSyncedLabel;\n        private System.Windows.Forms.TextBox LastSyncedTextbox;\n        private System.Windows.Forms.Label LocalKeePassFileHashLabel;\n        private System.Windows.Forms.TextBox LocalKeePassFileHashTextbox;\n        private System.Windows.Forms.Button ForceSyncButton;\n        private System.Windows.Forms.Label LastVerifiedLabel;\n        private System.Windows.Forms.TextBox LastVerifiedTextbox;\n        private System.Windows.Forms.Label StatusLabel;\n        private System.Windows.Forms.TextBox RefreshTokenStorageTextBox;\n        private System.Windows.Forms.Label RefreshTokenStorageLabel;\n        private System.Windows.Forms.TextBox CloudStorageTypeTextBox;\n        private System.Windows.Forms.Label CloudStorageTypeLabel;\n        private System.Windows.Forms.TextBox OneDriveEtagTextBox;\n        private System.Windows.Forms.Label OneDriveEtagLabel;\n        private System.Windows.Forms.LinkLabel LocalDatabasePathLinkLabel;\n        private System.Windows.Forms.TextBox ItemIdTextBox;\n        private System.Windows.Forms.Label ItemIdLabel;\n        private System.Windows.Forms.TextBox FolderIdTextBox;\n        private System.Windows.Forms.Label FolderIdLabel;\n        private System.Windows.Forms.TextBox DriveIdTextBox;\n        private System.Windows.Forms.Label DriveIdLabel;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    /// <summary>\n    /// Detail screen for a OneDriveSync configuration\n    /// </summary>\n    public partial class OneDriveConfigDetailsForm : Form\n    {\n        private KeyValuePair<string, Configuration> _configuration;\n\n        /// <summary>\n        /// Opens the configuration details screen for the provided configuration\n        /// </summary>\n        /// <param name=\"configuration\"></param>\n        public OneDriveConfigDetailsForm(KeyValuePair<string, Configuration> configuration)\n        {\n            InitializeComponent();\n\n            _configuration = configuration;\n        }\n\n        private void OneDriveConfigDetailsForm_Load(object sender, EventArgs e)\n        {\n            ShowConfiguration();\n        }\n\n        private void ShowConfiguration()\n        {\n            LocationNameLabel.Text = _configuration.Value.CloudStorageType == CloudStorageType.SharePoint ? \"SharePoint site:\" : \"OneDrive name:\";\n            LastSyncedLabel.Text = string.Format(LastSyncedLabel.Text, _configuration.Value.CloudStorageType);\n            LastVerifiedLabel.Text = string.Format(LastVerifiedLabel.Text, _configuration.Value.CloudStorageType);\n            OneDriveNameTextbox.Text = _configuration.Value.DoNotSync ? \"Not enabled for sync\" : _configuration.Value.CloudStorageType == CloudStorageType.SharePoint ? _configuration.Value.RemoteDatabasePath + (string.IsNullOrEmpty(_configuration.Value.OneDriveName) ? \"\" : \" (\" + _configuration.Value.OneDriveName + \")\") : _configuration.Value.OneDriveName;\n            CloudStorageTypeTextBox.Text = _configuration.Value.CloudStorageType.GetValueOrDefault(CloudStorageType.OneDriveConsumer).ToString();\n            LocalDatabasePathLinkLabel.Text = _configuration.Key;\n            LocalDatabasePathLinkLabel.LinkColor = System.IO.File.Exists(_configuration.Key) ? System.Drawing.Color.Blue : System.Drawing.Color.Red;\n            RemoteKeePassPathTextbox.Text = _configuration.Value.CloudStorageType == CloudStorageType.SharePoint ? _configuration.Value.RemoteFolderId + \"/\" + _configuration.Value.RemoteFileName : _configuration.Value.RemoteDatabasePath;\n            OneDriveRefreshTokenTextbox.Text = _configuration.Value.RefreshToken;\n            RefreshTokenStorageTextBox.Text = _configuration.Value.RefreshTokenStorage.ToString();\n            LastSyncedTextbox.Text = _configuration.Value.LastSyncedAt.HasValue ? _configuration.Value.LastSyncedAt.Value.ToString(\"dddd d MMMM yyyy HH:mm:ss\") : \"Never synced yet\";\n            LastVerifiedTextbox.Text = _configuration.Value.LastCheckedAt.HasValue ? _configuration.Value.LastCheckedAt.Value.ToString(\"dddd d MMMM yyyy HH:mm:ss\") : \"Never verified yet\";\n            LocalKeePassFileHashTextbox.Text = _configuration.Value.LocalFileHash;\n            OneDriveEtagTextBox.Text = _configuration.Value.ETag;\n            ForceSyncButton.Enabled = !_configuration.Value.DoNotSync;\n            ItemIdTextBox.Text = _configuration.Value.RemoteItemId;\n            FolderIdTextBox.Text = _configuration.Value.RemoteFolderId;\n            DriveIdTextBox.Text = _configuration.Value.RemoteDriveId;\n        }\n\n        private void CloseButton_Click(object sender, EventArgs e)\n        {\n            Close();\n        }\n\n        private void DeleteButton_Click(object sender, EventArgs e)\n        {\n            var answer = MessageBox.Show(\"Are you sure that you wish to delete the OneDrive configuration for the selected KeePass databases? This will NOT delete the actual KeePass database file, just its configuration for the KeeOneDriveSync plugin.\", \"Confirm removal\", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);\n            if (answer != DialogResult.Yes) return;\n\n            Configuration.DeleteConfig(_configuration.Key);\n\n            Close();\n        }\n\n        private async void ForceSyncButton_Click(object sender, EventArgs e)\n        {\n            if(_configuration.Value.KeePassDatabase == null)\n            {\n                UpdateStatus(\"Database must be open before it can synchronize\");\n                return;\n            }\n\n            UpdateStatus(\"Synchronizing\");\n            await KeePassDatabase.SyncDatabase(_configuration.Key, UpdateStatus, true, null);\n            ShowConfiguration();\n        }\n\n        private void UpdateStatus(string message)\n        {\n            StatusLabel.Text = message;\n        }\n\n        private void OneDriveConfigDetailsForm_KeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.F5)\n            {\n                ShowConfiguration();\n            }\n        }\n\n        private void LocalDatabasePathLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            if(System.IO.File.Exists(LocalDatabasePathLinkLabel.Text))\n            {\n                // File still exists locally, open explorer and have it highlight the file\n                System.Diagnostics.Process.Start(\"explorer.exe\", \"/select, \\\"\" + LocalDatabasePathLinkLabel.Text + \"\\\"\");\n                return;\n            }\n\n            // Check if the parent directory still exists \n            var fileInfo = new System.IO.FileInfo(LocalDatabasePathLinkLabel.Text);\n            if (System.IO.Directory.Exists(fileInfo.Directory.FullName))\n            {\n                // Parent directory still exists, open explorer in that folder\n                System.Diagnostics.Process.Start(\"explorer.exe\", \"\\\"\" + fileInfo.Directory.FullName + \"\\\"\");\n                return;\n            }\n\n            // Both the file and the parent folder no longer exist, nothing we can do\n        }\n\n        private void ItemIdLabel_Click(object sender, EventArgs e)\n        {\n\n        }\n\n        private void ItemIdTextBox_TextChanged(object sender, EventArgs e)\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveConfigForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.HeaderLabel = new System.Windows.Forms.Label();\n            this.ConfigurationListView = new System.Windows.Forms.ListView();\n            this.PathColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\n            this.StorageNameColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\n            this.StorageProviderColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\n            this.LastSyncedColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));\n            this.ConfigurationListViewContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);\n            this.ConfigurationListViewContextItemViewDetails = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemRenameStorage = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSyncNow = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemOpenFileLocation = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemDelete = new System.Windows.Forms.ToolStripMenuItem();\n            this.CloseButton = new System.Windows.Forms.Button();\n            this.StatusLabel = new System.Windows.Forms.Label();\n            this.AboutButton = new System.Windows.Forms.Button();\n            this.ConfigurationListViewContextItemOpenDatabase = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();\n            this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();\n            this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();\n            this.ConfigurationListViewContextItemRefresh = new System.Windows.Forms.ToolStripMenuItem();\n            this.selectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSelectAll = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSelectNotAvailableLocally = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSelectNotSynced = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSelectNotSynced24Hours = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSelectNotSyncedWeek = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSelectNotSynced2Weeks = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextItemSelectNotSyncedMonth = new System.Windows.Forms.ToolStripMenuItem();\n            this.ConfigurationListViewContextMenu.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(13, 36);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(433, 31);\n            this.ExplanationLabel.TabIndex = 0;\n            this.ExplanationLabel.Text = \"Here you\\'ll see all KeePass databases that are configured for use with OneDriveSy\" +\n    \"nc.\";\n            this.ExplanationLabel.UseMnemonic = false;\n            // \n            // HeaderLabel\n            // \n            this.HeaderLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.HeaderLabel.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.HeaderLabel.Location = new System.Drawing.Point(12, 9);\n            this.HeaderLabel.Name = \"HeaderLabel\";\n            this.HeaderLabel.Size = new System.Drawing.Size(434, 23);\n            this.HeaderLabel.TabIndex = 1;\n            this.HeaderLabel.Text = \"KeePass OneDriveSync\";\n            this.HeaderLabel.UseMnemonic = false;\n            // \n            // ConfigurationListView\n            // \n            this.ConfigurationListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ConfigurationListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {\n            this.PathColumn,\n            this.StorageNameColumn,\n            this.StorageProviderColumn,\n            this.LastSyncedColumn});\n            this.ConfigurationListView.ContextMenuStrip = this.ConfigurationListViewContextMenu;\n            this.ConfigurationListView.FullRowSelect = true;\n            this.ConfigurationListView.GridLines = true;\n            this.ConfigurationListView.HideSelection = false;\n            this.ConfigurationListView.Location = new System.Drawing.Point(15, 55);\n            this.ConfigurationListView.Name = \"ConfigurationListView\";\n            this.ConfigurationListView.Size = new System.Drawing.Size(430, 219);\n            this.ConfigurationListView.TabIndex = 3;\n            this.ConfigurationListView.UseCompatibleStateImageBehavior = false;\n            this.ConfigurationListView.View = System.Windows.Forms.View.Details;\n            this.ConfigurationListView.DoubleClick += new System.EventHandler(this.ConfigurationListView_DoubleClick);\n            this.ConfigurationListView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ConfigurationListView_KeyUp);\n            // \n            // PathColumn\n            // \n            this.PathColumn.Text = \"Local Path\";\n            this.PathColumn.Width = 275;\n            // \n            // StorageNameColumn\n            // \n            this.StorageNameColumn.Text = \"Storage Name\";\n            this.StorageNameColumn.Width = 150;\n            // \n            // StorageProviderColumn\n            // \n            this.StorageProviderColumn.Text = \"Storage Provider\";\n            this.StorageProviderColumn.Width = 175;\n            // \n            // LastSyncedColumn\n            // \n            this.LastSyncedColumn.Text = \"Last Synced\";\n            this.LastSyncedColumn.Width = 175;\n            // \n            // ConfigurationListViewContextMenu\n            // \n            this.ConfigurationListViewContextMenu.ImageScalingSize = new System.Drawing.Size(20, 20);\n            this.ConfigurationListViewContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.ConfigurationListViewContextItemViewDetails,\n            this.ConfigurationListViewContextItemRenameStorage,\n            this.ConfigurationListViewContextItemDelete,\n            this.toolStripMenuItem2,\n            this.ConfigurationListViewContextItemSyncNow,\n            this.toolStripMenuItem1,\n            this.selectToolStripMenuItem,\n            this.ConfigurationListViewContextItemRefresh,\n            this.toolStripMenuItem3,\n            this.ConfigurationListViewContextItemOpenFileLocation,\n            this.ConfigurationListViewContextItemOpenDatabase});\n            this.ConfigurationListViewContextMenu.Name = \"ConfigurationListViewContextMenu\";\n            this.ConfigurationListViewContextMenu.Size = new System.Drawing.Size(218, 198);\n            this.ConfigurationListViewContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ConfigurationListViewContextMenu_Opening);\n            // \n            // ConfigurationListViewContextItemViewDetails\n            // \n            this.ConfigurationListViewContextItemViewDetails.Name = \"ConfigurationListViewContextItemViewDetails\";\n            this.ConfigurationListViewContextItemViewDetails.ShortcutKeys = System.Windows.Forms.Keys.F1;\n            this.ConfigurationListViewContextItemViewDetails.Size = new System.Drawing.Size(217, 22);\n            this.ConfigurationListViewContextItemViewDetails.Text = \"&View details\";\n            this.ConfigurationListViewContextItemViewDetails.Click += new System.EventHandler(this.ConfigurationListViewContextItemViewDetails_Click);\n            // \n            // ConfigurationListViewContextItemRenameStorage\n            // \n            this.ConfigurationListViewContextItemRenameStorage.Name = \"ConfigurationListViewContextItemRenameStorage\";\n            this.ConfigurationListViewContextItemRenameStorage.ShortcutKeys = System.Windows.Forms.Keys.F2;\n            this.ConfigurationListViewContextItemRenameStorage.Size = new System.Drawing.Size(217, 22);\n            this.ConfigurationListViewContextItemRenameStorage.Text = \"&Rename storage\";\n            this.ConfigurationListViewContextItemRenameStorage.Click += new System.EventHandler(this.ConfigurationListViewContextItemRenameStorage_Click);\n            // \n            // ConfigurationListViewContextItemSyncNow\n            // \n            this.ConfigurationListViewContextItemSyncNow.Name = \"ConfigurationListViewContextItemSyncNow\";\n            this.ConfigurationListViewContextItemSyncNow.ShortcutKeys = System.Windows.Forms.Keys.F4;\n            this.ConfigurationListViewContextItemSyncNow.Size = new System.Drawing.Size(217, 22);\n            this.ConfigurationListViewContextItemSyncNow.Text = \"&Sync Now\";\n            this.ConfigurationListViewContextItemSyncNow.Click += new System.EventHandler(this.ConfigurationListViewContextItemSyncNow_Click);\n            // \n            // ConfigurationListViewContextItemOpenFileLocation\n            // \n            this.ConfigurationListViewContextItemOpenFileLocation.Name = \"ConfigurationListViewContextItemOpenFileLocation\";\n            this.ConfigurationListViewContextItemOpenFileLocation.ShortcutKeys = System.Windows.Forms.Keys.F7;\n            this.ConfigurationListViewContextItemOpenFileLocation.Size = new System.Drawing.Size(217, 22);\n            this.ConfigurationListViewContextItemOpenFileLocation.Text = \"Open file &location\";\n            this.ConfigurationListViewContextItemOpenFileLocation.Click += new System.EventHandler(this.ConfigurationListViewContextItemOpenFileLocation_Click);\n            // \n            // ConfigurationListViewContextItemDelete\n            // \n            this.ConfigurationListViewContextItemDelete.Name = \"ConfigurationListViewContextItemDelete\";\n            this.ConfigurationListViewContextItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete;\n            this.ConfigurationListViewContextItemDelete.Size = new System.Drawing.Size(217, 22);\n            this.ConfigurationListViewContextItemDelete.Text = \"&Delete configuration\";\n            this.ConfigurationListViewContextItemDelete.Click += new System.EventHandler(this.ConfigurationListViewContextItemDelete_Click);\n            // \n            // CloseButton\n            // \n            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;\n            this.CloseButton.Location = new System.Drawing.Point(347, 280);\n            this.CloseButton.Name = \"CloseButton\";\n            this.CloseButton.Size = new System.Drawing.Size(99, 33);\n            this.CloseButton.TabIndex = 4;\n            this.CloseButton.Text = \"&Close\";\n            this.CloseButton.UseVisualStyleBackColor = true;\n            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);\n            // \n            // StatusLabel\n            // \n            this.StatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.StatusLabel.Location = new System.Drawing.Point(13, 280);\n            this.StatusLabel.Name = \"StatusLabel\";\n            this.StatusLabel.Size = new System.Drawing.Size(223, 33);\n            this.StatusLabel.TabIndex = 5;\n            this.StatusLabel.Text = \"-\";\n            this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;\n            this.StatusLabel.UseMnemonic = false;\n            // \n            // AboutButton\n            // \n            this.AboutButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.AboutButton.Location = new System.Drawing.Point(242, 280);\n            this.AboutButton.Name = \"AboutButton\";\n            this.AboutButton.Size = new System.Drawing.Size(99, 33);\n            this.AboutButton.TabIndex = 6;\n            this.AboutButton.Text = \"&About\";\n            this.AboutButton.UseVisualStyleBackColor = true;\n            this.AboutButton.Click += new System.EventHandler(this.AboutButton_Click);\n            // \n            // ConfigurationListViewContextItemOpenDatabase\n            // \n            this.ConfigurationListViewContextItemOpenDatabase.Name = \"ConfigurationListViewContextItemOpenDatabase\";\n            this.ConfigurationListViewContextItemOpenDatabase.ShortcutKeys = System.Windows.Forms.Keys.F8;\n            this.ConfigurationListViewContextItemOpenDatabase.Size = new System.Drawing.Size(217, 22);\n            this.ConfigurationListViewContextItemOpenDatabase.Text = \"Open &KeePass database\";\n            this.ConfigurationListViewContextItemOpenDatabase.Click += new System.EventHandler(this.ConfigurationListViewContextItemOpenDatabase_Click);\n            // \n            // toolStripMenuItem1\n            // \n            this.toolStripMenuItem1.Name = \"toolStripMenuItem1\";\n            this.toolStripMenuItem1.Size = new System.Drawing.Size(214, 6);\n            // \n            // toolStripMenuItem2\n            // \n            this.toolStripMenuItem2.Name = \"toolStripMenuItem2\";\n            this.toolStripMenuItem2.Size = new System.Drawing.Size(214, 6);\n            // \n            // toolStripMenuItem3\n            // \n            this.toolStripMenuItem3.Name = \"toolStripMenuItem3\";\n            this.toolStripMenuItem3.Size = new System.Drawing.Size(214, 6);\n            // \n            // ConfigurationListViewContextItemRefresh\n            // \n            this.ConfigurationListViewContextItemRefresh.Name = \"ConfigurationListViewContextItemRefresh\";\n            this.ConfigurationListViewContextItemRefresh.ShortcutKeys = System.Windows.Forms.Keys.F5;\n            this.ConfigurationListViewContextItemRefresh.Size = new System.Drawing.Size(217, 22);\n            this.ConfigurationListViewContextItemRefresh.Text = \"Refresh &list\";\n            this.ConfigurationListViewContextItemRefresh.Click += new System.EventHandler(this.ConfigurationListViewContextItemRefresh_Click);\n            // \n            // selectToolStripMenuItem\n            // \n            this.selectToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.ConfigurationListViewContextItemSelectAll,\n            this.ConfigurationListViewContextItemSelectNotAvailableLocally,\n            this.ConfigurationListViewContextItemSelectNotSynced});\n            this.selectToolStripMenuItem.Name = \"selectToolStripMenuItem\";\n            this.selectToolStripMenuItem.Size = new System.Drawing.Size(217, 22);\n            this.selectToolStripMenuItem.Text = \"S&elect\";\n            // \n            // ConfigurationListViewContextItemSelectAll\n            // \n            this.ConfigurationListViewContextItemSelectAll.Name = \"ConfigurationListViewContextItemSelectAll\";\n            this.ConfigurationListViewContextItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));\n            this.ConfigurationListViewContextItemSelectAll.Size = new System.Drawing.Size(254, 22);\n            this.ConfigurationListViewContextItemSelectAll.Text = \"&All\";\n            this.ConfigurationListViewContextItemSelectAll.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectAll_Click);\n            // \n            // ConfigurationListViewContextItemSelectNotAvailableLocally\n            // \n            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Name = \"ConfigurationListViewContextItemSelectNotAvailableLocally\";\n            this.ConfigurationListViewContextItemSelectNotAvailableLocally.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) \n            | System.Windows.Forms.Keys.A)));\n            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Size = new System.Drawing.Size(254, 22);\n            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Text = \"&Not available locally\";\n            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotAvailableLocally_Click);\n            // \n            // ConfigurationListViewContextItemSelectNotSynced\n            // \n            this.ConfigurationListViewContextItemSelectNotSynced.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.ConfigurationListViewContextItemSelectNotSynced24Hours,\n            this.ConfigurationListViewContextItemSelectNotSyncedWeek,\n            this.ConfigurationListViewContextItemSelectNotSynced2Weeks,\n            this.ConfigurationListViewContextItemSelectNotSyncedMonth});\n            this.ConfigurationListViewContextItemSelectNotSynced.Name = \"ConfigurationListViewContextItemSelectNotSynced\";\n            this.ConfigurationListViewContextItemSelectNotSynced.Size = new System.Drawing.Size(254, 22);\n            this.ConfigurationListViewContextItemSelectNotSynced.Text = \"Not synced in the &past...\";\n            // \n            // ConfigurationListViewContextItemSelectNotSynced24Hours\n            // \n            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Name = \"ConfigurationListViewContextItemSelectNotSynced24Hours\";\n            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Size = new System.Drawing.Size(180, 22);\n            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Text = \"24 &hours\";\n            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSynced24Hours_Click);\n            // \n            // ConfigurationListViewContextItemSelectNotSyncedWeek\n            // \n            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Name = \"ConfigurationListViewContextItemSelectNotSyncedWeek\";\n            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Size = new System.Drawing.Size(180, 22);\n            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Text = \"&Week\";\n            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSyncedWeek_Click);\n            // \n            // ConfigurationListViewContextItemSelectNotSynced2Weeks\n            // \n            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Name = \"ConfigurationListViewContextItemSelectNotSynced2Weeks\";\n            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Size = new System.Drawing.Size(180, 22);\n            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Text = \"&2 Weeks\";\n            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSynced2Weeks_Click);\n            // \n            // ConfigurationListViewContextItemSelectNotSyncedMonth\n            // \n            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Name = \"ConfigurationListViewContextItemSelectNotSyncedMonth\";\n            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Size = new System.Drawing.Size(180, 22);\n            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Text = \"&Month\";\n            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSyncedMonth_Click);\n            // \n            // OneDriveConfigForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.CancelButton = this.CloseButton;\n            this.ClientSize = new System.Drawing.Size(458, 325);\n            this.Controls.Add(this.AboutButton);\n            this.Controls.Add(this.StatusLabel);\n            this.Controls.Add(this.CloseButton);\n            this.Controls.Add(this.ConfigurationListView);\n            this.Controls.Add(this.HeaderLabel);\n            this.Controls.Add(this.ExplanationLabel);\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(386, 217);\n            this.Name = \"OneDriveConfigForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"OneDrive Sync Configuration\";\n            this.Load += new System.EventHandler(this.OneDriveConfigForm_Load);\n            this.ConfigurationListViewContextMenu.ResumeLayout(false);\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.Label HeaderLabel;\n        private System.Windows.Forms.ListView ConfigurationListView;\n        private System.Windows.Forms.Button CloseButton;\n        private System.Windows.Forms.ColumnHeader PathColumn;\n        private System.Windows.Forms.ColumnHeader StorageNameColumn;\n        private System.Windows.Forms.ContextMenuStrip ConfigurationListViewContextMenu;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemDelete;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemViewDetails;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSyncNow;\n        private System.Windows.Forms.Label StatusLabel;\n        private System.Windows.Forms.Button AboutButton;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemOpenFileLocation;\n        private System.Windows.Forms.CheckBox UseSystemProxyCheckBox;\n        private System.Windows.Forms.ColumnHeader StorageProviderColumn;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemRenameStorage;\n        private System.Windows.Forms.ColumnHeader LastSyncedColumn;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemOpenDatabase;\n        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;\n        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;\n        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemRefresh;\n        private System.Windows.Forms.ToolStripMenuItem selectToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectAll;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotAvailableLocally;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSynced;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSynced24Hours;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSyncedWeek;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSynced2Weeks;\n        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSyncedMonth;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing KeePassLib.Serialization;\nusing KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partial class OneDriveConfigForm : Form\n    {\n        /// <summary>\n        /// Timer that resets any other status back to the default after a few seconds\n        /// </summary>\n        private readonly Timer _resetStatusTimer;\n\n        /// <summary>\n        /// The default status to show\n        /// </summary>\n        private string _defaultStatus;\n\n        public OneDriveConfigForm()\n        {\n            InitializeComponent();\n\n            _resetStatusTimer = new Timer {Enabled = false, Interval = 10000 };\n            _resetStatusTimer.Tick += (sender, args) => { _resetStatusTimer.Enabled = false; UpdateStatus(_defaultStatus); };\n        }\n\n        private void OneDriveConfigForm_Load(object sender, EventArgs e)\n        {\n            LoadConfigurations();\n        }\n\n        /// <summary>\n        /// Loads the configurations in the listview\n        /// </summary>\n        private void LoadConfigurations()\n        {\n            UpdateStatus(\"Loading configuration\");\n\n            // Clear the existing items\n            ConfigurationListView.Items.Clear();\n\n            var configurations = Configuration.GetAllConfigurations();\n\n            foreach (var configuration in configurations)\n            {\n                var configurationItem = new ListViewItem\n                {\n                    Text = configuration.Key,\n                    Tag = configuration\n                };\n                var doesDatabaseExistLocally = File.Exists(configuration.Key);\n                var isRemoteDatabase = Regex.IsMatch(configuration.Key, @\".+:[\\\\/]{2}.+\", RegexOptions.IgnoreCase);\n                configurationItem.BackColor = doesDatabaseExistLocally ? ConfigurationListView.BackColor : isRemoteDatabase ? Color.Orange : Color.Red;\n                configurationItem.ToolTipText = doesDatabaseExistLocally ? \"Database has been found\" : isRemoteDatabase ? \"Database is a remote database which is not supported\" : \"Database has not been found\"; \n                configurationItem.SubItems.Add(new ListViewItem.ListViewSubItem { Name = \"OneDrive\", Text = configuration.Value.DoNotSync ? \"Not synced\" : configuration.Value.OneDriveName });\n                configurationItem.SubItems.Add(new ListViewItem.ListViewSubItem { Name = \"CloudStorage\", Text = configuration.Value.CloudStorageType.HasValue ? configuration.Value.CloudStorageType.Value.ToString() : configuration.Value.DoNotSync ? \"Not in cloud\" : CloudStorageType.OneDriveConsumer.ToString() });\n                configurationItem.SubItems.Add(new ListViewItem.ListViewSubItem { Name = \"LastSynced\", Text = configuration.Value.LastCheckedAt.HasValue ? configuration.Value.LastCheckedAt.Value.ToString(\"ddd d MMMM yyyy HH:mm:ss\") : \"Never\", Tag = configuration.Value.LastCheckedAt.HasValue ? (DateTime?) configuration.Value.LastCheckedAt.Value : null });\n                ConfigurationListView.Items.Add(configurationItem);\n            }\n\n            _defaultStatus = string.Format(\"{0} configuration{1} found\", ConfigurationListView.Items.Count, ConfigurationListView.Items.Count != 1 ? \"s\" : \"\");\n            UpdateStatus(_defaultStatus);\n        }\n\n        private void CloseButton_Click(object sender, EventArgs e)\n        {\n            \n        }\n\n        private void ConfigurationListViewContextItemDelete_Click(object sender, EventArgs e)\n        {\n            DeleteItem();\n        }\n\n        private void ConfigurationListViewContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)\n        {\n            ConfigurationListViewContextItemDelete.Enabled = ConfigurationListView.SelectedItems.Count > 0;\n            ConfigurationListViewContextItemViewDetails.Enabled = ConfigurationListView.SelectedItems.Count == 1;\n            ConfigurationListViewContextItemOpenFileLocation.Enabled = ConfigurationListView.SelectedItems.Count > 0;\n            ConfigurationListViewContextItemSyncNow.Enabled = ConfigurationListView.SelectedItems.Count > 0;\n            ConfigurationListViewContextItemRenameStorage.Enabled = ConfigurationListView.SelectedItems.Count > 0;\n            ConfigurationListViewContextItemOpenDatabase.Enabled = ConfigurationListView.SelectedItems.Count > 0;\n        }\n\n        private void ConfigurationListView_DoubleClick(object sender, EventArgs e)\n        {\n            ViewDetails();\n        }\n\n        private void ConfigurationListViewContextItemViewDetails_Click(object sender, EventArgs e)\n        {\n            ViewDetails();\n        }\n\n        private void DeleteItem()\n        {\n            if (ConfigurationListView.SelectedItems.Count == 0) return;\n\n            var answer = MessageBox.Show(\"Are you sure that you wish to delete the OneDrive configuration for the selected KeePass databases? This will NOT delete the actual KeePass database file, just its configuration for the KeeOneDriveSync plugin.\", \"Confirm removal\", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);\n            if (answer != DialogResult.Yes) return;\n\n            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)\n            {\n                Configuration.DeleteConfig(((KeyValuePair<string, Configuration>)selectedItem.Tag).Key);\n            }\n\n            LoadConfigurations();\n        }\n\n        private void ViewDetails()\n        {\n            if (ConfigurationListView.SelectedItems.Count != 1) return;\n\n            var oneDriveConfigDetailsForm = new OneDriveConfigDetailsForm((KeyValuePair<string, Configuration>)ConfigurationListView.SelectedItems[0].Tag);\n            oneDriveConfigDetailsForm.ShowDialog();\n\n            LoadConfigurations();\n        }\n\n        private void RenameEntry()\n        {\n            if (ConfigurationListView.SelectedItems.Count == 0) return;\n\n            var selectedDatabaseText = ConfigurationListView.SelectedItems.Count == 1 ? ((KeyValuePair<string, Configuration>)ConfigurationListView.SelectedItems[0].Tag).Value.OneDriveName : string.Format(\"the selected {0} databases\", ConfigurationListView.SelectedItems.Count);\n\n            var renameItemDialog = new Forms.OneDriveRequestInputDialog\n            {\n                FormTitle = string.Format(\"Enter new storage name name for {0}\", selectedDatabaseText),\n                InputValue = ConfigurationListView.SelectedItems.Count == 1 ? ((KeyValuePair<string, Configuration>)ConfigurationListView.SelectedItems[0].Tag).Value.OneDriveName : string.Empty\n            };\n            renameItemDialog.ShowDialog(this);\n            if (renameItemDialog.DialogResult != DialogResult.OK) return;\n\n            // Loop through all selected items to update their names\n            foreach (ListViewItem configurationItem in ConfigurationListView.SelectedItems)\n            {\n                var configuration = (KeyValuePair<string, Configuration>)configurationItem.Tag;\n                \n                // Update the name in the configuration\n                configuration.Value.OneDriveName = renameItemDialog.InputValue;\n\n                // Update the name in the configuration list shown on the screen\n                configurationItem.SubItems[1].Text = renameItemDialog.InputValue;\n            }\n            Configuration.Save();\n\n            UpdateStatus(\"Storage Name has been changed\");\n        }\n\n        private async Task SyncNow()\n        {\n            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)\n            {\n                // Only allow syncing if the database is not marked with the DoNotSync flag\n                var configuration = (KeyValuePair<string, Configuration>)selectedItem.Tag;\n                if (configuration.Value.DoNotSync)\n                {\n                    return;\n                }\n                \n                // Ensure the database to be synced is currently open\n                if(configuration.Value.KeePassDatabase == null)\n                {\n                    UpdateStatus(string.Format(\"Database {0} must be open before it can sync\", configuration.Key));\n                    continue;\n                }\n\n                UpdateStatus(string.Format(\"Synchronizing database {0}\", configuration.Value.KeePassDatabase.Name));\n                await KeePassDatabase.SyncDatabase(selectedItem.Text, UpdateStatus, true, configuration.Value);\n\n                // Update the Last Synced column\n                selectedItem.SubItems[3].Text = configuration.Value.LastCheckedAt.HasValue ? configuration.Value.LastCheckedAt.Value.ToString(\"ddd d MMMM yyyy HH:mm:ss\") : \"Never\";\n                selectedItem.SubItems[3].Tag = configuration.Value.LastCheckedAt.HasValue ? (DateTime?) configuration.Value.LastCheckedAt.Value : null;\n            }\n        }\n\n        private async void ConfigurationListViewContextItemSyncNow_Click(object sender, EventArgs e)\n        {\n            await SyncNow();\n        }\n\n        private void UpdateStatus(string message)\n        {\n            StatusLabel.Text = message;\n\n            // If the status message is not the default message, enable the timer to reset the status back to the default after a few seconds\n            if (_defaultStatus != null && message != _defaultStatus)\n            {\n                _resetStatusTimer.Enabled = true;\n            }\n        }\n\n        private void AboutButton_Click(object sender, EventArgs e)\n        {\n            var oneDriveAboutForm = new OneDriveAboutForm();\n            oneDriveAboutForm.ShowDialog();\n        }\n\n        private void ConfigurationListView_KeyUp(object sender, KeyEventArgs e)\n        {\n\n        }\n\n        private void ConfigurationListViewContextItemOpenFileLocation_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)\n            {\n                // Get the full local path of the selected KeePass database configuration\n                var databaseFileLocation = ((KeyValuePair<string, Configuration>)selectedItem.Tag).Key;\n\n                // Open File Explorer and make it directly jump to the KeePass database if it exists, if not, just open the explorer to the folder\n                Process.Start(\"explorer.exe\", File.Exists(databaseFileLocation) ? string.Concat(\"/select, \", databaseFileLocation) : Directory.GetParent(databaseFileLocation).FullName);\n            }\n        }\n\n        private void ConfigurationListViewContextItemRenameStorage_Click(object sender, EventArgs e)\n        {\n            RenameEntry();\n        }\n\n        private void ConfigurationListViewContextItemOpenDatabase_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)\n            {\n                // Get the full local path of the selected KeePass database configuration\n                var databaseFileLocation = ((KeyValuePair<string, Configuration>)selectedItem.Tag).Key;\n\n                // Open the KeePass database\n                var databaseFile = IOConnectionInfo.FromPath(databaseFileLocation);\n                KoenZomersKeePassOneDriveSyncExt.Host.MainWindow.OpenDatabase(databaseFile, null, false);\n            }\n        }\n\n        private void ConfigurationListViewContextItemRefresh_Click(object sender, EventArgs e)\n        {\n            LoadConfigurations();\n        }\n\n        private void ConfigurationListViewContextItemSelectAll_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in ConfigurationListView.Items)\n            {\n                item.Selected = true;\n            }\n        }\n\n        private void ConfigurationListViewContextItemSelectNotAvailableLocally_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in ConfigurationListView.Items)\n            {\n                item.Selected = item.BackColor == Color.Red;\n            }\n        }\n\n        private void ConfigurationListViewContextItemSelectNotSynced24Hours_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in ConfigurationListView.Items)\n            {\n                var lastChecked = item.SubItems[3].Tag as DateTime?;\n                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddHours(24) < DateTime.Now;\n            }\n        }\n\n        private void ConfigurationListViewContextItemSelectNotSyncedWeek_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in ConfigurationListView.Items)\n            {\n                var lastChecked = item.SubItems[3].Tag as DateTime?;\n                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddDays(7) < DateTime.Now;\n            }\n        }\n\n        private void ConfigurationListViewContextItemSelectNotSynced2Weeks_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in ConfigurationListView.Items)\n            {\n                var lastChecked = item.SubItems[3].Tag as DateTime?;\n                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddDays(14) < DateTime.Now;\n            }\n        }\n\n        private void ConfigurationListViewContextItemSelectNotSyncedMonth_Click(object sender, EventArgs e)\n        {\n            foreach (ListViewItem item in ConfigurationListView.Items)\n            {\n                var lastChecked = item.SubItems[3].Tag as DateTime?;\n                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddMonths(1) < DateTime.Now;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"ConfigurationListViewContextMenu.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class OneDriveFilePickerDialog\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OneDriveFilePickerDialog));\n            this.MyFilesContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);\n            this.refreshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.GoToRootToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.goupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();\n            this.newFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.IconsList = new System.Windows.Forms.ImageList(this.components);\n            this.CancelButton = new System.Windows.Forms.Button();\n            this.OKButton = new System.Windows.Forms.Button();\n            this.UpButton = new System.Windows.Forms.Button();\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.FileNameTextBox = new System.Windows.Forms.TextBox();\n            this.FileNameLabel = new System.Windows.Forms.Label();\n            this.FilesTabControl = new System.Windows.Forms.TabControl();\n            this.MyFilesTabPage = new System.Windows.Forms.TabPage();\n            this.CloudLocationPath = new System.Windows.Forms.TextBox();\n            this.CloudLocationPicker = new System.Windows.Forms.ListView();\n            this.SharedWithMeTabPage = new System.Windows.Forms.TabPage();\n            this.SharedWithMeUpButton = new System.Windows.Forms.Button();\n            this.SharedWithMePath = new System.Windows.Forms.TextBox();\n            this.SharedWithMePicker = new System.Windows.Forms.ListView();\n            this.SharedWithMeContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);\n            this.RefreshSharedWithMeFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.GoToSharedWithMeRootTtoolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.GoUpSharedWithMeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.SharedWithMeNotAvailableLabel = new System.Windows.Forms.Label();\n            this.MyFilesContextMenu.SuspendLayout();\n            this.FilesTabControl.SuspendLayout();\n            this.MyFilesTabPage.SuspendLayout();\n            this.SharedWithMeTabPage.SuspendLayout();\n            this.SharedWithMeContextMenu.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // MyFilesContextMenu\n            // \n            this.MyFilesContextMenu.ImageScalingSize = new System.Drawing.Size(20, 20);\n            this.MyFilesContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.refreshToolStripMenuItem,\n            this.GoToRootToolStripMenuItem,\n            this.goupToolStripMenuItem,\n            this.toolStripMenuItem1,\n            this.newFolderToolStripMenuItem,\n            this.renameToolStripMenuItem,\n            this.deleteToolStripMenuItem});\n            this.MyFilesContextMenu.Name = \"ListViewContextMenu\";\n            this.MyFilesContextMenu.Size = new System.Drawing.Size(239, 202);\n            this.MyFilesContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ListViewContextMenu_Opening);\n            // \n            // refreshToolStripMenuItem\n            // \n            this.refreshToolStripMenuItem.Name = \"refreshToolStripMenuItem\";\n            this.refreshToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5;\n            this.refreshToolStripMenuItem.Size = new System.Drawing.Size(238, 32);\n            this.refreshToolStripMenuItem.Text = \"&Refresh\";\n            this.refreshToolStripMenuItem.Click += new System.EventHandler(this.RefreshToolStripMenuItem_Click);\n            // \n            // GoToRootToolStripMenuItem\n            // \n            this.GoToRootToolStripMenuItem.Name = \"GoToRootToolStripMenuItem\";\n            this.GoToRootToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.H)));\n            this.GoToRootToolStripMenuItem.Size = new System.Drawing.Size(238, 32);\n            this.GoToRootToolStripMenuItem.Text = \"&Go to root\";\n            this.GoToRootToolStripMenuItem.Click += new System.EventHandler(this.GoToRootToolStripMenuItem_Click);\n            // \n            // goupToolStripMenuItem\n            // \n            this.goupToolStripMenuItem.Enabled = false;\n            this.goupToolStripMenuItem.Name = \"goupToolStripMenuItem\";\n            this.goupToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U)));\n            this.goupToolStripMenuItem.Size = new System.Drawing.Size(238, 32);\n            this.goupToolStripMenuItem.Text = \"Go &up\";\n            this.goupToolStripMenuItem.Click += new System.EventHandler(this.GroupToolStripMenuItem_Click);\n            // \n            // toolStripMenuItem1\n            // \n            this.toolStripMenuItem1.Name = \"toolStripMenuItem1\";\n            this.toolStripMenuItem1.Size = new System.Drawing.Size(235, 6);\n            // \n            // newFolderToolStripMenuItem\n            // \n            this.newFolderToolStripMenuItem.Name = \"newFolderToolStripMenuItem\";\n            this.newFolderToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));\n            this.newFolderToolStripMenuItem.Size = new System.Drawing.Size(238, 32);\n            this.newFolderToolStripMenuItem.Text = \"&New Folder\";\n            this.newFolderToolStripMenuItem.Click += new System.EventHandler(this.NewFolderToolStripMenuItem_Click);\n            // \n            // renameToolStripMenuItem\n            // \n            this.renameToolStripMenuItem.Name = \"renameToolStripMenuItem\";\n            this.renameToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));\n            this.renameToolStripMenuItem.Size = new System.Drawing.Size(238, 32);\n            this.renameToolStripMenuItem.Text = \"R&ename\";\n            this.renameToolStripMenuItem.Click += new System.EventHandler(this.RenameToolStripMenuItem_Click);\n            // \n            // deleteToolStripMenuItem\n            // \n            this.deleteToolStripMenuItem.Name = \"deleteToolStripMenuItem\";\n            this.deleteToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;\n            this.deleteToolStripMenuItem.Size = new System.Drawing.Size(238, 32);\n            this.deleteToolStripMenuItem.Text = \"&Delete\";\n            this.deleteToolStripMenuItem.Click += new System.EventHandler(this.DeleteToolStripMenuItem_Click);\n            // \n            // IconsList\n            // \n            this.IconsList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject(\"IconsList.ImageStream\")));\n            this.IconsList.TransparentColor = System.Drawing.Color.Transparent;\n            this.IconsList.Images.SetKeyName(0, \"File\");\n            this.IconsList.Images.SetKeyName(1, \"Folder\");\n            this.IconsList.Images.SetKeyName(2, \"RemoteFolder\");\n            // \n            // CancelButton\n            // \n            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.CancelButton.Location = new System.Drawing.Point(663, 614);\n            this.CancelButton.Name = \"CancelButton\";\n            this.CancelButton.Size = new System.Drawing.Size(108, 49);\n            this.CancelButton.TabIndex = 3;\n            this.CancelButton.Text = \"&Cancel\";\n            this.CancelButton.UseVisualStyleBackColor = true;\n            // \n            // OKButton\n            // \n            this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.OKButton.Enabled = false;\n            this.OKButton.Location = new System.Drawing.Point(548, 614);\n            this.OKButton.Name = \"OKButton\";\n            this.OKButton.Size = new System.Drawing.Size(108, 49);\n            this.OKButton.TabIndex = 2;\n            this.OKButton.Text = \"&OK\";\n            this.OKButton.UseVisualStyleBackColor = true;\n            this.OKButton.Click += new System.EventHandler(this.OKButton_Click);\n            // \n            // UpButton\n            // \n            this.UpButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.UpButton.Enabled = false;\n            this.UpButton.Location = new System.Drawing.Point(681, 3);\n            this.UpButton.Name = \"UpButton\";\n            this.UpButton.Size = new System.Drawing.Size(62, 43);\n            this.UpButton.TabIndex = 4;\n            this.UpButton.Text = \"Up\";\n            this.UpButton.UseVisualStyleBackColor = true;\n            this.UpButton.EnabledChanged += new System.EventHandler(this.UpButton_EnabledChanged);\n            this.UpButton.Click += new System.EventHandler(this.UpButton_Click);\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(14, 11);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(686, 23);\n            this.ExplanationLabel.TabIndex = 8;\n            this.ExplanationLabel.Text = \"Select where you want to store the KeePass database. Right click for additional o\" +\n    \"ptions.\";\n            // \n            // FileNameTextBox\n            // \n            this.FileNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.FileNameTextBox.Location = new System.Drawing.Point(106, 623);\n            this.FileNameTextBox.Name = \"FileNameTextBox\";\n            this.FileNameTextBox.Size = new System.Drawing.Size(433, 26);\n            this.FileNameTextBox.TabIndex = 1;\n            this.FileNameTextBox.TextChanged += new System.EventHandler(this.FileNameTextBox_TextChanged);\n            this.FileNameTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.FileNameTextBox_KeyUp);\n            // \n            // FileNameLabel\n            // \n            this.FileNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.FileNameLabel.Location = new System.Drawing.Point(14, 623);\n            this.FileNameLabel.Name = \"FileNameLabel\";\n            this.FileNameLabel.Size = new System.Drawing.Size(87, 28);\n            this.FileNameLabel.TabIndex = 9;\n            this.FileNameLabel.Text = \"Filename:\";\n            // \n            // FilesTabControl\n            // \n            this.FilesTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.FilesTabControl.Controls.Add(this.MyFilesTabPage);\n            this.FilesTabControl.Controls.Add(this.SharedWithMeTabPage);\n            this.FilesTabControl.Location = new System.Drawing.Point(16, 38);\n            this.FilesTabControl.Name = \"FilesTabControl\";\n            this.FilesTabControl.SelectedIndex = 0;\n            this.FilesTabControl.Size = new System.Drawing.Size(754, 569);\n            this.FilesTabControl.TabIndex = 10;\n            this.FilesTabControl.SelectedIndexChanged += new System.EventHandler(this.FilesTabControl_SelectedIndexChanged);\n            // \n            // MyFilesTabPage\n            // \n            this.MyFilesTabPage.Controls.Add(this.CloudLocationPath);\n            this.MyFilesTabPage.Controls.Add(this.CloudLocationPicker);\n            this.MyFilesTabPage.Controls.Add(this.UpButton);\n            this.MyFilesTabPage.Location = new System.Drawing.Point(4, 29);\n            this.MyFilesTabPage.Name = \"MyFilesTabPage\";\n            this.MyFilesTabPage.Padding = new System.Windows.Forms.Padding(3);\n            this.MyFilesTabPage.Size = new System.Drawing.Size(746, 536);\n            this.MyFilesTabPage.TabIndex = 0;\n            this.MyFilesTabPage.Text = \"My files\";\n            this.MyFilesTabPage.UseVisualStyleBackColor = true;\n            // \n            // CloudLocationPath\n            // \n            this.CloudLocationPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloudLocationPath.BackColor = System.Drawing.Color.White;\n            this.CloudLocationPath.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.CloudLocationPath.Location = new System.Drawing.Point(10, 15);\n            this.CloudLocationPath.Name = \"CloudLocationPath\";\n            this.CloudLocationPath.Size = new System.Drawing.Size(668, 19);\n            this.CloudLocationPath.TabIndex = 7;\n            this.CloudLocationPath.TabStop = false;\n            // \n            // CloudLocationPicker\n            // \n            this.CloudLocationPicker.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloudLocationPicker.ContextMenuStrip = this.MyFilesContextMenu;\n            this.CloudLocationPicker.HideSelection = false;\n            this.CloudLocationPicker.LargeImageList = this.IconsList;\n            this.CloudLocationPicker.Location = new System.Drawing.Point(6, 54);\n            this.CloudLocationPicker.MultiSelect = false;\n            this.CloudLocationPicker.Name = \"CloudLocationPicker\";\n            this.CloudLocationPicker.ShowItemToolTips = true;\n            this.CloudLocationPicker.Size = new System.Drawing.Size(736, 470);\n            this.CloudLocationPicker.SmallImageList = this.IconsList;\n            this.CloudLocationPicker.TabIndex = 1;\n            this.CloudLocationPicker.TileSize = new System.Drawing.Size(244, 70);\n            this.CloudLocationPicker.UseCompatibleStateImageBehavior = false;\n            this.CloudLocationPicker.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.CloudLocationPicker_ItemSelectionChanged);\n            this.CloudLocationPicker.DoubleClick += new System.EventHandler(this.CloudLocationPicker_DoubleClick);\n            this.CloudLocationPicker.KeyUp += new System.Windows.Forms.KeyEventHandler(this.CloudLocationPicker_KeyUp);\n            // \n            // SharedWithMeTabPage\n            // \n            this.SharedWithMeTabPage.Controls.Add(this.SharedWithMeUpButton);\n            this.SharedWithMeTabPage.Controls.Add(this.SharedWithMePath);\n            this.SharedWithMeTabPage.Controls.Add(this.SharedWithMePicker);\n            this.SharedWithMeTabPage.Controls.Add(this.SharedWithMeNotAvailableLabel);\n            this.SharedWithMeTabPage.Location = new System.Drawing.Point(4, 29);\n            this.SharedWithMeTabPage.Name = \"SharedWithMeTabPage\";\n            this.SharedWithMeTabPage.Padding = new System.Windows.Forms.Padding(3);\n            this.SharedWithMeTabPage.Size = new System.Drawing.Size(746, 536);\n            this.SharedWithMeTabPage.TabIndex = 1;\n            this.SharedWithMeTabPage.Text = \"Shared with me\";\n            this.SharedWithMeTabPage.UseVisualStyleBackColor = true;\n            // \n            // SharedWithMeUpButton\n            // \n            this.SharedWithMeUpButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.SharedWithMeUpButton.Enabled = false;\n            this.SharedWithMeUpButton.Location = new System.Drawing.Point(681, 3);\n            this.SharedWithMeUpButton.Name = \"SharedWithMeUpButton\";\n            this.SharedWithMeUpButton.Size = new System.Drawing.Size(62, 43);\n            this.SharedWithMeUpButton.TabIndex = 9;\n            this.SharedWithMeUpButton.Text = \"Up\";\n            this.SharedWithMeUpButton.UseVisualStyleBackColor = true;\n            this.SharedWithMeUpButton.Click += new System.EventHandler(this.SharedWithMeUpButton_Click);\n            // \n            // SharedWithMePath\n            // \n            this.SharedWithMePath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.SharedWithMePath.BackColor = System.Drawing.Color.White;\n            this.SharedWithMePath.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.SharedWithMePath.Location = new System.Drawing.Point(10, 15);\n            this.SharedWithMePath.Name = \"SharedWithMePath\";\n            this.SharedWithMePath.Size = new System.Drawing.Size(663, 19);\n            this.SharedWithMePath.TabIndex = 8;\n            this.SharedWithMePath.TabStop = false;\n            // \n            // SharedWithMePicker\n            // \n            this.SharedWithMePicker.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.SharedWithMePicker.ContextMenuStrip = this.SharedWithMeContextMenu;\n            this.SharedWithMePicker.HideSelection = false;\n            this.SharedWithMePicker.LargeImageList = this.IconsList;\n            this.SharedWithMePicker.Location = new System.Drawing.Point(6, 54);\n            this.SharedWithMePicker.MultiSelect = false;\n            this.SharedWithMePicker.Name = \"SharedWithMePicker\";\n            this.SharedWithMePicker.ShowItemToolTips = true;\n            this.SharedWithMePicker.Size = new System.Drawing.Size(736, 470);\n            this.SharedWithMePicker.SmallImageList = this.IconsList;\n            this.SharedWithMePicker.TabIndex = 2;\n            this.SharedWithMePicker.TileSize = new System.Drawing.Size(244, 70);\n            this.SharedWithMePicker.UseCompatibleStateImageBehavior = false;\n            this.SharedWithMePicker.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.SharedWithMePicker_ItemSelectionChanged);\n            this.SharedWithMePicker.DoubleClick += new System.EventHandler(this.SharedWithMePicker_DoubleClick);\n            this.SharedWithMePicker.KeyUp += new System.Windows.Forms.KeyEventHandler(this.SharedWithMePicker_KeyUp);\n            // \n            // SharedWithMeContextMenu\n            // \n            this.SharedWithMeContextMenu.ImageScalingSize = new System.Drawing.Size(20, 20);\n            this.SharedWithMeContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.RefreshSharedWithMeFilesToolStripMenuItem,\n            this.GoToSharedWithMeRootTtoolStripMenuItem,\n            this.GoUpSharedWithMeToolStripMenuItem});\n            this.SharedWithMeContextMenu.Name = \"ListViewContextMenu\";\n            this.SharedWithMeContextMenu.Size = new System.Drawing.Size(233, 100);\n            this.SharedWithMeContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.SharedWithMeContextMenu_Opening);\n            // \n            // RefreshSharedWithMeFilesToolStripMenuItem\n            // \n            this.RefreshSharedWithMeFilesToolStripMenuItem.Name = \"RefreshSharedWithMeFilesToolStripMenuItem\";\n            this.RefreshSharedWithMeFilesToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5;\n            this.RefreshSharedWithMeFilesToolStripMenuItem.Size = new System.Drawing.Size(232, 32);\n            this.RefreshSharedWithMeFilesToolStripMenuItem.Text = \"&Refresh\";\n            this.RefreshSharedWithMeFilesToolStripMenuItem.Click += new System.EventHandler(this.RefreshSharedWithMeFilesToolStripMenuItem_Click);\n            // \n            // GoToSharedWithMeRootTtoolStripMenuItem\n            // \n            this.GoToSharedWithMeRootTtoolStripMenuItem.Name = \"GoToSharedWithMeRootTtoolStripMenuItem\";\n            this.GoToSharedWithMeRootTtoolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.H)));\n            this.GoToSharedWithMeRootTtoolStripMenuItem.Size = new System.Drawing.Size(232, 32);\n            this.GoToSharedWithMeRootTtoolStripMenuItem.Text = \"&Go to root\";\n            this.GoToSharedWithMeRootTtoolStripMenuItem.Click += new System.EventHandler(this.GoToSharedWithMeRootTtoolStripMenuItem_Click);\n            // \n            // GoUpSharedWithMeToolStripMenuItem\n            // \n            this.GoUpSharedWithMeToolStripMenuItem.Enabled = false;\n            this.GoUpSharedWithMeToolStripMenuItem.Name = \"GoUpSharedWithMeToolStripMenuItem\";\n            this.GoUpSharedWithMeToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U)));\n            this.GoUpSharedWithMeToolStripMenuItem.Size = new System.Drawing.Size(232, 32);\n            this.GoUpSharedWithMeToolStripMenuItem.Text = \"Go &up\";\n            this.GoUpSharedWithMeToolStripMenuItem.Click += new System.EventHandler(this.GoUpSharedWithMeToolStripMenuItem_Click);\n            // \n            // SharedWithMeNotAvailableLabel\n            // \n            this.SharedWithMeNotAvailableLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.SharedWithMeNotAvailableLabel.Location = new System.Drawing.Point(6, 54);\n            this.SharedWithMeNotAvailableLabel.Name = \"SharedWithMeNotAvailableLabel\";\n            this.SharedWithMeNotAvailableLabel.Size = new System.Drawing.Size(732, 471);\n            this.SharedWithMeNotAvailableLabel.TabIndex = 10;\n            this.SharedWithMeNotAvailableLabel.Text = \"Shared with me is not available when using the OneDrive for Business service. Use\" +\n    \" the Graph API service instead to connect to your OneDrive for Business site and\" +\n    \" it will be available.\";\n            this.SharedWithMeNotAvailableLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // OneDriveFilePickerDialog\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(786, 674);\n            this.Controls.Add(this.FilesTabControl);\n            this.Controls.Add(this.FileNameLabel);\n            this.Controls.Add(this.FileNameTextBox);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Controls.Add(this.CancelButton);\n            this.Controls.Add(this.OKButton);\n            this.KeyPreview = true;\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(467, 297);\n            this.Name = \"OneDriveFilePickerDialog\";\n            this.ShowIcon = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Select location\";\n            this.Load += new System.EventHandler(this.OneDriveFileSaveAsDialog_Load);\n            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OneDriveFileSaveAsDialog_KeyUp);\n            this.MyFilesContextMenu.ResumeLayout(false);\n            this.FilesTabControl.ResumeLayout(false);\n            this.MyFilesTabPage.ResumeLayout(false);\n            this.MyFilesTabPage.PerformLayout();\n            this.SharedWithMeTabPage.ResumeLayout(false);\n            this.SharedWithMeTabPage.PerformLayout();\n            this.SharedWithMeContextMenu.ResumeLayout(false);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n        private System.Windows.Forms.Button CancelButton;\n        private System.Windows.Forms.Button OKButton;\n        private System.Windows.Forms.Button UpButton;\n        private System.Windows.Forms.ContextMenuStrip MyFilesContextMenu;\n        private System.Windows.Forms.ToolStripMenuItem refreshToolStripMenuItem;\n        private System.Windows.Forms.ImageList IconsList;\n        private System.Windows.Forms.ToolStripMenuItem GoToRootToolStripMenuItem;\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem;\n        private System.Windows.Forms.TextBox FileNameTextBox;\n        private System.Windows.Forms.ToolStripMenuItem newFolderToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;\n        private System.Windows.Forms.ToolStripMenuItem renameToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem goupToolStripMenuItem;\n        private System.Windows.Forms.Label FileNameLabel;\n        private System.Windows.Forms.TabControl FilesTabControl;\n        private System.Windows.Forms.TabPage MyFilesTabPage;\n        private System.Windows.Forms.ListView CloudLocationPicker;\n        private System.Windows.Forms.TabPage SharedWithMeTabPage;\n        private System.Windows.Forms.ListView SharedWithMePicker;\n        private System.Windows.Forms.TextBox CloudLocationPath;\n        private System.Windows.Forms.ContextMenuStrip SharedWithMeContextMenu;\n        private System.Windows.Forms.ToolStripMenuItem RefreshSharedWithMeFilesToolStripMenuItem;\n        private System.Windows.Forms.TextBox SharedWithMePath;\n        private System.Windows.Forms.Button SharedWithMeUpButton;\n        private System.Windows.Forms.ToolStripMenuItem GoToSharedWithMeRootTtoolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem GoUpSharedWithMeToolStripMenuItem;\n        private System.Windows.Forms.Label SharedWithMeNotAvailableLabel;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing KoenZomers.OneDrive.Api;\nusing KoenZomers.OneDrive.Api.Entities;\n\nnamespace KoenZomersKeePassOneDriveSync.Forms\n{\n     public partial class OneDriveFilePickerDialog : Form\n    {\n        /// <summary>\n        /// Instance of the OneDrive API that can be used to communicate with the cloud service\n        /// </summary>\n        private readonly OneDriveApi _oneDriveApi;\n\n        /// <summary>\n        /// Reference to the currently displayed folder on OneDrive for the My files tab\n        /// </summary>\n        private OneDriveItem CurrentMyOneDriveItem;\n\n        /// <summary>\n        /// Reference to the currently displayed folder on OneDrive for the Shared With Me tab\n        /// </summary>\n        private OneDriveItem CurrentSharedWithMeOneDriveItem;\n\n        /// <summary>\n        /// Reference to the currently displayed folder on OneDrive for the active tab\n        /// </summary>\n        public OneDriveItem CurrentOneDriveItem\n        {\n            get { return FilesTabControl.SelectedIndex == 0 ? CurrentMyOneDriveItem : CurrentSharedWithMeOneDriveItem; }\n        }\n\n        /// <summary>\n        /// Gets or the filename in the textbox on the screen\n        /// </summary>\n        public string FileName\n        {\n            get { return FileNameTextBox.Text; }\n            set { FileNameTextBox.Text = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the text to explain the purpose of the dialog\n        /// </summary>\n        public string ExplanationText\n        {\n            get { return ExplanationLabel.Text; }\n            set { ExplanationLabel.Text = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets if the user can enter a filename which does not exist yet on their OneDrive\n        /// </summary>\n        public bool AllowEnteringNewFileName\n        {\n            get { return FileNameTextBox.Enabled; }\n            set { FileNameTextBox.Enabled = value; }\n        }\n\n        public OneDriveFilePickerDialog(OneDriveApi oneDriveApi)\n        {\n            InitializeComponent();\n\n            _oneDriveApi = oneDriveApi;\n\n            var sharedWithMeDisabled = (oneDriveApi is OneDriveForBusinessO365Api);\n\n            SharedWithMePicker.Visible = !sharedWithMeDisabled;\n            SharedWithMeUpButton.Visible = !sharedWithMeDisabled;\n            SharedWithMeNotAvailableLabel.Visible = sharedWithMeDisabled;\n        }\n\n        /// <summary>\n        /// Loads the folders in the \"My files\" view\n        /// </summary>\n        /// <param name=\"parentItemId\">Folder to display the child folders and items of. If not provided or NULL, the root folder will be used.</param>\n         public async Task LoadFolderItems(string parentItemId = null)\n         {\n             CloudLocationPicker.Items.Clear();\n\n            // Check if there is a parent folder to display its children of\n             OneDriveItemCollection itemCollection;\n             if (parentItemId == null)\n             {\n                // No parent folder, get the items under the root\n                itemCollection = await _oneDriveApi.GetDriveRootChildren();\n                CloudLocationPath.Text = \"/drive/root:\";\n                UpButton.Enabled = false;\n                GoToRootToolStripMenuItem.Enabled = false;\n                CurrentMyOneDriveItem = await _oneDriveApi.GetDriveRoot();\n             }\n             else\n             {\n                // Parent folder provided, get its children\n                itemCollection = await _oneDriveApi.GetChildrenByFolderId(parentItemId);\n                CurrentMyOneDriveItem = await _oneDriveApi.GetItemById(parentItemId);\n                GoToRootToolStripMenuItem.Enabled = true;\n                UpButton.Enabled = CurrentMyOneDriveItem.ParentReference != null;\n                UpButton.Tag = CurrentMyOneDriveItem.ParentReference != null ? CurrentMyOneDriveItem.ParentReference.Id : null;\n                CloudLocationPath.Text = CurrentMyOneDriveItem.ParentReference != null ? CurrentMyOneDriveItem.ParentReference.Path + \"/\" + CurrentMyOneDriveItem.Name : \"\";\n             }\n\n             foreach (var oneDriveItem in itemCollection.Collection)\n             {\n                var oneDriveListViewItem = new ListViewItem\n                {\n                    Text = oneDriveItem.Name,\n                    Tag = oneDriveItem.RemoteItem != null ? oneDriveItem.RemoteItem.Id : oneDriveItem.Id,\n                    ImageKey = oneDriveItem.Folder != null ? \"Folder\" : oneDriveItem.RemoteItem != null ? \"RemoteFolder\" : \"File\",\n                    Selected = oneDriveItem.Name.Equals(FileNameTextBox.Text, StringComparison.InvariantCultureIgnoreCase)\n                };\n\n                if (oneDriveItem.Size > 0)\n                {\n                    oneDriveListViewItem.ToolTipText += string.Format(\"Size: {0:n0} bytes\", oneDriveItem.Size) + Environment.NewLine;\n                }\n                else if (oneDriveItem.RemoteItem != null && oneDriveItem.RemoteItem.Size > 0)\n                {\n                    oneDriveListViewItem.ToolTipText += string.Format(\"Size: {0:n0} bytes\", oneDriveItem.RemoteItem.Size) + Environment.NewLine;\n                }\n                if (oneDriveItem.CreatedDateTime != null)\n                {\n                    oneDriveListViewItem.ToolTipText += string.Format(\"Created: {0:d MMMM yyyy HH:mm:ss}\", oneDriveItem.CreatedDateTime) + Environment.NewLine;\n                }\n                if (oneDriveItem.LastModifiedDateTime != null)\n                {\n                    oneDriveListViewItem.ToolTipText += string.Format(\"Last modified: {0:d MMMM yyyy HH:mm:ss}\", oneDriveItem.LastModifiedDateTime) + Environment.NewLine;\n                }\n\n                CloudLocationPicker.Items.Add(oneDriveListViewItem);\n             }\n\n            // Define if the OK button should be enabled\n            FileNameTextBox_TextChanged(null, null);\n        }\n\n        /// <summary>\n        /// Loads the items shared with the user in the \"Shared with me\" overview\n        /// </summary>\n        /// <param name=\"parentItem\">OneDriveItem to display the child folders and items of. If not provided or NULL, the root folder will be used.</param>\n        public async Task LoadSharedWithMeItems(OneDriveItem parentItem = null)\n        {\n            SharedWithMePicker.Items.Clear();\n\n            if (parentItem == null)\n            {\n                // Get the root of the shared with me items\n                var itemCollection = await _oneDriveApi.GetSharedWithMe();\n                var sortedItemCollection = itemCollection.Collection.OrderBy(i => i.Name).OrderBy(i => i.Folder == null).OrderBy(i => i.RemoteItem.Folder == null);\n                SharedWithMeUpButton.Enabled = false;\n                CurrentSharedWithMeOneDriveItem = null;\n                GoToSharedWithMeRootTtoolStripMenuItem.Enabled = false;\n                SharedWithMePath.Text = string.Empty;\n\n                foreach (var oneDriveItem in sortedItemCollection)\n                {\n                    var oneDriveListViewItem = new ListViewItem\n                    {\n                        Text = oneDriveItem.Name,\n                        Tag = oneDriveItem,\n                        ImageKey = (oneDriveItem.RemoteItem != null && oneDriveItem.RemoteItem.Folder != null) || oneDriveItem.Folder != null ? \"RemoteFolder\" : \"File\",\n                        Selected = oneDriveItem.Name.Equals(FileNameTextBox.Text, StringComparison.InvariantCultureIgnoreCase)\n                    };\n\n                    OneDriveIdentity sharedInfo = null;\n                    if (oneDriveItem.RemoteItem != null && oneDriveItem.RemoteItem.Shared != null && oneDriveItem.RemoteItem.Shared.Owner != null && oneDriveItem.RemoteItem.Shared.Owner.User != null)\n                    {\n                        sharedInfo = oneDriveItem.RemoteItem.Shared.Owner.User;\n                    }\n                    else if (oneDriveItem.Shared != null && oneDriveItem.Shared.Owner != null && oneDriveItem.Shared.Owner.User != null)\n                    {\n                        sharedInfo = oneDriveItem.Shared.Owner.User;\n                    }\n                    if (sharedInfo != null)\n                    {\n                        oneDriveListViewItem.ToolTipText = string.Format(\"Shared by {0} ({1})\", sharedInfo.DisplayName, sharedInfo.Id);\n                    }\n                    else\n                    {\n                        oneDriveListViewItem.ToolTipText = \"Shared by information not available\";\n                    }\n                    if (oneDriveItem.Size > 0)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Size: {0:n0} bytes\", oneDriveItem.Size);\n                    }\n                    else if(oneDriveItem.RemoteItem != null && oneDriveItem.RemoteItem.Size > 0)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Size: {0:n0} bytes\", oneDriveItem.RemoteItem.Size);\n                    }\n                    if (oneDriveItem.CreatedDateTime != null)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Created: {0:d MMMM yyyy HH:mm:ss}\", oneDriveItem.CreatedDateTime);\n                    }\n                    if (oneDriveItem.LastModifiedDateTime != null)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Last modified: {0:d MMMM yyyy HH:mm:ss}\", oneDriveItem.LastModifiedDateTime);\n                    }\n\n                    SharedWithMePicker.Items.Add(oneDriveListViewItem);\n                }\n            }\n            else\n            {\n                // Parent folder provided, get its children\n                var itemCollection = await _oneDriveApi.GetAllChildrenFromDriveByFolderId(parentItem.RemoteItem != null ? parentItem.RemoteItem.ParentReference.DriveId : parentItem.ParentReference.DriveId, \n                                                                                          parentItem.RemoteItem != null ? parentItem.RemoteItem.ParentReference != null ? string.IsNullOrEmpty(parentItem.RemoteItem.ParentReference.Id) || parentItem.RemoteItem.Folder != null ? parentItem.RemoteItem.Id : parentItem.RemoteItem.ParentReference.Id : parentItem.RemoteItem.Id : parentItem.Id);\n\n                SharedWithMeUpButton.Tag = parentItem.Name == \"root\" || parentItem.ParentReference == null || parentItem.ParentReference.Id == null || (parentItem.ParentReference.Path != null && parentItem.ParentReference.Path.EndsWith(\"root:\")) ? null : await _oneDriveApi.GetItemFromDriveById(parentItem.ParentReference.Id, parentItem.ParentReference.DriveId);\n                CurrentSharedWithMeOneDriveItem = parentItem;\n                GoToSharedWithMeRootTtoolStripMenuItem.Enabled = true;\n                SharedWithMeUpButton.Enabled = true;\n\n                if (CurrentSharedWithMeOneDriveItem.ParentReference != null && CurrentSharedWithMeOneDriveItem.ParentReference.Path != null)\n                {\n                    var rootLocation = CurrentSharedWithMeOneDriveItem.ParentReference.Path.IndexOf(\"root:\");\n                    SharedWithMePath.Text = ((rootLocation == -1 ? CurrentSharedWithMeOneDriveItem.ParentReference.Path : CurrentSharedWithMeOneDriveItem.ParentReference.Path.Remove(0, rootLocation + 5).TrimStart(new[] { '/' })) + \"/\" + CurrentSharedWithMeOneDriveItem.Name).TrimStart(new[] { '/' });\n                }\n                else\n                {\n                    SharedWithMePath.Text = CurrentSharedWithMeOneDriveItem.Name;\n                }\n\n                foreach (var oneDriveItem in itemCollection)\n                {\n                    var oneDriveListViewItem = new ListViewItem\n                    {\n                        Text = oneDriveItem.Name,\n                        Tag = oneDriveItem,\n                        ImageKey = oneDriveItem.Folder != null ? \"RemoteFolder\" : \"File\",\n                        Selected = oneDriveItem.Name.Equals(FileNameTextBox.Text, StringComparison.InvariantCultureIgnoreCase)\n                    };\n\n                    OneDriveIdentity sharedInfo = null;\n                    if (oneDriveItem.RemoteItem != null && oneDriveItem.RemoteItem.Shared != null && oneDriveItem.RemoteItem.Shared.Owner != null && oneDriveItem.RemoteItem.Shared.Owner.User != null)\n                    {\n                        sharedInfo = oneDriveItem.RemoteItem.Shared.Owner.User;\n                    }\n                    else if (oneDriveItem.Shared != null && oneDriveItem.Shared.Owner != null && oneDriveItem.Shared.Owner.User != null)\n                    {\n                        sharedInfo = oneDriveItem.Shared.Owner.User;\n                    }\n                    if (sharedInfo != null)\n                    {\n                        oneDriveListViewItem.ToolTipText = string.Format(\"Shared by {0} ({1})\", sharedInfo.DisplayName, sharedInfo.Id);\n                    }\n                    else\n                    {\n                        oneDriveListViewItem.ToolTipText = \"Shared by information not available\";\n                    }\n                    if (oneDriveItem.Size > 0)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Size: {0} bytes\", oneDriveItem.Size);\n                    }\n                    else if (oneDriveItem.RemoteItem != null && oneDriveItem.RemoteItem.Size > 0)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Size: {0} bytes\", oneDriveItem.RemoteItem.Size);\n                    }\n                    if (oneDriveItem.CreatedDateTime != null)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Created: {0:d MMMM yyyy HH:mm:ss}\", oneDriveItem.CreatedDateTime);\n                    }\n                    if (oneDriveItem.LastModifiedDateTime != null)\n                    {\n                        oneDriveListViewItem.ToolTipText += Environment.NewLine + string.Format(\"Last modified: {0:d MMMM yyyy HH:mm:ss}\", oneDriveItem.LastModifiedDateTime);\n                    }\n\n                    SharedWithMePicker.Items.Add(oneDriveListViewItem);\n                }\n            }\n\n            // Define if the OK button should be enabled\n            FileNameTextBox_TextChanged(null, null);\n        }\n\n        private async void CloudLocationPicker_DoubleClick(object sender, EventArgs e)\n         {\n             if (CloudLocationPicker.SelectedItems.Count == 0) return;\n\n             var selectedItem = CloudLocationPicker.SelectedItems[0];\n             if (selectedItem.ImageKey == \"File\" && OKButton.Enabled)\n             {\n                OKButton_Click(sender, e);\n                return;\n             }\n\n             await LoadFolderItems(selectedItem.Tag.ToString());\n         }\n\n         private async void UpButton_Click(object sender, EventArgs e)\n        {\n            var childItem = UpButton.Tag as string;\n            await LoadFolderItems(childItem);\n        }\n\n        private async void RefreshToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            await LoadFolderItems(CurrentMyOneDriveItem != null ? CurrentMyOneDriveItem.Id : null);\n        }\n\n        private void OneDriveFileSaveAsDialog_KeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.Back && UpButton.Enabled)\n            {\n                UpButton_Click(sender, null);\n            }\n        }\n\n        private void OKButton_Click(object sender, EventArgs e)\n        {\n            DialogResult = DialogResult.OK;\n            Close();\n        }\n\n        private void CloudLocationPicker_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)\n        {\n            if (CloudLocationPicker.SelectedItems.Count == 0) return;\n\n            var selectedItem = CloudLocationPicker.SelectedItems[0];\n            if (selectedItem.ImageKey == \"File\")\n            {\n                FileNameTextBox.Text = selectedItem.Text;\n            }\n        }\n\n        private async void GoToRootToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            await LoadFolderItems();\n        }\n\n        private void ListViewContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)\n        {\n            renameToolStripMenuItem.Enabled = deleteToolStripMenuItem.Enabled = CloudLocationPicker.SelectedItems.Count > 0;\n        }\n\n        private void OneDriveFileSaveAsDialog_Load(object sender, EventArgs e)\n        {\n\n        }\n\n        private async void NewFolderToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            var newFolderDialog = new OneDriveRequestInputDialog\n            {\n                FormTitle = \"Create new folder\"\n            };\n            newFolderDialog.ShowDialog(this);\n            if (newFolderDialog.DialogResult != DialogResult.OK) return;\n\n            try\n            {\n                var newFolderItem = await _oneDriveApi.CreateFolder(CurrentMyOneDriveItem, newFolderDialog.InputValue);\n                MessageBox.Show(\"Folder has been created\", \"New Folder\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n                await LoadFolderItems(newFolderItem.Id);\n            }\n            catch (Exception)\n            {\n                MessageBox.Show(\"Folder could not be created\", \"New Folder\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n            }\n        }\n\n        private async void DeleteToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            var confirm = MessageBox.Show(\"Are you sure you want to delete the selected item?\", \"Confirm deletion\", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);\n            if (confirm != DialogResult.Yes) return;\n            if (CloudLocationPicker.SelectedItems.Count == 0) return;\n            if (CloudLocationPicker.SelectedItems[0].Tag == null) return;\n\n            try\n            {\n                var itemToDelete = await _oneDriveApi.GetItemById(CloudLocationPicker.SelectedItems[0].Tag.ToString());\n                await _oneDriveApi.Delete(itemToDelete);\n                MessageBox.Show(\"Item has been deleted\", \"Delete item\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n                await LoadFolderItems(CurrentMyOneDriveItem.Id);\n            }\n            catch (Exception)\n            {\n                MessageBox.Show(\"Item could not be deleted\", \"Delete item\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n            }\n        }\n\n        private void FileNameTextBox_TextChanged(object sender, EventArgs e)\n        {\n            OKButton.Enabled = CurrentOneDriveItem != null && !string.IsNullOrEmpty(FileNameTextBox.Text);\n        }\n\n        private async void RenameToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (CloudLocationPicker.SelectedItems.Count == 0) return;\n            if (CloudLocationPicker.SelectedItems[0].Tag == null) return;\n\n            var renameItemDialog = new OneDriveRequestInputDialog\n            {\n                FormTitle = \"Enter new name\",\n                InputValue = CloudLocationPicker.SelectedItems[0].Text\n            };\n            renameItemDialog.ShowDialog(this);\n            if (renameItemDialog.DialogResult != DialogResult.OK) return;\n\n            try\n            {\n                var oneDriveItemToRename = await _oneDriveApi.GetItemById(CloudLocationPicker.SelectedItems[0].Tag.ToString());\n                var operationSuccessful = await _oneDriveApi.Rename(oneDriveItemToRename, renameItemDialog.InputValue);\n                if (operationSuccessful)\n                {\n                    MessageBox.Show(\"Item has been renamed\", \"Rename item\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n                    await LoadFolderItems(CurrentMyOneDriveItem != null ? CurrentMyOneDriveItem.Id : null);\n                }\n                else\n                {\n                    MessageBox.Show(\"Item could not be renamed\", \"Rename item\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n                }\n            }\n            catch (Exception)\n            {\n                MessageBox.Show(\"Item could not be renamed\", \"Rename item\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n            }\n        }\n\n        private void GroupToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            UpButton_Click(sender, e);\n        }\n\n        private void UpButton_EnabledChanged(object sender, EventArgs e)\n        {\n            goupToolStripMenuItem.Enabled = UpButton.Enabled;\n        }\n\n        private void CloudLocationPicker_KeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.Enter)\n            {\n                CloudLocationPicker_DoubleClick(sender, e);\n            }\n        }\n\n        private void FileNameTextBox_KeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.Enter && OKButton.Enabled)\n            {\n                OKButton_Click(sender, e);\n            }\n        }\n\n        private async void FilesTabControl_SelectedIndexChanged(object sender, EventArgs e)\n        {\n            // When switching to the \"Shared with me\" tab and the items have not been loaded yet, load them now\n            if(FilesTabControl.SelectedIndex == 1 && SharedWithMePicker.Items.Count == 0)\n            {\n                await LoadSharedWithMeItems();\n            }\n\n            // Ensure the OK button is properly enabled/disabled when switching tabs\n            switch (FilesTabControl.SelectedIndex)\n            {\n                case 1:\n                    SharedWithMePicker_ItemSelectionChanged(sender, null);\n                    break;\n\n                case 0:\n                    CloudLocationPicker_ItemSelectionChanged(sender, null);\n                    break;\n            }\n        }\n\n        private async void RefreshSharedWithMeFilesToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            await LoadSharedWithMeItems(CurrentSharedWithMeOneDriveItem);\n        }\n\n        private async void SharedWithMePicker_DoubleClick(object sender, EventArgs e)\n        {\n            if (SharedWithMePicker.SelectedItems.Count == 0) return;\n\n            var selectedItem = SharedWithMePicker.SelectedItems[0];\n            if (selectedItem.ImageKey == \"File\" && OKButton.Enabled)\n            {\n                OKButton_Click(sender, e);\n                return;\n            }\n\n            await LoadSharedWithMeItems(selectedItem.Tag as OneDriveItem);\n        }\n\n        private void SharedWithMePicker_KeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.Enter)\n            {\n                SharedWithMePicker_DoubleClick(sender, e);\n            }\n        }\n\n        private async void SharedWithMeUpButton_Click(object sender, EventArgs e)\n        {\n            var childItem = SharedWithMeUpButton.Tag as OneDriveItem;\n            await LoadSharedWithMeItems(childItem);\n        }\n\n        private async void GoToSharedWithMeRootTtoolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            await LoadSharedWithMeItems();\n        }\n\n        private async void GoUpSharedWithMeToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n\n        }\n\n        private void SharedWithMeContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)\n        {\n\n        }\n\n        private void SharedWithMePicker_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)\n        {\n            if (SharedWithMePicker.SelectedItems.Count == 0)\n            {\n                // If we're not in a folder yet, disable the button as a new file can't be created in Shared With Me outside a folder\n                if(string.IsNullOrEmpty(SharedWithMePath.Text))\n                {\n                    OKButton.Enabled = false;\n                }\n                return;\n            }\n\n            var selectedItem = SharedWithMePicker.SelectedItems[0];\n            if (selectedItem.ImageKey == \"File\")\n            {\n                FileNameTextBox.Text = selectedItem.Text;\n                OKButton.Enabled = true;\n                CurrentSharedWithMeOneDriveItem = selectedItem.Tag as OneDriveItem;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"MyFilesContextMenu.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>132, 17</value>\n  </metadata>\n  <metadata name=\"IconsList.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <data name=\"IconsList.ImageStream\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n    <value>\n        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w\n        LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0\n        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAD8\n        yQAAAk1TRnQBSQFMAgEBAwEAAbABAAGwAQABQAEAAUABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgEAAEB\n        AgABQAMAAQEBAAEgBwABAf8A/wD/AP8AMAAEAQECAwEBAgMBAQIDAQECAwEBAgMBAQIDAQECAwEBAgMB\n        AQIDAQECAwEBAgMBAQIDAQECAwEBAgMBAQIDAQECAwEBAgMBAQIDAQECAwEBAgMBAQIDAQECAwEBAgMB\n        AQIDAQECAwEBAgMBAQIDAQECAwEBAgMBAQIDAQECAwEBAgMAAQGsAAMCAQMDBAEFAwQBBQMCAQMDAAEB\n        7AADAgEDAwQBBQMEAQUDAgEDAwABAf8AtQADAgEDAwcBCgMMARADDgETAw8BFAMPARQDDwEUAw8BFAMP\n        ARQDDwEUAw8BFAMPARQDDwEUAw8BFAMPARQDDwEUAw8BFAMPARQDDwEUAw8BFAMPARQDDwEUAw8BFAMP\n        ARQDDwEUAw8BFAMPARQDDwEUAw8BFAMPARQDDwEUAw8BFAMOARMDDQESAwoBDQMEAQYDAAEBnwABAQMD\n        AQQDCgENAw8BFAMRARcDDQERAwUBBwMBAQLjAAEBAwMBBAMKAQ0DDwEUAxEBFwMNAREDBQEHAwEBAv8A\n        sAABAQMHAQkDFwEgAyQBNQMpAT4DKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFA\n        AyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFA\n        AyoBQAMqAUADKgFAAykBPwMoATwDIQEwAxQBHAMIAQsDAQEClwABAQMDAQQDCwEPAzMBUwFaAbkB1wH/\n        AR0BUgFpAf8DHgErAxIBGAMIAQsDAwEEAwABATsABAEEAgEDAwQBBgMEAQYDAwEEAwEBAgMAAQEDAAEB\n        ewABAQMDAQQDCwEPAzMBUwFaAbkB1wH/AR0BUgFpAf8DHgErAxIBGAMIAQsDAwEEAwABATsABAEEAgED\n        AwQBBgMEAQYDAwEEAwEBAgMAAQEDAAEB/wBMAAEBAwwBEAMkATYDNwFbBP8D9wH/A/gB/wP4Af8D+AH/\n        A/kB/wP6Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/QH/A/0B/wP9Af8D/gH/\n        A/4B/wP+Af8D/gH/A/0B/wP7Af8D+gH/A/gB/wP1Af8D8gH/A+8B/wPsAf8B6ALnAf8DbwH1AxkBIwMK\n        AQ0DAgEDjwABAQMEAQUDCgEOA0IBdQFZAbgB1wH/AVkBuAHWAf8BNwGKAaUB/wMvAUkDJAE1AxcBIAML\n        AQ8DBAEGAwABAScABAEEAgEDAwQBBgMIAQsDEAEWAxkBIwMeASsDFgEeAw8BFAMKAQ4DCAELAwcBCQME\n        AQUDAAEBbwABAQMEAQUDCgEOA0IBdQFZAbgB1wH/AVkBuAHWAf8BNwGKAaUB/wMvAUkDJAE1AxcBIAML\n        AQ8DBAEGAwABAScABAEEAgEDAwQBBgMIAQsDEAEWAxkBIwMeASsDFgEeAw8BFAMKAQ4DCAELAwcBCQME\n        AQUDAAEB/wBBAAMBAQIDDgETAykBPwM9AWoE/wP2Af8D9wH/A/gB/wP4Af8D+QH/A/oB/wP6Af8D+gH/\n        A/sB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP+Af8D/gH/A/4B/wP+Af8D/QH/\n        A/sB/wP5Af8D9gH/A/MB/wPxAf8D7gH/AesC6gH/A+cB/wPiAf8DoAH+Ax0BKQMNAREDAwEEhwABAQME\n        AQUDCwEPA1IBowFZAbgB1gH/AVkBuAHWAf8BWQG4AdYB/wE5AY8BqQH/AzgBXgMyAVEDKAE9AxwBJwMQ\n        ARUDBwEJAwIBAxMABAEEAgEDAwQBBgMIAQsDDQERAxQBHAMfBCwBRANSAakBUwGwAc4B/wFaAbkB2AH/\n        AVoBuQHXAf8CWAFbAcsDHAEoAxoBJAMWAR4DDQESAwUBBwMBAQJnAAEBAwQBBQMLAQ8DUgGjAVkBuAHW\n        Af8BWQG4AdYB/wFZAbgB1gH/ATkBjwGpAf8DOAFeAzIBUQMoAT0DHAEnAxABFQMHAQkDAgEDEwAEAQQC\n        AQMDBAEGAwgBCwMNAREDFAEcAx8ELAFEA1IBqQFTAbABzgH/AVoBuQHYAf8BWgG5AdcB/wJYAVsBywMc\n        ASgDGgEkAxYBHgMNARIDBQEHAwEBAv8APQADAQECAw8BFAMqAUADPgFsBP8C9wH2Af8D9wH/A/gB/wP4\n        Af8D+QH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP+\n        Af8D/gH/A/4B/wP+Af8D/AH/A/sB/wP5Af8D9gH/A/MB/wPwAf8D7QH/A+oB/wPkAf8D3QH/A9cB/wPK\n        Af8DIwEzAw8BFAMEAQUDAAEBewABAQMEAQUDDAEQA1wBzQFaAbkB1wH/AVoBuQHXAf8BWQG5AdcB/wFZ\n        AbkB1wH/ATkBjwGpAf8DOgFiAzkBXwM0AVUDKwFDAyABLwMTARoDCQEMAwQBBQMCBAMEBAEGAwcBCgMM\n        ARADEgEZAxsEJgE5A1ABmgFJAagBrgH9AVoBuQHYAf8BWQG4AdYB/wFZAbgB1gH/AVkBuAHWAf8BWQG4\n        AdYB/wFZAbgB1gH/AUkBoQG+Af8DLAFEAyoBQAMmATkDHAEoAw4BEwMFAQcDAQECXwABAQMEAQUDDAEQ\n        A1wBzQFaAbkB1wH/AVoBuQHXAf8BWQG5AdcB/wFZAbkB1wH/ATkBjwGpAf8DOgFiAzkBXwM0AVUDKwFD\n        AyABLwMTARoDCQEMAwQBBQMCBAMEBAEGAwcBCgMMARADEgEZAxsEJgE5A1ABmgFJAagBrgH9AVoBuQHY\n        Af8BWQG4AdYB/wFZAbgB1gH/AVkBuAHWAf8BWQG4AdYB/wFZAbgB1gH/AUkBoQG+Af8DLAFEAyoBQAMm\n        ATkDHAEoAw4BEwMFAQcDAQEC/wA5AAMBAQIDDwEUAyoBQAM+AWwE/wL3AfYB/wP3Af8D+AH/A/gB/wP5\n        Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/A/0B/wP9Af8D/QH/A/4B/wP+\n        Af8D/gH/A/4B/wP8Af8D+wH/A/kB/wP2Af8D8wH/A/AB/wPtAf8D6gH/A+IB/wPVAf8DywH/A9cB/wPK\n        Af8DLwFJAxEBFwMFAQcDAAEBcwABAQMEAQUDCwEPAV0BYgFkAe0BWgG6AdgB/wFaAboB2AH/AVoBugHY\n        Af8BWgG5AdgB/wFaAbkB2AH/ATkBjwGpAf8DOgFhAzoBYgM5AV8DNQFXAy8BSQMkATUDGAEiAw8BFAMN\n        ARIDEAEWAxgEIQEwAUwCTQGRAWsBfwGEAfcBWgG6AdkB/wFZAbkB1wH/AVkBuQHXAf8BWQG4AdYB/wFZ\n        AbgB1gH/AVkBuAHWAf8BWQG4AdYB/wFZAbgB1gH/AVkBuAHWAf8BWQG4AdYB/wFZAbgB1gH/AVoBuQHX\n        Af8BWgG6AdgB/wFYAmEB5gMoATwDGwEmAw0BEgMFAQcDAQECVwABAQMEAQUDCwEPAV0BYgFkAe0BWgG6\n        AdgB/wFaAboB2AH/AVoBugHYAf8BWgG5AdgB/wFaAbkB2AH/ATkBjwGpAf8DOgFhAzoBYgM5AV8DNQFX\n        Ay8BSQMkATUDGAEiAw8BFAMNARIDEAEWAxgEIQEwAUwCTQGRAWsBfwGEAfcBWgG6AdkB/wFZAbkB1wH/\n        AVkBuQHXAf8BWQG4AdYB/wFZAbgB1gH/AVkBuAHWAf8BWQG4AdYB/wFZAbgB1gH/AVkBuAHWAf8BWQG4\n        AdYB/wFZAbgB1gH/AVoBuQHXAf8BWgG6AdgB/wFYAmEB5gMoATwDGwEmAw0BEgMFAQcDAQEC/wA1AAMB\n        AQIDDwEUAyoBQAM+AWwE/wL3AfYB/wP3Af8D+AH/A/gB/wP5Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7\n        Af8D+wH/A/wB/wP8Af8D/AH/A/0B/wP9Af8D/QH/A/4B/wP+Af8D/gH/A/4B/wP8Af8D+wH/A/kB/wP2\n        Af8D8wH/A/AB/wPtAf8D6gH/A+IB/wPRAf8DvgH/A90B/wPWAf8DyQH/Az8BbAMTARoDBgEIAwABAWsA\n        AQEDBAEGAwwBEAFbAbwB2gH/AVsBuwHZAf8BWwG7AdkB/wFbAboB2QH/AVsBugHZAf8BWwG6AdkB/wFb\n        AboB2AH/ATkBjgGpAf8DOAFeAzkBXwM5AV8DOAFcAzUBVwMwAU0DKQE/AyYBOANKAYoBXQFhAWUB8AFb\n        AboB2QH/AVoBuQHXAf8BWgG5AdcB/wFaAbkB1wH/AVoBuQHXAf8BWgG5AdcB/wFaAbkB1wH/AVoBuQHX\n        Af8BWgG5AdcB/wFaAbkB1wH/AVoBuQHXAf8BWgG5AdcB/wFaAbkB1wH/AVoBuQHXAf8BWgG5AdgB/wFZ\n        AbkB2AH/AWkBtAHHAf8BXAG7AdoB/wMtAUYDJgE4AxkBIwMNAREDBQEHAwEBAk8AAQEDBAEGAwwBEAFb\n        AbwB2gH/AVsBuwHZAf8BWwG7AdkB/wFbAboB2QH/AVsBugHZAf8BWwG6AdkB/wFbAboB2AH/ATkBjgGp\n        Af8DOAFeAzkBXwM5AV8DOAFcAzUBVwMwAU0DKQE/AyYBOANKAYoBXQFhAWUB8AFbAboB2QH/AVoBuQHX\n        Af8BWgG5AdcB/wFaAbkB1wH/AVoBuQHXAf8BWgG5AdcB/wFaAbkB1wH/AVoBuQHXAf8BWgG5AdcB/wFa\n        AbkB1wH/AVoBuQHXAf8BWgG5AdcB/wFaAbkB1wH/AVoBuQHXAf8BWgG5AdgB/wFZAbkB2AH/AWkBtAHH\n        Af8BXAG7AdoB/wMtAUYDJgE4AxkBIwMNAREDBQEHAwEBAv8AMQADAQECAw8BFAMqAUADPgFsBP8D9gH/\n        A/cB/wP4Af8D+AH/A/kB/wP6Af8D+gH/A/oB/wP7Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/QH/\n        A/0B/wP9Af8D/gH/A/4B/wP+Af8D/gH/A/0B/wP7Af8D+QH/A/YB/wPzAf8D8AH/A+4B/wPqAf8B5QLk\n        Af8C1QHUAf8DuQH/A6sB/wPjAf8D1gH/A8kB/wNKAY0DFQEdAwcBCQMBAQJgAAMBAQIDBAEGAwsBDwFc\n        Ab0B3AH/AVwBvAHaAf8BXAG8AdoB/wFcAbwB2gH/AVwBuwHaAf8BWwG7AdoB/wFbAbsB2gH/AVsBuwHa\n        Af8BOgGOAakB/wM2AVkDNwFaAzcBWgM1AVgBUAJSAaMBZwF9AYMB9wFLAaUBwgH/AUwBpwHEAf8BWgG6\n        AdgB/wFaAboB2AH/AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/\n        AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/AVoBugHYAf8BWgG6\n        AdgB/wHAAaQBigH/Ae0BlgFHAf8BrwGoAZsB/wFbAbsB2gH/Ay0BRQMpAT8DIQExAxYBHwMLAQ8DBAEG\n        AwEBAkQAAwEBAgMEAQYDCwEPAVwBvQHcAf8BXAG8AdoB/wFcAbwB2gH/AVwBvAHaAf8BXAG7AdoB/wFb\n        AbsB2gH/AVsBuwHaAf8BWwG7AdoB/wE6AY4BqQH/AzYBWQM3AVoDNwFaAzUBWAFQAlIBowFnAX0BgwH3\n        AUsBpQHCAf8BTAGnAcQB/wFaAboB2AH/AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/AVoBugHYAf8BWgG6\n        AdgB/wFaAboB2AH/AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/\n        AVoBugHYAf8BWgG6AdgB/wFaAboB2AH/AcABpAGKAf8B7QGWAUcB/wGvAagBmwH/AVsBuwHaAf8DLQFF\n        AykBPwMhATEDFgEfAwsBDwMEAQYDAQEC/wAtAAMBAQIDDwEUAyoBQAM+AWwE/wP2Af8D9wH/A/gB/wP4\n        Af8D+QH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP+\n        Af8D/gH/A/4B/wP+Af8D/QH/A/sB/wP6Af8D9wH/A/QB/wPxAf8D7gH/A+sB/wPnAf8B2gLZAf8CvgG9\n        Af8DoQH/A/AB/wPjAf8D1QH/A8gB/wNSAacDFgEfAwcBCgMBAQJYAAMBAQIDBQEHAxQBGwFeAb4B3AH/\n        AV0BvQHcAf8BXQG9AdwB/wFcAb0B2wH/AVwBvQHbAf8BXAG8AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8\n        AdsB/wE6AY4BqAH/AVACUQGfAWcBfQGDAfcBSAGhAb4B/wE/AZYBsgH/ATkBjgGpAf8BNQGJAaQB/wE1\n        AYkBpAH/AUEBmAG0Af8BWwG7AdkB/wFbAbsB2QH/AVsBuwHZAf8BWwG7AdkB/wFbAbsB2QH/AVsBugHZ\n        Af8BWwG6AdkB/wFbAboB2QH/AVsBugHZAf8BWwG6AdkB/wFbAboB2QH/AVsBugHZAf8BWwG6AdgB/wFb\n        AboB2AH/AVsBugHYAf8BWwG6AdgB/wHEAakBkQH/AfUBngFPAf8BswGtAZ8B/wFbAbsB2QH/AykBPwMo\n        AT0DJQE3Ax0BKgMUARsDCgENAwQBBQMBAQI8AAMBAQIDBQEHAxQBGwFeAb4B3AH/AV0BvQHcAf8BXQG9\n        AdwB/wFcAb0B2wH/AVwBvQHbAf8BXAG8AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8AdsB/wE6AY4BqAH/\n        AVACUQGfAWcBfQGDAfcBSAGhAb4B/wE/AZYBsgH/ATkBjgGpAf8BNQGJAaQB/wE1AYkBpAH/AUEBmAG0\n        Af8BWwG7AdkB/wFbAbsB2QH/AVsBuwHZAf8BWwG7AdkB/wFbAbsB2QH/AVsBugHZAf8BWwG6AdkB/wFb\n        AboB2QH/AVsBugHZAf8BWwG6AdkB/wFbAboB2QH/AVsBugHZAf8BWwG6AdgB/wFbAboB2AH/AVsBugHY\n        Af8BWwG6AdgB/wHEAakBkQH/AfUBngFPAf8BswGtAZ8B/wFbAbsB2QH/AykBPwMoAT0DJQE3Ax0BKgMU\n        ARsDCgENAwQBBQMBAQL/ACkAAwEBAgMPARQDKgFAAz4BbAT/A/YB/wP3Af8D+AH/A/gB/wP5Af8D+gH/\n        A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/A/0B/wP9Af8D/QH/A/4B/wP+Af8D/gH/\n        A/4B/wP9Af8D+wH/A/oB/wP3Af8D9AH/A/IB/wPvAf8D7AH/A+gB/wLfAd4B/wPGAf8BpAKjAf8DyQH/\n        A+8B/wPiAf8D1QH/A8gB/wNYAbsDFgEfAwcBCQMAAQFQAAMBAQIDBQEHAyQBNQFfAb8B3gH/AV4BvgHd\n        Af8BXQG+Ad0B/wFdAb4B3QH/AV0BvgHdAf8BXQG+AdwB/wFdAb0B3AH/AV0BvQHcAf8BXQG9AdwB/wFd\n        Ab0B3AH/AToBjgGpAf8BPAGRAa0B/wE1AYgBowH/ATIBhAGfAf8BMAGCAZ0B/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wE8AZIBrgH/AVsBuwHaAf8BWwG7AdoB/wFbAbsB2gH/AVsBuwHaAf8BWwG7AdoB/wFb\n        AbsB2QH/AVsBuwHZAf8BWwG7AdkB/wFbAbsB2QH/AVsBuwHZAf8BWwG7AdkB/wFbAbsB2QH/AVsBuwHZ\n        Af8BWwG7AdkB/wFbAbsB2QH/AVsBuwHZAf8BygGtAZUB/wH9Ab8BlQH/AbgB0AHZAf8BXAG8AdoB/wMl\n        ATcDJAE2AyMBNAMfAS0DGgEkAxEBFwMIAQsDBAEFAwEBAjQAAwEBAgMFAQcDJAE1AV8BvwHeAf8BXgG+\n        Ad0B/wFdAb4B3QH/AV0BvgHdAf8BXQG+Ad0B/wFdAb4B3AH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/\n        AV0BvQHcAf8BOgGOAakB/wE8AZEBrQH/ATUBiAGjAf8BMgGEAZ8B/wEwAYIBnQH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/ATwBkgGuAf8BWwG7AdoB/wFbAbsB2gH/AVsBuwHaAf8BWwG7AdoB/wFbAbsB2gH/\n        AVsBuwHZAf8BWwG7AdkB/wFbAbsB2QH/AVsBuwHZAf8BWwG7AdkB/wFbAbsB2QH/AVsBuwHZAf8BWwG7\n        AdkB/wFbAbsB2QH/AVsBuwHZAf8BWwG7AdkB/wHKAa0BlQH/Af0BvwGVAf8BuAHQAdkB/wFcAbwB2gH/\n        AyUBNwMkATYDIwE0Ax8BLQMaASQDEQEXAwgBCwMEAQUDAQEC/wAlAAMBAQIDDwEUAyoBQAM+AWwE/wP2\n        Af8D9wH/A/gB/wP4Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP9\n        Af8D/QH/A/0B/wP+Af8D/gH/A/4B/wP+Af8D/QH/A/wB/wP6Af8D+AH/A/UB/wPyAf8D8AH/A+0B/wPq\n        Af8D4gH/As4BzQH/A6sB/wOSAf8D/AH/A+8B/wPiAf8D1QH/A8gB/wNSAacDFgEeAwcBCQMAAQFMAAMD\n        AQQDLwFKAWABwAHgAf8BXgHAAd8B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHe\n        Af8BXgG+Ad0B/wFeAb4B3QH/AV4BvgHdAf8BXgG+Ad0B/wE6AY8BqQH/AS8BggGdAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOwGRAawB/wFcAbwB2gH/AVwBvAHa\n        Af8BXAG8AdoB/wFcAbwB2gH/AVwBvAHaAf8BXAG8AdoB/wFcAbwB2gH/AVwBvAHaAf8BXAG8AdoB/wFc\n        AbwB2gH/AVwBvAHaAf8BXAG8AdoB/wFcAbsB2gH/AVwBuwHaAf8BXAG7AdoB/wFbAbsB2gH/AcsB5gHx\n        Bf8BuAHdAe0B/wFcAbwB2gH/AyABLgMgAS4DHwEsAx0BKQMaASUDFQEdAw4BEwMHAQkDAwEEAwEBAjAA\n        AwMBBAMvAUoBYAHAAeAB/wFeAcAB3wH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/\n        Ad4B/wFeAb4B3QH/AV4BvgHdAf8BXgG+Ad0B/wFeAb4B3QH/AToBjwGpAf8BLwGCAZ0B/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE7AZEBrAH/AVwBvAHaAf8BXAG8\n        AdoB/wFcAbwB2gH/AVwBvAHaAf8BXAG8AdoB/wFcAbwB2gH/AVwBvAHaAf8BXAG8AdoB/wFcAbwB2gH/\n        AVwBvAHaAf8BXAG8AdoB/wFcAbwB2gH/AVwBuwHaAf8BXAG7AdoB/wFcAbsB2gH/AVsBuwHaAf8BywHm\n        AfEF/wG4Ad0B7QH/AVwBvAHaAf8DIAEuAyABLgMfASwDHQEpAxoBJQMVAR0DDgETAwcBCQMDAQQDAQEC\n        /wAhAAMBAQIDDwEUAyoBQAM+AWwE/wP2Af8D9wH/AvgB9wH/A/gB/wP5Af8D+QH/A/oB/wP6Af8D+gH/\n        A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/A/0B/wP9Af8D/QH/A/0B/wP+Af8D/gH/A/4B/wP+Af8D/AH/\n        A/sB/wP5Af8D9gH/A/MB/wPxAf8D7gH/A+sB/wPmAf8B1QLUAf8DsgH/A5MF/wP7Af8D7gH/A+EB/wPU\n        Af8DxwH/A0sBjgMUARwDBgEIAwABAUgAAwQBBQFfAcAB4AH/AWABwgHhAf8BYAHBAeEB/wFfAcAB4AH/\n        AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAb8B3wH/AV4BvwHeAf8BXgG/\n        Ad4B/wE6AY8BqQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BOwGRAawB/wFcAb0B2wH/AVwBvAHbAf8BXAG8AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8\n        AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8AdsB/wFcAbwB2wH/\n        AVwBvAHbAf8BXAG8AdsB/wFcAbwB2gH/AcoB5gHxBf8BuQHeAe0B/wFcAbwB2gH/AxoBJQMaASUDGgEl\n        AxkBIwMYASEDFQEdAxEBFwMLAQ8DBgEIAwIBAwMAAQEsAAMEAQUBXwHAAeAB/wFgAcIB4QH/AWABwQHh\n        Af8BXwHAAeAB/wFfAcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwG/Ad8B/wFe\n        Ab8B3gH/AV4BvwHeAf8BOgGPAakB/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/ATsBkQGsAf8BXAG9AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8AdsB/wFc\n        AbwB2wH/AVwBvAHbAf8BXAG8AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8AdsB/wFcAbwB2wH/AVwBvAHb\n        Af8BXAG8AdsB/wFcAbwB2wH/AVwBvAHbAf8BXAG8AdoB/wHKAeYB8QX/AbkB3gHtAf8BXAG8AdoB/wMa\n        ASUDGgElAxoBJQMZASMDGAEhAxUBHQMRARcDCwEPAwYBCAMCAQMDAAEB/wAdAAMBAQIDDwEUAyoBQAM+\n        AWwE/wP2Af8D9wH/A/cB/wP4Af8D+QH/A/kB/wP6Af8D+gH/A/oB/wP7Af8D+wH/A/sB/wP8Af8D/AH/\n        A/wB/wP8Af8D/QH/A/0B/wP9Af8D/gH/A/4B/wP+Af8D/gH/A/0B/wP7Af8D+gH/A/cB/wP1Af8D8gH/\n        A+8B/wPtAf8D6QH/A9oB/wG5ArgB/wGYApcJ/wP7Af8D7gH/A+EB/wPUAf8DxwH/A0ABbgMSARkDBAEG\n        AwABAUQAAwIBAwFhAcQB4wH/AWEBwwHiAf8BYQHDAeIB/wFgAcEB4QH/AWABwQHhAf8BYAHBAeEB/wFg\n        AcEB4AH/AWABwQHgAf8BXwHBAeAB/wFfAcEB4AH/AV8BwAHgAf8BXwHAAeAB/wE6AY8BqQH/AS8BggGd\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOwGRAawB/wFd\n        Ab0B3AH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/AV0BvQHc\n        Af8BXQG9AdsB/wFdAb0B2wH/AV0BvQHbAf8BXAG9AdsB/wFcAb0B2wH/AVwBvQHbAf8BXAG9AdsB/wFc\n        Ab0B2wH/AcoB5gHyBf8BuQHeAe0B/wFcAbwB2wH/AxcBIAMWAR8DFQEdAxQBHAMUARsDEgEZAxEBFwMN\n        ARIDCgENAwUBBwMCAQMDAAEBKAADAgEDAWEBxAHjAf8BYQHDAeIB/wFhAcMB4gH/AWABwQHhAf8BYAHB\n        AeEB/wFgAcEB4QH/AWABwQHgAf8BYAHBAeAB/wFfAcEB4AH/AV8BwQHgAf8BXwHAAeAB/wFfAcAB4AH/\n        AToBjwGpAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wE7AZEBrAH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/\n        AV0BvQHcAf8BXQG9AdwB/wFdAb0B2wH/AV0BvQHbAf8BXQG9AdsB/wFcAb0B2wH/AVwBvQHbAf8BXAG9\n        AdsB/wFcAb0B2wH/AVwBvQHbAf8BygHmAfIF/wG5Ad4B7QH/AVwBvAHbAf8DFwEgAV4CWwHQA1IBpgMk\n        ATYDFAEbAxIBGQMRARcDDQESAwoBDQMFAQcDAgEDAwABAf8AGQADAQECAw8BFAMqAUADPgFsBP8D9gH/\n        A/cB/wP3Af8D+AH/A/kB/wP5Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/\n        A/0B/wP9Af8D/QH/A/4B/wP+Af8D/gH/A/4B/wP9Af8D/AH/A/oB/wP5Af8D9gH/A/MB/wPxAf8D7gH/\n        A+sB/wPeAf8DwAH/A54N/wP7Af8D7QH/A+AB/wPUAf8DxwH/AzEBTQMQARYDBAEFSAABYgHFAeUB/wFi\n        AcQB5AH/AWIBxAHjAf8BYQHDAeIB/wFhAcIB4gH/AWEBwgHiAf8BYQHCAeIB/wFgAcIB4gH/AWABwgHh\n        Af8BYAHCAeEB/wFgAcIB4QH/AWABwQHhAf8BOgGPAakB/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATsBkQGtAf8BXQG+Ad0B/wFdAb4B3QH/AV0BvgHd\n        Af8BXQG+Ad0B/wFdAb4B3AH/AV0BvgHcAf8BXQG+AdwB/wFdAb4B3AH/AV0BvQHcAf8BXQG9AdwB/wFd\n        Ab0B3AH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/AV0BvQHcAf8BXQG9AdwB/wHMAecB8gX/AbkB3gHu\n        Af8BXQG9AdsB/wMSARkDEgEYAxEBFwMRARcDEAEVAw8BFAMOARMDDQESAwoBDgMHAQoDBAEGAwEBAgMA\n        AQEoAAFiAcUB5QH/AWIBxAHkAf8BYgHEAeMB/wFhAcMB4gH/AWEBwgHiAf8BYQHCAeIB/wFhAcIB4gH/\n        AWABwgHiAf8BYAHCAeEB/wFgAcIB4QH/AWABwgHhAf8BYAHBAeEB/wE6AY8BqQH/AS8BggGdAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOwGRAa0B/wFdAb4B3QH/\n        AV0BvgHdAf8BXQG+Ad0B/wFdAb4B3QH/AV0BvgHcAf8BXQG+AdwB/wFdAb4B3AH/AV0BvgHcAf8BXQG9\n        AdwB/wFdAb0B3AH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/AV0BvQHcAf8BXQG9AdwB/wFdAb0B3AH/\n        AcwB5wHyBf8BuQHeAe4B/wFdAb0B2wH/AWICWAHpAf0BtwGRAf8B9gGkAWkB/wHcAUkBJgH/AW0BRgFC\n        AfUDTgGYAw4BEwMNARIDCgEOAwcBCgMEAQYDAQECAwABAf8AFQADAQECAw8BFAMqAUADPgFsBP8D9gH/\n        AvcB9gH/A/cB/wP4Af8D+AH/A/kB/wP6Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8\n        Af8D/QH/A/0B/wP9Af8D/QH/A/4B/wP+Af8D/gH/A/4B/wP9Af8D+wH/A/oB/wP3Af8D9QH/A/IB/wPw\n        Af8D7gH/A+UB/wPNAf8DsAH/AqABnwH/A5oB/wOWAf8BlwKWAf8BywLKAf8D7QH/A+AB/wPTAf8DxgH/\n        AyUBNwMOARMDAwEERAABYwHFAeYB/wFjAcUB5QH/AWMBxQHlAf8BYgHEAeQB/wFiAcQB4wH/AWIBwwHj\n        Af8BYQHDAeMB/wFhAcMB4wH/AWEBwwHjAf8BYQHDAeMB/wFhAcMB4gH/AWEBwwHiAf8BOgGPAakB/wEv\n        AYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATsBkQGt\n        Af8BXgG+Ad0B/wFeAb4B3QH/AV4BvgHdAf8BXgG+Ad0B/wFeAb4B3QH/AV4BvgHdAf8BXgG+Ad0B/wFd\n        Ab4B3QH/AV0BvgHdAf8BXQG+Ad0B/wFdAb4B3QH/AV0BvgHdAf8BXQG+Ad0B/wFdAb4B3QH/AV0BvgHd\n        Af8BXQG+Ad0B/wHMAecB8wX/AbkB3wHuAf8BXQG9AdwB/wMOARMDDwEUAw0BEgMNARIDDQERAw0BEQML\n        AQ8DCgEOAwoBDQMIAQsDBgEIAwMBBAMBAQIDAAEBJAABYwHFAeYB/wFjAcUB5QH/AWMBxQHlAf8BYgHE\n        AeQB/wFiAcQB4wH/AWIBwwHjAf8BYQHDAeMB/wFhAcMB4wH/AWEBwwHjAf8BYQHDAeMB/wFhAcMB4gH/\n        AWEBwwHiAf8BOgGPAakB/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/ATsBkQGtAf8BXgG+Ad0B/wFeAb4B3QH/AV4BvgHdAf8BXgG+Ad0B/wFeAb4B3QH/\n        AV4BvgHdAf8BXgG+Ad0B/wFdAb4B3QH/AV0BvgHdAf8BXQG+Ad0B/wFdAb4B3QH/AV0BvgHdAf8BXQG+\n        Ad0B/wFdAb4B3QH/AV0BvgHdAf8BXQG+Ad0B/wHMAecB8wX/AbkB3wHuAf8BXQG9AdwB/wHcAUkBJgH/\n        Af0BtgGQAf8B/AGzAY4B/wH8Aa8BigH/AfwBrQGIAf8B8gGUAVkB/wHWATkBFgH/A1YBtgMaASQDCAEL\n        AwYBCAMDAQQDAQECAwABAf8AEQADAQECAw8BFAMqAUADPgFsBP8D9gH/A/YB/wP3Af8D+AH/A/gB/wP5\n        Af8D+gH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP+\n        Af8D/gH/A/4B/wP+Af8D/QH/A/wB/wP7Af8D+QH/A/cB/wP0Af8D8gH/A/AB/wPqAf8D3QH/A80B/wPD\n        Af8CvQG8Af8DtwH/A7EB/wOtAf8DrAH/ArcBtgH/A9sB/wPTAf8DxgH/AyABLgMMARADAgEDQAABYwHG\n        AecB/wFkAcYB5gH/AWQBxgHmAf8BYwHFAeUB/wFjAcUB5QH/AWIBxQHlAf8BYgHEAeQB/wFiAcQB5AH/\n        AWIBxAHkAf8BYgHEAeQB/wFiAcQB5AH/AWIBxAHkAf8BOgGPAakB/wEvAYIBnQH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATsBkQGtAf8BXgG/Ad4B/wFeAb8B3gH/\n        AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/\n        Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvgHdAf8BXgG+Ad0B/wHLAecB8wX/\n        AboB3wHuAf8BXQG9AdwB/wMLAQ8DDAEQAwoBDgMKAQ4DCgENAwkBDAMJAQwDCQEMAwgBCwMHAQoDBgEI\n        AwQBBgMCAQMDAAEBJAABYwHGAecB/wFkAcYB5gH/AWQBxgHmAf8BYwHFAeUB/wFjAcUB5QH/AWIBxQHl\n        Af8BYgHEAeQB/wFiAcQB5AH/AWIBxAHkAf8BYgHEAeQB/wFiAcQB5AH/AWIBxAHkAf8BOgGPAakB/wEv\n        AYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATsBkQGt\n        Af8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFe\n        Ab8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvgHd\n        Af8BXgG+Ad0B/wHLAecB8wX/AboB3wHuAf8BXQG9AdwB/wHYAT0BGQH/AfIBmgFfAf8B/AG2AZEB/wH8\n        Aa8BigH/AfsBqwGGAf8B+wGoAYMB/wH7AaQBaQH/AfUBlgFbAf8BrwFAAT8B/QNDAXgDBgEIAwQBBgMC\n        AQMDAAEB/wARAAMBAQIDDwEUAyoBQAM+AWwE/wL2AfUB/wP2Af8D9wH/A/cB/wP4Af8D+QH/A/kB/wP6\n        Af8D+gH/A/oB/wP7Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/QH/A/0B/wP9Af8D/QH/A/4B/wP+\n        Af8D/gH/A/4B/wP9Af8D+wH/A/oB/wP4Af8D9gH/A/QB/wPyAf8D7wH/A+oB/wPlAf8D4AH/A9wB/wHZ\n        AtgB/wPUAf8DzwH/A8oB/wLKAckB/wHQAs8B/wPaAf8D1gH/A6sB/QMdASkDCgENAwEBAjwAAWUByAHo\n        Af8BZQHHAegB/wFlAccB6AH/AWQBxgHmAf8BZAHGAeYB/wFjAcYB5gH/AWMBxgHmAf8BYwHGAeYB/wFj\n        AcUB5QH/AWMBxQHlAf8BYwHFAeUB/wFjAcUB5QH/AToBjwGqAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE7AZEBrQH/AV8BwAHfAf8BXwHAAd8B/wFf\n        AcAB3wH/AV8BwAHfAf8BXwG/Ad8B/wFfAb8B3wH/AV8BvwHfAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHe\n        Af8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BywHnAfMF/wG6\n        Ad8B7wH/AV0BvgHcAf8DCAELAwkBDAMIAQsDCAELAwcBCgMHAQkDBwEJAwcBCQMGAQgDBQEHAwUBBwME\n        AQYDAgEDAwABASQAAWUByAHoAf8BZQHHAegB/wFlAccB6AH/AWQBxgHmAf8BZAHGAeYB/wFjAcYB5gH/\n        AWMBxgHmAf8BYwHGAeYB/wFjAcUB5QH/AWMBxQHlAf8BYwHFAeUB/wFjAcUB5QH/AToBjwGqAf8BLwGC\n        AZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE7AZEBrQH/\n        AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwG/Ad8B/wFfAb8B3wH/AV8BvwHfAf8BXgG/\n        Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/AV4BvwHeAf8BXgG/Ad4B/wFeAb8B3gH/\n        AV4BvwHeAf8BywHnAfMF/wG6Ad8B7wH/AV0BvgHcAf8B6gGQAVUB/wH1AbEBiwH/AeIBXgE7Af8B1gE4\n        ARUB/wHvAY4BUwH/AfsBqAGDAf8B+wGkAWkB/wH6AaEBZgH/AfoBngFjAf8BqAFMASkB/gM/AW0DBAEG\n        AwIBAwMAAQH/ABEAAwEBAgMPARQDKgFAAz4BbAT/A/UB/wP2Af8D9wH/A/cB/wP4Af8C+QH4Af8D+QH/\n        A/oB/wP6Af8D+gH/A/oB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP9Af8D/gH/\n        A/4B/wP+Af8D/gH/A/4B/wP8Af8D+wH/A/oB/wP4Af8D9gH/A/QB/wPyAf8D8AH/A+8B/wPsAf8D6wH/\n        A+kB/wPnAf8D5AH/A+IB/wHgAt8B/wHhAuAB/wPjAf8D5gH/A+gB/wNpAfIDFwEgAwUBBzwAAWYByQHp\n        Af8BZgHJAekB/wFmAckB6QH/AWUBxwHoAf8BZAHHAegB/wFkAccB5wH/AWQBxwHnAf8BZAHHAecB/wFk\n        AccB5wH/AWQBxgHnAf8BZAHGAecB/wFkAcYB5gH/ATsBkAGqAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE7AZEBrQH/AV8BwAHfAf8BXwHAAd8B/wFf\n        AcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHf\n        Af8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BzQHoAfMF/wG6\n        AeAB7wH/AV4BvgHdAf8DBgEIAwcBCQMGAQgDBQEHAwUBBwMEAQYDBAEGAwQBBQMEAQUDAwEEAwMBBAMB\n        AQIDAQECAwABASQAAWYByQHpAf8BZgHJAekB/wFmAckB6QH/AWUBxwHoAf8BZAHHAegB/wFkAccB5wH/\n        AWQBxwHnAf8BZAHHAecB/wFkAccB5wH/AWQBxgHnAf8BZAHGAecB/wFkAcYB5gH/ATsBkAGqAf8BLwGC\n        AZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE7AZEBrQH/\n        AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwHA\n        Ad8B/wFfAcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/AV8BwAHfAf8BXwHAAd8B/wFfAcAB3wH/\n        AV8BwAHfAf8BzQHoAfMF/wG6AeAB7wH/AV4BvgHdAf8B6gGPAVQB/wH2AbcBkAH/AfEBowFoAf8B6wGR\n        AVYB/wHjAWIBPgH/AdQBNAERAf8B+AGfAWQB/wH6AaEBZgH/AfoBnQFiAf8B+gGaAWAB/wHWATgBFQH/\n        AxEBFwMBAQIDAAEB/wARAAMBAQIDDwEUAyoBQAM+AWwE/wP1Af8D9gH/A/YB/wP3Af8D+AH/A/gB/wP5\n        Af8D+gH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP9\n        Af8D/gH/A/4B/wP+Af8D/gH/A/0B/wP8Af8D+wH/A/oB/wP4Af8D9gH/A/QB/wPzAf8D8QH/A/AB/wPu\n        Af8D7QH/A+wB/wPsAf8D6wH/AesC6gH/A+oB/wPrAf8D6wH/A+wB/wPuAf8DIwEzAwoBDgMAAQE4AAFn\n        AcoB6wH/AWcBygHrAf8BZwHKAeoB/wFmAckB6QH/AWUByQHpAf8BZQHIAekB/wFlAcgB6QH/AWUByAHp\n        Af8BZQHIAegB/wFlAcgB6AH/AWUByAHoAf8BZQHHAegB/wE7AZABqgH/AS8BggGdAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOwGRAa0B/wFgAcEB4AH/AWABwQHg\n        Af8BYAHBAeAB/wFfAcEB4AH/AV8BwQHgAf8BXwHBAeAB/wFfAcEB4AH/AV8BwQHgAf8BXwHBAeAB/wFf\n        AcEB4AH/AV8BwAHgAf8BXwHAAeAB/wFfAcAB4AH/AV8BwAHgAf8BXwHAAeAB/wFfAcAB4AH/Ac0B6AHz\n        Bf8BugHgAe8B/wFfAb8B3QH/AwMEBAEGAwQBBQMEAQUDAwEEAwIBAwMCAQMDAQECAwEBAgMBAQIDAAEB\n        AwABAQMAAQEoAAFnAcoB6wH/AWcBygHrAf8BZwHKAeoB/wFmAckB6QH/AWUByQHpAf8BZQHIAekB/wFl\n        AcgB6QH/AWUByAHpAf8BZQHIAegB/wFlAcgB6AH/AWUByAHoAf8BZQHHAegB/wE7AZABqgH/AS8BggGd\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOwGRAa0B/wFg\n        AcEB4AH/AWABwQHgAf8BYAHBAeAB/wFfAcEB4AH/AV8BwQHgAf8BXwHBAeAB/wFfAcEB4AH/AV8BwQHg\n        Af8BXwHBAeAB/wFfAcEB4AH/AV8BwAHgAf8BXwHAAeAB/wFfAcAB4AH/AV8BwAHgAf8BXwHAAeAB/wFf\n        AcAB4AH/Ac0B6AHzBf8BugHgAe8B/wFfAb8B3QH/AeYBgQFGAf8B9gG3AZAB/wHxAaMBaAH/AesBkQFW\n        Af8B5QFpAUUB/wHgAVkBNQH/AdcBPAEZAf8B+QGfAWQB/wH6AZ0BYgH/AfoBmQFfAf8B9wGTAVkB/wFa\n        AlgBwAMAAQH/ABUAAwEBAgMPARQDKgFAAz4BbAT/A/UB/wL2AfUB/wP2Af8D9wH/AvgB9wH/A/gB/wP5\n        Af8D+QH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP8Af8D/QH/A/0B/wP9\n        Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP9Af8D/AH/A/sB/wP6Af8D+AH/A/cB/wP1Af8D8wH/A/IB/wPx\n        Af8D8AH/A+8B/wPuAf8D7gH/A+4B/wPuAf8D7gH/A+4B/wPvAf8D7wH/AygBPQMNARIDAAEBOAABaAHL\n        AewB/wFoAcsB7AH/AWgBywHsAf8BZgHKAesB/wFmAcoB6wH/AWYBygHqAf8BZgHJAeoB/wFmAckB6gH/\n        AWYByQHqAf8BZgHJAeoB/wFmAckB6QH/AWUByQHpAf8BOwGQAaoB/wEvAYIBnQH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AToBkAGsAf8BYAHBAeEB/wFgAcEB4QH/\n        AWABwQHhAf8BYAHBAeEB/wFgAcEB4QH/AWABwQHhAf8BYAHBAeEB/wFgAcEB4QH/AWABwQHhAf8BYAHB\n        AeEB/wFgAcEB4AH/AWABwQHgAf8BYAHBAeAB/wFgAcEB4AH/AWABwQHgAf8BYAHBAeAB/wHNAegB9AX/\n        AbsB4AHwAf8BYgHBAd4B/wMBBAIBAwMCAQMDAQECAwABAQMAAQEDAAEBQAABaAHLAewB/wFoAcsB7AH/\n        AWgBywHsAf8BZgHKAesB/wFmAcoB6wH/AWYBygHqAf8BZgHJAeoB/wFmAckB6gH/AWYByQHqAf8BZgHJ\n        AeoB/wFmAckB6QH/AWUByQHpAf8BOwGQAaoB/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AToBkAGsAf8BYAHBAeEB/wFgAcEB4QH/AWABwQHhAf8BYAHB\n        AeEB/wFgAcEB4QH/AWABwQHhAf8BYAHBAeEB/wFgAcEB4QH/AWABwQHhAf8BYAHBAeEB/wFgAcEB4AH/\n        AWABwQHgAf8BYAHBAeAB/wFgAcEB4AH/AWABwQHgAf8BYAHBAeAB/wHNAegB9AX/AbsB4AHwAf8BYgHB\n        Ad4B/wIxATABTQHbAUkBJQH/AfEBpQGAAf8B6wGRAVYB/wHlAWkBRQH/AeABWAE0Af8B2wFJASUB/wHU\n        ATUBEgH/AfoBngFjAf8B+gGZAV8B/wH5AZYBXAH/AYkBRwFBAfn/ABkAAwEBAgMPARQDKgFAAz4BbAT/\n        A/UB/wL2AfUB/wP2Af8D9wH/A/cB/wP4Af8D+AH/A/kB/wP6Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7\n        Af8D/AH/A/wB/wP8Af8D/AH/A/0B/wP9Af8D/QH/A/0B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/0B/wP8\n        Af8D+wH/A/oB/wP5Af8D9wH/A/YB/wP1Af8D9AH/A/MB/wPyAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx\n        Af8D8gH/A/IB/wMpAT8DDgETAwEBAjgAAWkBzQHuAf8BaQHNAe4B/wFpAcwB7QH/AWcBywHsAf8BZwHL\n        AewB/wFnAcsB7AH/AWcBywHsAf8BZwHLAesB/wFnAcoB6wH/AWcBygHrAf8BZwHKAesB/wFmAcoB6wH/\n        ATsBkAGqAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wE0AYgBowH/AVEBrgHMAf8BYAHCAeIB/wFgAcIB4gH/AWABwgHhAf8BYAHCAeEB/wFgAcIB4QH/\n        AWABwgHhAf8BYAHCAeEB/wFgAcIB4QH/AWABwgHhAf8BYAHCAeEB/wFgAcIB4QH/AWABwgHhAf8BYAHC\n        AeEB/wFgAcIB4QH/AWABwgHhAf8BgAHHAeQB/wFeAcAB4QH/AV8BwQHhAf8BZQHCAeAB/wcAAQFUAAFp\n        Ac0B7gH/AWkBzQHuAf8BaQHMAe0B/wFnAcsB7AH/AWcBywHsAf8BZwHLAewB/wFnAcsB7AH/AWcBywHr\n        Af8BZwHKAesB/wFnAcoB6wH/AWcBygHrAf8BZgHKAesB/wE7AZABqgH/AS8BggGdAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BNAGIAaMB/wFRAa4BzAH/AWABwgHi\n        Af8BYAHCAeIB/wFgAcIB4QH/AWABwgHhAf8BYAHCAeEB/wFgAcIB4QH/AWABwgHhAf8BYAHCAeEB/wFg\n        AcIB4QH/AWABwgHhAf8BYAHCAeEB/wFgAcIB4QH/AWMBuwHWAf8BKQFGAVIB/wFfAcAB3wH/AYABxwHk\n        Af8BXgHAAeEB/wFfAcEB4QH/AWUBwgHgAf8HAAEBAVgCVgG7AekBjAFRAf8B5QFpAUUB/wHgAVgBNAH/\n        AdsBSQElAf8B1wE6ARcB/wH6AZ4BYwH/AfoBmQFfAf8B+QGWAVwB/wHWATkBFgH//wAZAAMBAQIDDwEU\n        AyoBQAM+AWwE/wL1AfQB/wP1Af8D9gH/A/YB/wP3Af8D+AH/A/gB/wP5Af8D+QH/A/oB/wP6Af8D+gH/\n        A/sB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP8Af8D/QH/A/0B/wP9Af8D/QH/A/4B/wP+Af8D/gH/\n        A/4F/wP9Af8D/AH/A/wB/wP7Af8D+gH/A/kB/wP3Af8D9gH/A/YB/wP1Af8D9AH/A/QB/wP0Af8D8wH/\n        A/QB/wP0Af8D9AH/A/UB/wMqAUADDwEUAwEBAjgAAYABzgHvAf8BgAHOAe8B/wGAAc4B7wH/AWgBzQHu\n        Af8BaAHMAe4B/wFoAcwB7QH/AWgBzAHtAf8BaAHMAe0B/wFoAcwB7QH/AWgBzAHtAf8BaAHLAewB/wFn\n        AcsB7AH/ATsBkAGrAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/ATYBigGlAf8BRwGiAb4B/wFhAcIB4gH/AWEBwwHiAf8BYQHDAeIB/wFh\n        AcMB4gH/AWEBwgHiAf8BYQHCAeIB/wFhAcIB4gH/AWEBwgHiAf8BYQHCAeIB/wFhAcIB4gH/AWEBwgHi\n        Af8BYQHCAeIB/wFhAcIB4gH/AWEBwgHiAf8BYAHCAeIB/wFgAcIB4gH/AWABwgHiAf8BZgHDAeAB/1wA\n        AYABzgHvAf8BgAHOAe8B/wGAAc4B7wH/AWgBzQHuAf8BaAHMAe4B/wFoAcwB7QH/AWgBzAHtAf8BaAHM\n        Ae0B/wFoAcwB7QH/AWgBzAHtAf8BaAHLAewB/wFnAcsB7AH/ATsBkAGrAf8BLwGCAZ0B/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATYBigGlAf8BRwGi\n        Ab4B/wFhAcIB4gH/AWEBwwHiAf8BYQHDAeIB/wFhAcMB4gH/AWEBwgHiAf8BYQHCAeIB/wFhAcIB4gH/\n        AWEBwgHiAf8BYQHCAeIB/wFiAbABygH/AdABNAETAf8B9AGuAYgB/wHuAZsBXwH/AT4BQAFFAf8BYAHC\n        AeIB/wFgAcIB4gH/AWABwgHiAf8BZgHDAeAB/wwAAkoBSQGJAeYBgQFGAf8B4AFZATUB/wHbAUkBJQH/\n        AdUBNwEUAf8B+gGeAWQB/wH6AZkBXwH/AfkBlgFcAf8B2wFBAR4B//8AGQADAQECAw8BFAMqAUADPgFs\n        BP8D9AH/A/UB/wL2AfUB/wP2Af8D9wH/A/cB/wP4Af8C+QH4Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP7\n        Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/AH/A/0B/wP9Af8D/QH/A/0B/wP+Af8D/gH/A/4B/wP+\n        Af8D/gH/A/4B/wP9Af8D/AH/A/sB/wP7Af8D+gH/A/kB/wP4Af8D+AH/A/cB/wP3Af8D9gH/A/YB/wP3\n        Af8D9wH/A/cB/wP4Af8DKgFAAw8BFAMBAQI4AAGBAc8B8QH/AYEBzwHxAf8BgQHPAfEB/wFpAc4B7wH/\n        AWkBzgHvAf8BaQHOAe8B/wFpAc0B7wH/AWkBzQHvAf8BaQHNAe4B/wFpAc0B7gH/AWkBzQHuAf8BaAHN\n        Ae4B/wFcAbsB2gH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATsBkQGtAf8BXwHAAeAB/wFhAcMB4wH/AWEBwwHjAf8BYQHD\n        AeMB/wFhAcMB4wH/AWEBwwHjAf8BYQHDAeMB/wFhAcMB4wH/AWEBwwHjAf8BYQHDAeMB/wFhAcMB4wH/\n        AWEBwwHiAf8BYQHDAeIB/wFhAcMB4gH/AWEBwwHiAf8BYQHDAeIB/wFhAcMB4gH/AWUBwAHaAf9cAAGB\n        Ac8B8QH/AYEBzwHxAf8BgQHPAfEB/wFpAc4B7wH/AWkBzgHvAf8BaQHOAe8B/wFpAc0B7wH/AWkBzQHv\n        Af8BaQHNAe4B/wFpAc0B7gH/AWkBzQHuAf8BaAHNAe4B/wFcAbsB2gH/AS8BgQGcAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATsBkQGt\n        Af8BXwHAAeAB/wFhAcMB4wH/AWEBwwHjAf8BYQHDAeMB/wFhAcMB4wH/AWEBwwHjAf8BYQHDAeMB/wFh\n        AcMB4wH/AbQBPgEnAf8B4wFiAT0B/wH4AbgBkgH/AfoBwgGbAf8B/gHMAaUB/wGXATgBKAH/AWEBwwHi\n        Af8BYQHDAeIB/wFhAcMB4gH/AWUBwAHaAf8QAAHXAT0BGQH/AeABWAE0Af8B2QFEASAB/wHsAYEBSAH/\n        AfoBnQFiAf8B+gGZAV8B/wH5AZUBWwH/AdoBQAEdAf//ABkAAwEBAgMPARQDKgFAAz4BbAT/A/QB/wL1\n        AfQB/wP1Af8D9gH/AvcB9gH/A/cB/wP4Af8D+AH/A/kB/wP5Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7\n        Af8D+wH/A/wB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/4B/wP+Af8D/gH/A/4B/wP+\n        Af8D/gH/A/0B/wP9Af8D/AH/A/sB/wP7Af8D+gH/A/oB/wP6Af8D+gH/A/kB/wP5Af8D+QH/A/oB/wP6\n        Af8D+gH/AyoBQAMPARQDAQECOAABggHRAfMB/wGCAdEB8gH/AYIB0AHyAf8BgAHPAfEB/wGAAc8B8QH/\n        AYABzwHwAf8BgAHPAfAB/wGAAc8B8AH/AYABzgHwAf8BgAHOAfAB/wGAAc4B7wH/AWkBzgHvAf8BaQHO\n        Ae8B/wFnAcsB7AH/ATEBgwGeAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wE4AY0BqQH/AWABwQHhAf8BYgHEAeQB/wFiAcQB5AH/AWIBxAHkAf8BYgHE\n        AeMB/wFiAcQB4wH/AWIBxAHjAf8BYgHEAeMB/wFiAcQB4wH/AWIBxAHjAf8BYgHEAeMB/wFiAcMB4wH/\n        AWIBwwHjAf8BYgHDAeMB/wFhAcMB4wH/AWEBwwHjAf8BiQHQAeoB/wFfAWgBbAHzXAABggHRAfMB/wGC\n        AdEB8gH/AYIB0AHyAf8BgAHPAfEB/wGAAc8B8QH/AYABzwHwAf8BgAHPAfAB/wGAAc8B8AH/AYABzgHw\n        Af8BgAHOAfAB/wGAAc4B7wH/AWkBzgHvAf8BaQHOAe8B/wFnAcsB7AH/ATEBgwGeAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE4AY0BqQH/AWABwQHh\n        Af8BYgHEAeQB/wFiAcQB5AH/AWIBxAHkAf8BYgHEAeMB/wFiAcQB4wH/AYgBmAGkAf8B1QE3ARQB/wHy\n        AacBgAH/AfUBrwGIAf8B9wG4AZEB/wH6AcQBnQH/Af4BywGkAf8BnQE3ASYB/wFhAcMB4wH/AWEBwwHj\n        Af8BiQHQAeoB/wFfAWgBbAHzEAABqgFPASwB/gHWATsBGAH/Ae4BhgFMAf8B+gGhAWYB/wH6AZ0BYgH/\n        AfoBmQFfAf8B+QGSAVgB/wHXATwBGQH//wAZAAMBAQIDDwEUAyoBQAM+AWwE/wP0Af8C9QH0Af8D9QH/\n        AvYB9QH/A/YB/wP3Af8D9wH/A/gB/wL5AfgB/wP5Af8D+gH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/\n        A/sB/wP8Af8D/AH/A/wB/wP8Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP+Af8D/gH/A/4B/wP+Af8D/gH/\n        A/4B/wP+Af8D/gH/A/0B/wP8Af8D/AH/A/wB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D/AH/\n        AyoBQAMPARQDAQECOAABgwHSAfQB/wGDAdIB9AH/AYMB0gH0Af8BgQHRAfIB/wGBAdAB8gH/AYEB0AHy\n        Af8BgQHQAfIB/wGBAdAB8gH/AYEB0AHxAf8BgQHQAfEB/wGBAc8B8QH/AYABzwHxAf8BgAHPAfEB/wGA\n        Ac8B8AH/ATsBkAGqAf8BLwGBAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wE4AYwBqAH/AWABwQHhAf8BYgHEAeQB/wFiAcQB5AH/AWIBxAHkAf8BYgHEAeQB/wFi\n        AcQB5AH/AWIBxAHkAf8BYgHEAeQB/wFiAcQB5AH/AWIBxAHkAf8BYgHEAeQB/wFiAcQB5AH/AWIBxAHk\n        Af8BYgHEAeQB/wGSAdwB8QH/A2EB4gMxAU9gAAGDAdIB9AH/AYMB0gH0Af8BgwHSAfQB/wGBAdEB8gH/\n        AYEB0AHyAf8BgQHQAfIB/wGBAdAB8gH/AYEB0AHyAf8BgQHQAfEB/wGBAdAB8QH/AYEBzwHxAf8BgAHP\n        AfEB/wGAAc8B8QH/AYABzwHwAf8BOwGQAaoB/wEvAYEBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATgBjAGoAf8BYAHBAeEB/wFiAcQB5AH/AWIBxAHkAf8BYgHE\n        AeQB/wFjAbkB1QH/Ac4BNgEWAf8B5wGEAUkB/wHvAZ0BYgH/AfIBpgGAAf8B9gGlAWkB/wH5AZcBXQH/\n        AfoBrwGRAf8B/AG9AZcB/wGdATcBJgH/AZIB3AHxAf8DYQHiAzEBTwwAAzIBUAFlAl4B5QHfAU8BLAH/\n        AfsBqQGEAf8B+wGkAWkB/wH6AaEBZgH/AfoBnQFiAf8B+QGRAVcB/wHsAZUBWQH/AdcBPQEaAf//ABkA\n        AwEBAgMPARQDKgFAAz4BbAT/AvQB8wH/A/QB/wL1AfQB/wP1Af8D9gH/A/YB/wP3Af8D+AH/A/gB/wP5\n        Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP7Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/AH/A/0B/wP9\n        Af8D/QH/A/0B/wP9Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/0B/wP9\n        Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/AyoBQAMPARQDAQECOAABhAHUAfYB/wGEAdMB9QH/\n        AYQB0wH1Af8BgwHSAfQB/wGCAdIB9AH/AYIB0gH0Af8BggHRAfMB/wGCAdEB8wH/AYIB0QHzAf8BggHR\n        AfMB/wGCAdEB8wH/AYEB0QHyAf8BgQHQAfIB/wGBAdAB8gH/ATwBkQGrAf8BLwGCAZ0B/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE4AYwBqAH/AWEBwgHhAf8BYwHF\n        AeUB/wFjAcUB5QH/AWMBxQHlAf8BYwHFAeUB/wFjAcUB5QH/AWMBxQHlAf8BYwHFAeUB/wFjAcUB5QH/\n        AWMBxQHlAf8BYgHFAeUB/wFiAcUB5QH/AWIBxQHlAf8BYgHFAeUB/wEsAWIBjQH/aAABhAHUAfYB/wGE\n        AdMB9QH/AYQB0wH1Af8BgwHSAfQB/wGCAdIB9AH/AYIB0gH0Af8BggHRAfMB/wGCAdEB8wH/AYIB0QHz\n        Af8BggHRAfMB/wGCAdEB8wH/AYEB0QHyAf8BgQHQAfIB/wGBAdAB8gH/ATwBkQGrAf8BLwGCAZ0B/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE4AYwBqAH/AWEBwgHh\n        Af8BYwHFAeUB/wFjAcUB5QH/AasBQgEvAf8B2gFFASEB/wHpAYsBUAH/AewBlAFYAf8B7wGdAWEB/wH5\n        AZABVgH/Af0B1AG5Av8B4QHIAv8B5AHOAf8B+QGSAVgB/wGbATcBJAH/AS4BXAGFAf8DDgETA1EBogNf\n        AeAB1QE3ARQB/wHZAUABHQH/AfYBogFoAf8B/AGxAYwB/wH7AasBhgH/AfsBqAGDAf8B+wGkAWkB/wH5\n        AZ8BZAH/AfkBkgFYAf8B9wG6AZQB/wHtAZsBXwH/AdkBRAEgAf//ABkAAwEBAgMPARQDKgFAAz4BbAT/\n        A/MB/wP0Af8C9QH0Af8D9QH/AvYB9QH/A/YB/wP3Af8D9wH/A/gB/wP4Af8D+QH/A/kB/wP6Af8D+gH/\n        A/oB/wP6Af8D+wH/A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP9Af8D/QH/\n        A/0B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4F/wP+Af8D/gH/A/4B/wP+Bf8D/gH/\n        A/4B/wMqAUADDwEUAwEBAjgAAYUB1QH3Af8BhQHVAfcB/wGFAdUB9wH/AYQB0wH2Af8BgwHTAfUB/wGD\n        AdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdIB9QH/AYMB0gH0Af8BgwHSAfQB/wGCAdIB9AH/AYIB0gH0\n        Af8BggHSAfQB/wE8AZEBqwH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BOAGMAakB/wFhAcMB4gH/AWMBxgHmAf8BYwHGAeYB/wFjAcYB5gH/AWMBxgHm\n        Af8BYwHGAeYB/wFjAcUB5QH/AWMBxQHlAf8BYwHFAeUB/wFjAcUB5QH/AWMBxQHlAf8BYwHFAeUB/wFj\n        AcUB5QH/AWMBxQHlAf8BGAFMAWIB/2gAAYUB1QH3Af8BhQHVAfcB/wGFAdUB9wH/AYQB0wH2Af8BgwHT\n        AfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdIB9QH/AYMB0gH0Af8BgwHSAfQB/wGCAdIB9AH/\n        AYIB0gH0Af8BggHSAfQB/wE8AZEBqwH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BOAGMAakB/wFhAcMB4gH/AYQBpgG3Af8B1gE3ARQB/wHjAWMBPwH/\n        AecBgwFIAf8B6QGLAVAB/wH0AZIBWAH/AfsBqwGJAv8B3gHCAv8B3wHFAv8B4AHIAv8B5AHNAf8B+QGS\n        AVgB/wHrAZEBVgH/AfEBogFmAf8B9gGyAYwB/wH8Ab0BlwH/Af0BvwGZAf8B/QG7AZUB/wH9AbYBkAH/\n        AfwBswGOAf8B/AGvAYoB/wH7AasBhgH/AfoBogFnAf8B+QGPAVUB/wH9AcoBrgL/AdABqgH/AfkBvgGX\n        Af8B8AGgAWUB/wHaAUYBIgH//wAZAAMBAQIDDwEUAyoBQAM+AWwE/wPzAf8C9AHzAf8D9AH/AvUB9AH/\n        A/UB/wP2Af8D9gH/A/cB/wL4AfcB/wP4Af8D+QH/A/kB/wP6Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7\n        Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/4B/wP+\n        Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/AyoBQAMP\n        ARQDAQECOAABhgHWAfkB/wGGAdYB+QH/AYYB1gH4Af8BhQHVAfcB/wGEAdUB9wH/AYQB1AH3Af8BhAHU\n        AfcB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdMB9gH/AYMB0wH2Af8BgwHTAfUB/wGDAdMB9QH/\n        ATwBkQGsAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wE4AYwBqQH/AWIBwwHiAf8BZAHGAeYB/wFkAcYB5gH/AWQBxgHmAf8BZAHGAeYB/wFkAcYB5gH/\n        AWQBxgHmAf8BZAHGAeYB/wFkAcYB5gH/AWQBxgHmAf8BYwHGAeYB/wFjAcYB5gH/AWMBxgHmAf8BYwHG\n        AeYB/wEYAUsBYQH/aAABhgHWAfkB/wGGAdYB+QH/AYYB1gH4Af8BhQHVAfcB/wGEAdUB9wH/AYQB1AH3\n        Af8BhAHUAfcB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdMB9gH/AYMB0wH2Af8BgwHTAfUB/wGD\n        AdMB9QH/ATwBkQGsAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wE6AYgBowH/AcsBOQEZAf8B3AFLAScB/wHiAVwBOAH/AeQBZAFAAf8B6AGFAUoB/wH5\n        AZIBWAH/Af4B2AG5Av8B2wG9Av8B3AHAAv8B3gHEAv8B4AHHAv8B4wHMAf8B+QGSAVgC/wHMAaUB/wH+\n        AcgBoQH/Af4BxQGfAf8B/gHBAZsB/wH9Ab0BlwH/Af0BugGUAf8B/QG3AZEB/wH7Aa0BhwH/AfkBlgFb\n        Af8B+QGaAWIB/wH9AeIB1gL/AewB3gL/AeABxwL/AdIBrwH/AfoBwgGcAf8B8QGmAYEB/wHbAUcBJAH/\n        /wAZAAMBAQIDDwEUAyoBQAM+AWwE/wLzAfIB/wPzAf8D9AH/A/QB/wP1Af8C9gH1Af8D9gH/AvcB9gH/\n        A/cB/wP4Af8D+AH/A/kB/wP5Af8D+gH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D/AH/\n        A/wB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/gH/A/4B/wP+Af8D/gH/\n        A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/AyoBQAMPARQDAQECOAABhwHYAfsB/wGH\n        AdgB+gH/AYcB1wH6Af8BhgHWAfkB/wGGAdYB+QH/AYUB1gH4Af8BhQHWAfgB/wGFAdUB+AH/AYUB1QH4\n        Af8BhQHVAfgB/wGFAdUB9wH/AYUB1QH3Af8BhAHVAfcB/wGEAdQB9wH/ATwBkQGsAf8BLwGCAZ0B/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE4AY0BqQH/AWIBxAHj\n        Af8BZAHHAecB/wFkAccB5wH/AWQBxwHnAf8BZAHHAecB/wFkAccB5wH/AWQBxwHnAf8BZAHHAecB/wFk\n        AccB5wH/AWQBxwHnAf8BZAHHAecB/wFkAccB5wH/AWQBxwHnAf8BZAHGAecB/wEYAUsBYQH/aAABhwHY\n        AfsB/wGHAdgB+gH/AYcB1wH6Af8BhgHWAfkB/wGGAdYB+QH/AYUB1gH4Af8BhQHWAfgB/wGFAdUB+AH/\n        AYUB1QH4Af8BhQHVAfgB/wGFAdUB9wH/AYUB1QH3Af8BhAHVAfcB/wGEAdQB9wH/ATwBkQGsAf8BLwGC\n        AZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BhAFPAU0B/wHWAToBFwH/\n        AdwBTAEoAf8B3wFUATAB/wHhAVsBNwH/AfcBjwFVAf8B/AG7AZgC/wHXAbcC/wHZAboC/wHbAb0C/wHc\n        AcAC/wHeAcMC/wHgAcYC/wHjAcwB/wH5AZIBWAL/Ac4BpwH/Af0BwwGdAf8B+wGyAYwB/wH5AZ8BZAH/\n        AfkBkAFVAf8B+QGNAVEB/wH7AbUBmwH/Af4B9QHuAv8B/AH6Av8C/gL/AfcB8QL/Ae0B4AL/AeIBywL/\n        AdQBsgH/AfsBxQGfAf8B8wGrAYYB/wHbAUcBJAH//wAZAAMBAQIDDwEUAyoBQAM+AWwE/wLzAfIB/wPz\n        Af8C9AHzAf8D9AH/AvUB9AH/A/UB/wL2AfUB/wP2Af8D9wH/A/cB/wP4Af8D+AH/A/kB/wP5Af8D+gH/\n        A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/QH/\n        A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/\n        A/4B/wP+Af8DKgFAAw8BFAMBAQI4AAGIAdkB/AH/AYcB2QH8Af8BhwHZAfwB/wGHAdgB+wH/AYcB1wH6\n        Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHWAfkB/wGF\n        AdYB+QH/AYUB1gH4Af8BPAGRAawB/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/ATgBjQGpAf8BYgHEAeQB/wFlAcgB6AH/AWUBxwHoAf8BZQHHAegB/wFl\n        AccB6AH/AWUBxwHoAf8BZAHHAegB/wFkAccB6AH/AWQBxwHoAf8BZAHHAecB/wFkAccB5wH/AWQBxwHn\n        Af8BZAHHAecB/wFkAccB5wH/ARcBSwFhAf9oAAGIAdkB/AH/AYcB2QH8Af8BhwHZAfwB/wGHAdgB+wH/\n        AYcB1wH6Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHW\n        AfkB/wGFAdYB+QH/AYUB1gH4Af8BPAGRAawB/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wHXATsBGAH/AdoBRQEhAf8B3AFMASgB/wHoAWIBPgH/AfkBmAFeAf8B/gHU\n        AbIC/wHWAbQC/wHXAbYC/wHZAbkC/wHaAbwC/wHcAb8C/wHeAcMC/wHfAcYC/wHiAcoB/wH9Ac0BtAH/\n        Af0B1gG/Af8B/gHfAcsB/wH+AesB2gL/Ae8B4gL/AfEB5QL/AfMB6QL/AfUB7gL/AfgB8wL/AfsB+AL/\n        Av4C/wH5AfUC/wHvAeQC/wHkAc8C/wHXAbcB/wH8AckBogH/AfUBsQGLAf8BkgFKASgB+/8AGQADAQEC\n        Aw8BFAMqAUADPgFsBP8D8gH/AvMB8gH/A/MB/wL0AfMB/wP0Af8D9QH/A/UB/wP2Af8D9gH/A/cB/wP3\n        Af8D+AH/A/gB/wP5Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/wB/wP8\n        Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9\n        Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8DKgFAAw8BFAMBAQI4AAGJAdoB/AH/AYgB2gH8Af8BiAHa\n        AfwB/wGIAdkB+wH/AYgB2QH7Af8BhwHZAfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/\n        AYcB2AH7Af8BhwHYAfoB/wGHAdcB+gH/AYYB1wH6Af8BPAGSAawB/wEvAYIBnQH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATgBjQGpAf8BYgHFAeUB/wFlAcgB6QH/\n        AWUByAHpAf8BZQHIAekB/wFlAcgB6QH/AWUByAHpAf8BZQHIAegB/wFlAcgB6AH/AWUByAHoAf8BZQHI\n        AegB/wFlAcgB6AH/AWUByAHoAf8BZQHIAegB/wFlAcgB6AH/ARoBTwFlAf9oAAGJAdoB/AH/AYgB2gH8\n        Af8BiAHaAfwB/wGIAdkB+wH/AYgB2QH7Af8BhwHZAfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGH\n        AdgB+wH/AYcB2AH7Af8BhwHYAfoB/wGHAdcB+gH/AYYB1wH6Af8BPAGSAawB/wEvAYIBnQH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BNwFnAZQB/wHYAT4BGwH/AdoBRQEhAf8B+QGRAVcB/wH9\n        AcgBowL/AdMBrwL/AdQBsQL/AdUBswL/AdcBtgL/AdgBuQL/AdoBvAL/AdsBvgL/Ad0BwgL/Ad8BxQL/\n        AeEByQL/AeQBzQL/AeYB0QL/AegB1gL/AeoB2gL/Ae0B3wL/AfAB5AL/AfIB6AL/AfUB7QL/AfcB8gL/\n        AfoB+AL/Af4B/QL/AfoB9wL/AfEB5wL/AeYB0wL/AdkBvAH/Af0BzAGlAf8B9AGxAYsB/wFIAkcBg/8A\n        GQADAQECAw8BFAMqAUADPgFsBP8C8gHxAf8D8gH/AvMB8gH/A/MB/wP0Af8D9AH/A/UB/wL2AfUB/wP2\n        Af8C9wH2Af8D9wH/AvgB9wH/A/gB/wL5AfgB/wP5Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP7Af8D+wH/\n        A/sB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/QH/A/0B/wP9Af8D/QH/\n        A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wMqAUADDwEUAwEBAjgAAYoB3AH8\n        Af8BiQHcAfwB/wGJAdsB/AH/AYkB2gH7Af8BiAHaAfsB/wGIAdoB+wH/AYgB2gH7Af8BiAHaAfsB/wGI\n        AdkB+wH/AYgB2QH7Af8BiAHZAfsB/wGIAdkB+wH/AYcB2QH7Af8BhwHZAfsB/wE8AZIBrAH/AS8BggGd\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOAGNAakB/wFj\n        AcUB5QH/AWYByQHpAf8BZQHJAekB/wFlAckB6QH/AWUByQHpAf8BZQHJAekB/wFlAckB6QH/AWUByQHp\n        Af8BZQHJAekB/wFlAcgB6QH/AWUByAHpAf8BZQHIAekB/wFlAcgB6QH/AWQByAHpAf8BIwFaAYgB/2gA\n        AYoB3AH8Af8BiQHcAfwB/wGJAdsB/AH/AYkB2gH7Af8BiAHaAfsB/wGIAdoB+wH/AYgB2gH7Af8BiAHa\n        AfsB/wGIAdkB+wH/AYgB2QH7Af8BiAHZAfsB/wGIAdkB+wH/AYcB2QH7Af8BhwHZAfsB/wE8AZIBrAH/\n        AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wHTATcBFgH/AesBYQE+Af8B+gGj\n        AWgC/wHRAasC/wHSAa0C/wHTAa8C/wHUAbAC/wHVAbMC/wHWAbUC/wHYAbgC/wHaAbwC/wHbAb4C/wHd\n        AcIC/wHfAcUC/wHhAckC/wHjAc0C/wHlAdAC/wHoAdUC/wHqAdkC/wHtAd4C/wHwAeMC/wHyAecC/wH0\n        AewC/wH3AfEC/wH6AfcC/wH9AfwC/wH8AfkC/wHzAeoC/wHoAdYC/wHcAcAB/wH+AdABqQH/AdYBNwEU\n        Af//AB0AAwEBAgMPARQDKgFAAz4BbAT/A/EB/wLyAfEB/wLzAfIB/wPzAf8C9AHzAf8D9AH/AvUB9AH/\n        A/UB/wL2AfUB/wP2Af8C9wH2Af8D9wH/AvgB9wH/A/gB/wL5AfgB/wP5Af8D+QH/A/oB/wP6Af8D+gH/\n        A/oB/wP6Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/\n        A/wB/wP8Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/AyoBQAMPARQDAQEC\n        OAABiwHdAfwB/wGKAd0B/AH/AYoB3QH8Af8BiQHcAfsB/wGJAdsB+wH/AYkB2wH7Af8BiQHbAfsB/wGJ\n        AdsB+wH/AYkB2wH7Af8BiQHbAfsB/wGJAdoB+wH/AYkB2gH7Af8BiAHaAfsB/wGIAdoB+wH/ATwBkgGs\n        Af8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE4\n        AY0BqQH/AWMBxQHmAf8BZgHJAeoB/wFmAckB6gH/AWYByQHqAf8BZgHJAeoB/wFmAckB6gH/AWYByQHq\n        Af8BZgHJAeoB/wFmAckB6gH/AWYByQHqAf8BZgHJAeoB/wFmAckB6gH/AWYByQHqAf8BZQHJAeoB/wEi\n        AVoBiAH/aAABiwHdAfwB/wGKAd0B/AH/AYoB3QH8Af8BiQHcAfsB/wGJAdsB+wH/AYkB2wH7Af8BiQHb\n        AfsB/wGJAdsB+wH/AYkB2wH7Af8BiQHbAfsB/wGJAdoB+wH/AYkB2gH7Af8BiAHaAfsB/wGIAdoB+wH/\n        ATwBkgGsAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AdUBNwEUAf8B/gHK\n        AaQC/wHQAaoC/wHQAasC/wHRAawC/wHSAa4C/wHTAbAC/wHVAbMC/wHWAbUC/wHYAbgC/wHZAbsC/wHb\n        Ab0C/wHdAcEC/wHeAcQC/wHhAcgC/wHjAcwC/wHlAdAC/wHnAdQC/wHpAdgC/wHsAd0C/wHvAeIC/wHx\n        AeYC/wH0AesC/wH2AfAC/wH5AfUC/wH9AfsC/wH9AfsC/wH1Ae0C/wHqAdoC/wHgAcYB/wGrAVQBMAH+\n        /wAhAAMBAQIDDwEUAyoBQAM+AWwE/wPxAf8C8gHxAf8D8gH/AvMB8gH/A/MB/wL0AfMB/wP0Af8C9QH0\n        Af8D9QH/AvYB9QH/A/YB/wP3Af8D9wH/A/gB/wP4Af8C+QH4Af8D+QH/A/kB/wP6Af8D+gH/A/oB/wP6\n        Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8\n        Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/AyoBQAMPARQDAQECOAABjAHe\n        Af0B/wGLAd4B/QH/AYoB3gH9Af8BigHdAfwB/wGKAd0B/AH/AYoB3QH8Af8BigHcAfwB/wGKAdwB+wH/\n        AYoB3AH7Af8BigHcAfsB/wGKAdwB+wH/AYkB3AH7Af8BiQHbAfsB/wGJAdsB+wH/AT0BkgGsAf8BLwGC\n        AZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE5AY0BqQH/\n        AWQBxgHnAf8BZgHKAesB/wFmAcoB6wH/AWYBygHrAf8BZgHKAesB/wFmAcoB6wH/AWYBygHrAf8BZgHK\n        AesB/wFmAcoB6gH/AWYBygHqAf8BZgHKAeoB/wFmAcoB6gH/AWYBygHqAf8BZQHKAeoB/wEiAVkBiAH/\n        aAABjAHeAf0B/wGLAd4B/QH/AYoB3gH9Af8BigHdAfwB/wGKAd0B/AH/AYoB3QH8Af8BigHcAfwB/wGK\n        AdwB+wH/AYoB3AH7Af8BigHcAfsB/wGKAdwB+wH/AYkB3AH7Af8BiQHbAfsB/wGJAdsB+wH/AT0BkgGs\n        Af8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AekBigFPAv8BzwGoAv8B0AGp\n        Av8B0AGqAv8B0QGsAv8B0gGuAv8B0wGwAv8B1QGyAv8B1gG0Av8B1wG3Av8B2QG7Av8B2gG9Av8B3AHA\n        Av8B3gHDAv8B4AHHAv8B4wHMAv8B5AHPAv8B5wHUAv8B6QHXAv8B7AHcAv8B7wHhAv8B8QHlAv8B9AHr\n        Av8B9gHvAv8B+QH1Av8B/AH6Av8B/gH9Av8B9gHwAv8B9QHoAf8B1QE1ARIB//8AJQADAQECAw8BFAMq\n        AUADPgFsBP8C8QHwAf8D8QH/AvIB8QH/A/IB/wLzAfIB/wPzAf8C9AHzAf8D9AH/AvUB9AH/A/UB/wP2\n        Af8D9gH/A/cB/wP3Af8D+AH/A/gB/wP4Af8D+QH/A/kB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP7\n        Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8\n        Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8DKgFAAw8BFAMBAQI4AAGNAeAB/QH/AYwB4AH9Af8BiwHf\n        Af0B/wGLAd4B/AH/AYsB3gH8Af8BiwHeAfwB/wGLAd4B/AH/AYsB3QH8Af8BiwHdAfwB/wGLAd0B/AH/\n        AYoB3QH8Af8BigHdAfwB/wGKAd0B/AH/AYoB3AH8Af8BPQGSAawB/wEvAYIBnQH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATkBjgGpAf8BZAHHAegB/wFnAcsB6wH/\n        AWcBywHrAf8BZwHLAesB/wFnAcsB6wH/AWcBygHrAf8BZwHKAesB/wFnAcoB6wH/AWcBygHrAf8BZwHK\n        AesB/wFnAcoB6wH/AWcBygHrAf8BZwHKAesB/wFmAcoB6wH/ASIBWQGIAf9oAAGNAeAB/QH/AYwB4AH9\n        Af8BiwHfAf0B/wGLAd4B/AH/AYsB3gH8Af8BiwHeAfwB/wGLAd4B/AH/AYsB3QH8Af8BiwHdAfwB/wGL\n        Ad0B/AH/AYoB3QH8Af8BigHdAfwB/wGKAd0B/AH/AYoB3AH8Af8BPQGSAawB/wEvAYIBnQH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BxQE9ASEB/wHzAa0BhwL/AdABqQL/AdABqgL/AdEBrAL/\n        AdIBrgL/AdMBrwL/AdQBsgL/AdYBtAL/AdcBtwL/AdkBugL/AdoBvAL/AdwBwAL/Ad4BwwL/AeABxwL/\n        AeIBywL/AeQBzwL/AecB0wL/AekB1wL/AesB3AL/Ae4B4AL/AfAB5QL/AfMB6gL/AfUB7gL/AfkB9AL/\n        AfwB+QL/Av4B/wHnAZgBggH/AV4CXAHO/wApAAMBAQIDDwEUAyoBQAM+AWwE/wPwAf8C8QHwAf8D8QH/\n        AvIB8QH/A/IB/wLzAfIB/wPzAf8D9AH/A/QB/wP1Af8D9QH/A/YB/wP2Af8D9wH/A/cB/wL4AfcB/wP4\n        Af8D+AH/A/kB/wP5Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7\n        Af8D+wH/A/sB/wP7Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8\n        Af8DKgFAAw8BFAMBAQI4AAGOAeEB/QH/AYwB4QH9Af8BjAHhAf0B/wGMAd8B/AH/AYwB3wH8Af8BjAHf\n        AfwB/wGMAd8B/AH/AYwB3wH8Af8BjAHfAfwB/wGLAd4B/AH/AYsB3gH8Af8BiwHeAfwB/wGLAd4B/AH/\n        AYsB3gH8Af8BPQGSAa0B/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/ATkBjgGpAf8BZAHHAegB/wFnAcsB7AH/AWcBywHsAf8BZwHLAewB/wFnAcsB7AH/\n        AWcBywHsAf8BZwHLAewB/wFnAcsB7AH/AWcBywHsAf8BZwHLAewB/wFnAcsB7AH/AWcBywHsAf8BZwHL\n        AewB/wFmAcsB7AH/ASIBWQGHAf9oAAGOAeEB/QH/AYwB4QH9Af8BjAHhAf0B/wGMAd8B/AH/AYwB3wH8\n        Af8BjAHfAfwB/wGMAd8B/AH/AYwB3wH8Af8BjAHfAfwB/wGLAd4B/AH/AYsB3gH8Af8BiwHeAfwB/wGL\n        Ad4B/AH/AYsB3gH8Af8BPQGSAa0B/wEvAYIBnQH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wFXAVwBZgH/AdUBNwETAf8B/QHQAakC/wHRAasC/wHSAa0C/wHTAa8C/wHUAbEC/wHV\n        AbMC/wHXAbYC/wHZAbkC/wHaAbwC/wHcAb8C/wHdAcIC/wHgAcYC/wHiAcoC/wHkAc4C/wHmAdIC/wHo\n        AdYC/wHrAdsC/wHuAd8C/wHwAeQC/wHyAekC/wH2Ae4B/wH9AfYB8gH/AeQBiwFeAf8BYQJbAeH/ADEA\n        AwEBAgMPARQDKgFAAz4BbAT/AvAB7wH/AvEB8AH/AvEB8AH/AvIB8QH/A/IB/wLzAfIB/wPzAf8D8wH/\n        A/QB/wP0Af8D9QH/A/UB/wP2Af8D9gH/AvcB9gH/A/cB/wL4AfcB/wP4Af8D+AH/A/kB/wP5Af8D+QH/\n        A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/\n        A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wMqAUADDwEUAwEBAjgAAY4B4gH9\n        Af8BjQHiAf0B/wGNAeIB/QH/AY0B4QH8Af8BjQHhAfwB/wGNAeAB/AH/AY0B4AH8Af8BjQHgAfwB/wGM\n        AeAB/AH/AYwB4AH8Af8BjAHgAfwB/wGMAd8B/AH/AYwB3wH8Af8BjAHfAfwB/wE9AZMBrQH/AS8BggGd\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGOAaoB/wFl\n        AcgB6gH/AWgBzAHtAf8BaAHMAe0B/wFoAcwB7QH/AWgBzAHtAf8BaAHMAe0B/wFoAcwB7QH/AWgBzAHt\n        Af8BaAHMAe0B/wFoAcwB7QH/AWgBzAHtAf8BaAHLAewB/wFoAcsB7AH/AWcBywHsAf8BLAFoAZcB/2gA\n        AY4B4gH9Af8BjQHiAf0B/wGNAeIB/QH/AY0B4QH8Af8BjQHhAfwB/wGNAeAB/AH/AY0B4AH8Af8BjQHg\n        AfwB/wGMAeAB/AH/AYwB4AH8Af8BjAHgAfwB/wGMAd8B/AH/AYwB3wH8Af8BjAHfAfwB/wE9AZMBrQH/\n        AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGO\n        AaoB/wG7AVkBSQH/AeQBaAFEAv8B0gGtAv8B0wGvAv8B1AGxAv8B1QGzAv8B1wG2Av8B2AG5Av8B2gG7\n        Av8B2wG/Av8B3QHCAv8B3wHFAv8B4gHKAv8B4wHNAv8B5gHRAv8B6AHVAv8B6wHaAv8B8wHmAf8B+QHb\n        AcwB/wHiAWgBTQH/AdUBOAEVAf8CQAE/AW7/ADkAAwEBAgMPARQDKgFAAz4BbAT/AvAB7wH/AvAB7wH/\n        AvEB8AH/A/EB/wLyAfEB/wPyAf8C8wHyAf8D8wH/AvQB8wH/A/QB/wP0Af8D9QH/A/UB/wP2Af8D9gH/\n        AvcB9gH/A/cB/wP3Af8D+AH/A/gB/wP5Af8D+QH/A/kB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6\n        Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7\n        Af8D+wH/A/sB/wMqAUADDwEUAwEBAjgAAY8B5AH9Af8BjgHjAf0B/wGOAeMB/QH/AY4B4gH8Af8BjgHi\n        AfwB/wGOAeIB/AH/AY4B4gH8Af8BjgHhAfwB/wGNAeEB/AH/AY0B4QH8Af8BjQHhAfwB/wGNAeEB/AH/\n        AY0B4QH8Af8BjQHgAfwB/wE9AZMBrQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGOAaoB/wFlAckB6wH/AWgBzAHuAf8BaAHMAe4B/wFoAcwB7gH/\n        AWgBzAHtAf8BaAHMAe0B/wFoAcwB7QH/AWgBzAHtAf8BaAHMAe0B/wFoAcwB7QH/AWgBzAHtAf8BaAHM\n        Ae0B/wFoAcwB7QH/AWcBzAHtAf8BLAFoAZcB/2gAAY8B5AH9Af8BjgHjAf0B/wGOAeMB/QH/AY4B4gH8\n        Af8BjgHiAfwB/wGOAeIB/AH/AY4B4gH8Af8BjgHhAfwB/wGNAeEB/AH/AY0B4QH8Af8BjQHhAfwB/wGN\n        AeEB/AH/AY0B4QH8Af8BjQHgAfwB/wE9AZMBrQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGOAaoB/wFlAckB6wH/AWgBzAHuAf8B0QE2ARQB/wH3\n        Ab4BmgL/AdQBsQL/AdUBswL/AdYBtQL/AdgBuAL/AdkBuwL/AdsBvgL/Ad0BwQL/Ad8BxQH/AeYBiQFU\n        Af8B2gFIASYB/wHXAT0BGgH/AW8BRwFCAfUBWgJXAb0DSwGO/wBJAAMBAQIDDwEUAyoBQAM+AWwE/wLv\n        Ae4B/wLwAe8B/wPwAf8C8QHwAf8D8QH/AvIB8QH/A/IB/wLzAfIB/wPzAf8C9AHzAf8D9AH/A/QB/wP1\n        Af8D9QH/AvYB9QH/A/YB/wL3AfYB/wP3Af8D9wH/A/gB/wP4Af8D+AH/A/kB/wP5Af8D+QH/A/oB/wP6\n        Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7\n        Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wMqAUADDwEUAwEBAjgAAZAB5QH9Af8BjwHlAf0B/wGPAeUB/QH/\n        AY8B4wH8Af8BjwHjAfwB/wGPAeMB/AH/AY8B4wH8Af8BjgHjAfwB/wGOAeMB/AH/AY4B4gH8Af8BjgHi\n        AfwB/wGOAeIB/AH/AY4B4gH8Af8BjgHiAfwB/wE9AZMBrQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGOAaoB/wFmAckB6wH/AWkBzQHuAf8BaQHN\n        Ae4B/wFpAc0B7gH/AWkBzQHuAf8BaQHNAe4B/wFpAc0B7gH/AWkBzQHuAf8BaQHNAe4B/wFpAc0B7gH/\n        AWkBzQHuAf8BaAHNAe4B/wFoAc0B7gH/AWcBzQHuAf8BLAFoAZcB/2gAAZAB5QH9Af8BjwHlAf0B/wGP\n        AeUB/QH/AY8B4wH8Af8BjwHjAfwB/wGPAeMB/AH/AY8B4wH8Af8BjgHjAfwB/wGOAeMB/AH/AY4B4gH8\n        Af8BjgHiAfwB/wGOAeIB/AH/AY4B4gH8Af8BjgHiAfwB/wE9AZMBrQH/AS8BggGdAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGOAaoB/wFmAckB6wH/AWkBzQHu\n        Af8BaQHNAe4B/wKeAacB/wHXAT0BGgL/AdgBtgL/AdYBtQL/AdgBuAL/AdkBugL/AdsBvgL/AdwBwAL/\n        Ad8BxAH/AdsBSQElAf8BjAGlAbMB/wEsAWgBlwH//wBVAAMBAQIDDwEUAyoBQAM+AWwE/wLvAe4B/wPv\n        Af8C8AHvAf8D8AH/AvEB8AH/A/EB/wLyAfEB/wPyAf8C8wHyAf8D8wH/AvQB8wH/A/QB/wP0Af8C9QH0\n        Af8D9QH/AvYB9QH/A/YB/wP2Af8D9wH/A/cB/wP3Af8D+AH/A/gB/wP4Af8D+QH/A/kB/wP5Af8D+gH/\n        A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/\n        A/oB/wP6Af8D+gH/A/oB/wMqAUADDwEUAwEBAjgAAZEB5gH+Af8BkAHmAf4B/wGQAeYB/AH/AZAB5QH8\n        Af8BkAHlAfwB/wGQAeQB/AH/AY8B5AH8Af8BjwHkAfwB/wGPAeQB/AH/AY8B5AH8Af8BjwHkAfwB/wGP\n        AeMB/AH/AY8B4wH8Af8BjwHjAfwB/wE9AZMBrQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGOAaoB/wFmAcoB7AH/AWkBzgHvAf8BaQHOAe8B/wFp\n        Ac4B7wH/AWkBzgHvAf8BaQHOAe8B/wFpAc4B7wH/AWkBzQHvAf8BaQHNAe8B/wFpAc0B7wH/AWkBzQHv\n        Af8BaQHNAe8B/wFpAc0B7wH/AWgBzQHvAf8BLAFoAZcB/2gAAZEB5gH+Af8BkAHmAf4B/wGQAeYB/AH/\n        AZAB5QH8Af8BkAHlAfwB/wGQAeQB/AH/AY8B5AH8Af8BjwHkAfwB/wGPAeQB/AH/AY8B5AH8Af8BjwHk\n        AfwB/wGPAeMB/AH/AY8B4wH8Af8BjwHjAfwB/wE9AZMBrQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BOQGOAaoB/wFmAcoB7AH/AWkBzgHvAf8BaQHO\n        Ae8B/wFpAc4B7wH/AWkBzgHvAf8BwwFRATwB/wHqAZMBWwL/AdgBuAL/AdkBuQL/AdsBvQL/AdwBwAL/\n        Ad4BwwH/AdQBMQENAf8BYgHAAd8B/wEsAWgBlwH//wBVAAMBAQIDDwEUAyoBQAM+AWwE/wPuAf8C7wHu\n        Af8D7wH/AvAB7wH/A/AB/wLxAfAB/wPxAf8C8gHxAf8D8gH/AvMB8gH/A/MB/wPzAf8D9AH/A/QB/wL1\n        AfQB/wP1Af8C9gH1Af8D9gH/A/YB/wL3AfYB/wP3Af8D9wH/AvgB9wH/A/gB/wP4Af8D+AH/A/kB/wP5\n        Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6\n        Af8D+gH/A/oB/wP6Af8D+gH/AyoBQAMPARQDAQECOAABkgHoAf4B/wGRAecB/gH/AZEB5wH9Af8BkQHm\n        Af0B/wGRAeYB/QH/AZAB5gH9Af8BkAHlAf0B/wGQAeUB/QH/AZAB5QH9Af8BkAHlAfwB/wGQAeUB/AH/\n        AZAB5QH8Af8BkAHkAfwB/wGQAeQB/AH/AT0BkwGtAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE5AY4BqgH/AWcBygHtAf8BgAHOAfAB/wGAAc4B8AH/\n        AYABzgHwAf8BgAHOAfAB/wGAAc4B8AH/AYABzgHwAf8BgAHOAe8B/wGAAc4B7wH/AYABzgHvAf8BaQHO\n        Ae8B/wFpAc4B7wH/AWkBzgHvAf8BaAHOAe8B/wEsAWcBlwH/aAABkgHoAf4B/wGRAecB/gH/AZEB5wH9\n        Af8BkQHmAf0B/wGRAeYB/QH/AZAB5gH9Af8BkAHlAf0B/wGQAeUB/QH/AZAB5QH9Af8BkAHlAfwB/wGQ\n        AeUB/AH/AZAB5QH8Af8BkAHkAfwB/wGQAeQB/AH/AT0BkwGtAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE5AY4BqgH/AWcBygHtAf8BgAHOAfAB/wGA\n        Ac4B8AH/AYABzgHwAf8BgAHOAfAB/wGAAc4B8AH/AYABzgHwAf8B0wEzAREB/wH7AdEBsgL/AdoBvAL/\n        AdwBvwL/Ad4BwwH/AdEBMgEOAf8BaAHOAe8B/wEsAWcBlwH//wBVAAMBAQIDDwEUAyoBQAM+AWwE/wLu\n        Ae0B/wLvAe4B/wLvAe4B/wPvAf8C8AHvAf8D8AH/AvEB8AH/A/EB/wLyAfEB/wPyAf8C8wHyAf8D8wH/\n        A/MB/wL0AfMB/wP0Af8C9QH0Af8D9QH/A/UB/wL2AfUB/wP2Af8D9gH/A/cB/wP3Af8D9wH/A/gB/wP4\n        Af8D+AH/A/gB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6\n        Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8DKgFAAw8BFAMBAQI4AAGTAekB/gH/AZIB6QH+Af8BkgHo\n        Af0B/wGSAecB/QH/AZEB5wH9Af8BkQHnAf0B/wGRAecB/QH/AZEB5wH9Af8BkQHmAf0B/wGRAeYB/QH/\n        AZEB5gH9Af8BkQHmAf0B/wGRAeYB/QH/AZAB5gH9Af8BPQGTAa0B/wEvAYIBnQH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATkBjgGqAf8BZwHLAe0B/wGAAc8B8AH/\n        AYABzwHwAf8BgAHPAfAB/wGAAc8B8AH/AYABzwHwAf8BgAHPAfAB/wGAAc8B8AH/AYABzwHwAf8BgAHP\n        AfAB/wGAAc8B8AH/AYABzwHwAf8BgAHPAfAB/wFpAc8B8AH/AToBkAGqAf9oAAGTAekB/gH/AZIB6QH+\n        Af8BkgHoAf0B/wGSAecB/QH/AZEB5wH9Af8BkQHnAf0B/wGRAecB/QH/AZEB5wH9Af8BkQHmAf0B/wGR\n        AeYB/QH/AZEB5gH9Af8BkQHmAf0B/wGRAeYB/QH/AZAB5gH9Af8BPQGTAa0B/wEvAYIBnQH/AS8BgQGc\n        Af8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/ATkBjgGqAf8BZwHLAe0B/wGA\n        Ac8B8AH/AYABzwHwAf8BgAHPAfAB/wGAAc8B8AH/AYABzwHwAf8BgAHPAfAB/wGAAc8B8AH/AaoBjwGO\n        Af8B3AFQAS4C/wHfAcMC/wHiAccB/wHAAUMBKwH/AWkBzwHwAf8BOgGQAaoB//8AVQADAQECAw8BFAMq\n        AUADPgFsBP8C7gHtAf8C7gHtAf8C7wHuAf8C7wHuAf8D7wH/AvAB7wH/A/AB/wLxAfAB/wPxAf8C8gHx\n        Af8D8gH/AvMB8gH/AvMB8gH/A/MB/wL0AfMB/wP0Af8D9AH/AvUB9AH/A/UB/wL2AfUB/wP2Af8D9gH/\n        A/YB/wP3Af8D9wH/A/cB/wL4AfcB/wP4Af8D+AH/A/gB/wP4Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5\n        Af8D+QH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/AyoBQAMPARQDAQECOAABlAHq\n        Af4B/wGUAeoB/QH/AZMB6gH9Af8BkgHpAf0B/wGSAegB/QH/AZIB6AH9Af8BkgHoAf0B/wGSAegB/QH/\n        AZIB6AH9Af8BkgHoAf0B/wGSAecB/QH/AZIB5wH9Af8BkQHnAf0B/wGRAecB/QH/AT4BlAGtAf8BLwGC\n        AZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE6AY8BqgH/\n        AWgBzAHuAf8BgQHQAfEB/wGBAdAB8QH/AYEBzwHxAf8BgQHPAfEB/wGBAc8B8QH/AYABzwHxAf8BgAHP\n        AfEB/wGAAc8B8QH/AYABzwHxAf8BgAHPAfEB/wGAAc8B8QH/AYABzwHxAf8BaQHPAfEB/wE5AZABqgH/\n        aAABlAHqAf4B/wGUAeoB/QH/AZMB6gH9Af8BkgHpAf0B/wGSAegB/QH/AZIB6AH9Af8BkgHoAf0B/wGS\n        AegB/QH/AZIB6AH9Af8BkgHoAf0B/wGSAecB/QH/AZIB5wH9Af8BkQHnAf0B/wGRAecB/QH/AT4BlAGt\n        Af8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wE6\n        AY8BqgH/AWgBzAHuAf8BgQHQAfEB/wGBAdAB8QH/AYEBzwHxAf8BgQHPAfEB/wGBAc8B8QH/AYABzwHx\n        Af8BgAHPAfEB/wGAAc8B8QH/AYABzwHxAf8BswFpAWIB/wG+AVUBRAH/AYABzwHxAf8BaQHPAfEB/wE5\n        AZABqgH//wBVAAMBAQIDDwEUAyoBQAM+AWwE/wLtAewB/wLuAe0B/wLuAe0B/wLvAe4B/wLvAe4B/wPv\n        Af8C8AHvAf8D8AH/AvEB8AH/A/EB/wLyAfEB/wLyAfEB/wPyAf8C8wHyAf8D8wH/AvQB8wH/A/QB/wP0\n        Af8C9QH0Af8D9QH/A/UB/wL2AfUB/wP2Af8D9gH/A/YB/wP3Af8D9wH/A/cB/wP3Af8D+AH/A/gB/wP4\n        Af8D+AH/A/gB/wL5AfgB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/\n        A/kB/wMqAUADDwEUAwEBAjgAAZUB6wH+Af8BlQHrAf0B/wGUAesB/QH/AZMB6gH9Af8BkwHqAf0B/wGT\n        AeoB/QH/AZMB6QH9Af8BkwHpAf0B/wGTAekB/QH/AZMB6QH9Af8BkwHpAf0B/wGSAekB/QH/AZIB6AH9\n        Af8BkgHoAf0B/wE+AZQBrQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEv\n        AYEBnAH/AS8BgQGcAf8BOwGRAa0B/wFoAcwB7wH/AYEB0AHyAf8BgQHQAfIB/wGBAdAB8gH/AYEB0AHy\n        Af8BgQHQAfIB/wGBAdAB8gH/AYEB0AHyAf8BgQHQAfIB/wGBAdAB8gH/AYEB0AHxAf8BgQHQAfEB/wGB\n        AdAB8QH/AYAB0AHxAf8BOgGQAaoB/2gAAZUB6wH+Af8BlQHrAf0B/wGUAesB/QH/AZMB6gH9Af8BkwHq\n        Af0B/wGTAeoB/QH/AZMB6QH9Af8BkwHpAf0B/wGTAekB/QH/AZMB6QH9Af8BkwHpAf0B/wGSAekB/QH/\n        AZIB6AH9Af8BkgHoAf0B/wE+AZQBrQH/AS8BggGdAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BLwGB\n        AZwB/wEvAYEBnAH/AS8BgQGcAf8BOwGRAa0B/wFoAcwB7wH/AYEB0AHyAf8BgQHQAfIB/wGBAdAB8gH/\n        AYEB0AHyAf8BgQHQAfIB/wGBAdAB8gH/AYEB0AHyAf8BgQHQAfIB/wGBAdAB8gH/AYEB0AHxAf8BgQHQ\n        AfEB/wGBAdAB8QH/AYAB0AHxAf8BOgGQAaoB//8AVQADAQECAw8BFAMqAUADPgFsBP8C7QHsAf8C7QHs\n        Af8C7gHtAf8C7gHtAf8C7wHuAf8C7wHuAf8D7wH/AvAB7wH/A/AB/wLxAfAB/wPxAf8C8gHxAf8C8gHx\n        Af8D8gH/AvMB8gH/A/MB/wPzAf8C9AHzAf8D9AH/A/QB/wL1AfQB/wP1Af8D9QH/AvYB9QH/A/YB/wP2\n        Af8D9gH/AvcB9gH/A/cB/wP3Af8D9wH/A/cB/wL4AfcB/wP4Af8D+AH/A/gB/wP4Af8D+AH/A/gB/wP4\n        Af8D+AH/A/gB/wP4Af8D+AH/A/gB/wP4Af8D+AH/AyoBQAMPARQDAQECOAABlgHtAf4B/wGWAe0B/QH/\n        AZQB7AH9Af8BlAHrAf0B/wGUAesB/QH/AZQB6wH9Af8BlAHrAf0B/wGUAesB/QH/AZQB6gH9Af8BlAHq\n        Af0B/wGTAeoB/QH/AZMB6gH9Af8BkwHqAf0B/wGTAeoB/QH/AT4BlAGtAf8BLwGCAZ0B/wEvAYEBnAH/\n        AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BMQGDAZ4B/wFBAZgBtQH/AYABzgHvAf8BggHR\n        AfMB/wGCAdEB8wH/AYEB0QHyAf8BgQHRAfIB/wGBAdEB8gH/AYEB0QHyAf8BgQHRAfIB/wGBAdEB8gH/\n        AYEB0QHyAf8BgQHQAfIB/wGBAdAB8gH/AYEB0AHyAf8BgAHQAfIB/wE6AZABqgH/aAABlgHtAf4B/wGW\n        Ae0B/QH/AZQB7AH9Af8BlAHrAf0B/wGUAesB/QH/AZQB6wH9Af8BlAHrAf0B/wGUAesB/QH/AZQB6gH9\n        Af8BlAHqAf0B/wGTAeoB/QH/AZMB6gH9Af8BkwHqAf0B/wGTAeoB/QH/AT4BlAGtAf8BLwGCAZ0B/wEv\n        AYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/AS8BgQGcAf8BMQGDAZ4B/wFBAZgBtQH/AYABzgHv\n        Af8BggHRAfMB/wGCAdEB8wH/AYEB0QHyAf8BgQHRAfIB/wGBAdEB8gH/AYEB0QHyAf8BgQHRAfIB/wGB\n        AdEB8gH/AYEB0QHyAf8BgQHQAfIB/wGBAdAB8gH/AYEB0AHyAf8BgAHQAfIB/wE6AZABqgH//wBVAAMB\n        AQIDDwEUAyoBQAM+AWwE/wLsAesB/wLtAewB/wLtAewB/wLuAe0B/wLuAe0B/wLvAe4B/wLvAe4B/wPv\n        Af8C8AHvAf8D8AH/AvEB8AH/AvEB8AH/A/EB/wLyAfEB/wPyAf8C8wHyAf8C8wHyAf8D8wH/AvQB8wH/\n        AvQB8wH/A/QB/wP0Af8C9QH0Af8D9QH/A/UB/wL2AfUB/wP2Af8D9gH/A/YB/wP2Af8C9wH2Af8D9wH/\n        A/cB/wP3Af8D9wH/A/cB/wP3Af8C+AH3Af8C+AH3Af8D+AH/A/gB/wP4Af8D+AH/A/gB/wP4Af8D+AH/\n        AvgB9wH/AyoBQAMPARQDAQECOAABlwHuAf4B/wGWAe4B/QH/AZUB7gH9Af8BlQHtAf0B/wGVAewB/QH/\n        AZUB7AH9Af8BlQHsAf0B/wGVAewB/QH/AZUB7AH9Af8BlQHsAf0B/wGUAesB/QH/AZQB6wH9Af8BlAHr\n        Af0B/wGUAesB/QH/AT4BlAGtAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEvAYEBnAH/\n        ATEBhAGfAf8BPgGVAbEB/wFXAbUB1AH/AYIB0QHzAf8BggHRAfMB/wGCAdEB8wH/AYIB0QHzAf8BggHR\n        AfMB/wGCAdEB8wH/AYIB0QHzAf8BggHRAfMB/wGCAdEB8wH/AYIB0QHzAf8BggHRAfMB/wGCAdEB8wH/\n        AYIB0QHzAf8BgQHRAfMB/wE6AZABqgH/aAABlwHuAf4B/wGWAe4B/QH/AZUB7gH9Af8BlQHtAf0B/wGV\n        AewB/QH/AZUB7AH9Af8BlQHsAf0B/wGVAewB/QH/AZUB7AH9Af8BlQHsAf0B/wGUAesB/QH/AZQB6wH9\n        Af8BlAHrAf0B/wGUAesB/QH/AT4BlAGtAf8BLwGCAZ0B/wEvAYEBnAH/AS8BgQGcAf8BLwGBAZwB/wEv\n        AYEBnAH/ATEBhAGfAf8BPgGVAbEB/wFXAbUB1AH/AYIB0QHzAf8BggHRAfMB/wGCAdEB8wH/AYIB0QHz\n        Af8BggHRAfMB/wGCAdEB8wH/AYIB0QHzAf8BggHRAfMB/wGCAdEB8wH/AYIB0QHzAf8BggHRAfMB/wGC\n        AdEB8wH/AYIB0QHzAf8BgQHRAfMB/wE6AZABqgH//wBVAAMBAQIDDwEUAyoBQAM+AWwE/wLsAesB/wLs\n        AesB/wLtAewB/wLtAewB/wLuAe0B/wLuAe0B/wLvAe4B/wLvAe4B/wPvAf8C8AHvAf8C8AHvAf8C8QHw\n        Af8C8QHwAf8D8QH/AvIB8QH/AvIB8QH/A/IB/wLzAfIB/wPzAf8D8wH/AvQB8wH/A/QB/wP0Af8D9AH/\n        AvUB9AH/A/UB/wP1Af8D9QH/AvYB9QH/A/YB/wP2Af8D9gH/A/YB/wP2Af8C9wH2Af8D9wH/A/cB/wP3\n        Af8D9wH/A/cB/wP3Af8D9wH/A/cB/wP3Af8D9wH/A/cB/wP3Af8DKgFAAw8BFAMBAQI4AAGXAe8C/wGX\n        Ae8B/gH/AZYB7wH+Af8BlgHuAf4B/wGWAe4B/gH/AZYB7gH9Af8BlgHtAf0B/wGWAe0B/QH/AZYB7QH9\n        Af8BlQHtAf0B/wGVAe0B/QH/AZUB7AH9Af8BlQHsAf0B/wGVAewB/QH/AT4BlAGtAf8BLwGCAZ0B/wEv\n        AYEBnAH/AS8BgQGcAf8BMAGCAZ0B/wE4AY0BqAH/AUoBpAHCAf8BZwHLAe4B/wGDAdIB9AH/AYMB0gH0\n        Af8BgwHSAfQB/wGCAdIB9AH/AYIB0gH0Af8BggHSAfQB/wGCAdIB9AH/AYIB0gH0Af8BggHSAfQB/wGC\n        AdIB9AH/AYIB0gH0Af8BggHSAfQB/wGCAdIB9AH/AYIB0gH0Af8BgQHSAfMB/wFIAaEBvgH/aAABlwHv\n        Av8BlwHvAf4B/wGWAe8B/gH/AZYB7gH+Af8BlgHuAf4B/wGWAe4B/QH/AZYB7QH9Af8BlgHtAf0B/wGW\n        Ae0B/QH/AZUB7QH9Af8BlQHtAf0B/wGVAewB/QH/AZUB7AH9Af8BlQHsAf0B/wE+AZQBrQH/AS8BggGd\n        Af8BLwGBAZwB/wEvAYEBnAH/ATABggGdAf8BOAGNAagB/wFKAaQBwgH/AWcBywHuAf8BgwHSAfQB/wGD\n        AdIB9AH/AYMB0gH0Af8BggHSAfQB/wGCAdIB9AH/AYIB0gH0Af8BggHSAfQB/wGCAdIB9AH/AYIB0gH0\n        Af8BggHSAfQB/wGCAdIB9AH/AYIB0gH0Af8BggHSAfQB/wGCAdIB9AH/AYEB0gHzAf8BSAGhAb4B//8A\n        VQADAQECAw8BFAMqAUADPgFsBP8C6wHqAf8C7AHrAf8C7AHrAf8C7QHsAf8C7QHsAf8C7gHtAf8C7gHt\n        Af8D7gH/Au8B7gH/Au8B7gH/AvAB7wH/AvAB7wH/A/AB/wLxAfAB/wLxAfAB/wPxAf8C8gHxAf8D8gH/\n        A/IB/wLzAfIB/wPzAf8D8wH/AvQB8wH/AvQB8wH/A/QB/wP0Af8C9QH0Af8D9QH/A/UB/wP1Af8D9QH/\n        AvYB9QH/AvYB9QH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/\n        A/YB/wP2Af8DKgFAAw8BFAMBAQI4AAGYAfEC/wGUAesB+wH/AZcB8AH+Af8BlwHvAf4B/wGXAe8B/gH/\n        AZcB7wH+Af8BlwHvAf4B/wGXAe4B/gH/AZYB7gH+Af8BlgHuAf4B/wGWAe4B/gH/AZYB7gH+Af8BlgHu\n        Af0B/wGWAe0B/QH/AT4BlAGtAf8BLwGCAZ0B/wEwAYIBnQH/ATUBiQGlAf8BQwGcAbkB/wFeAb8B3wH/\n        AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHT\n        AfUB/wGDAdIB9AH/AYMB0gH0Af8BgwHSAfQB/wGDAdIB9AH/AYMB0gH0Af8BgwHSAfQB/wGDAdIB9AH/\n        AYMB0gH0Af8BggHSAfQB/wFIAaEBvgH/aAABmAHxAv8BlAHrAfsB/wGXAfAB/gH/AZcB7wH+Af8BlwHv\n        Af4B/wGXAe8B/gH/AZcB7wH+Af8BlwHuAf4B/wGWAe4B/gH/AZYB7gH+Af8BlgHuAf4B/wGWAe4B/gH/\n        AZYB7gH9Af8BlgHtAf0B/wE+AZQBrQH/AS8BggGdAf8BMAGCAZ0B/wE1AYkBpQH/AUMBnAG5Af8BXgG/\n        Ad8B/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/\n        AYMB0wH1Af8BgwHSAfQB/wGDAdIB9AH/AYMB0gH0Af8BgwHSAfQB/wGDAdIB9AH/AYMB0gH0Af8BgwHS\n        AfQB/wGDAdIB9AH/AYIB0gH0Af8BSAGhAb4B//8AVQADAQECAw8BFAMqAUADPgFsBP8C6wHqAf8C6wHq\n        Af8C7AHrAf8C7AHrAf8C7QHsAf8C7QHsAf8C7gHtAf8C7gHtAf8D7gH/Au8B7gH/Au8B7gH/A+8B/wLw\n        Ae8B/wPwAf8C8QHwAf8C8QHwAf8D8QH/AvIB8QH/AvIB8QH/A/IB/wLzAfIB/wLzAfIB/wPzAf8D8wH/\n        AvQB8wH/AvQB8wH/A/QB/wP0Af8D9AH/AvUB9AH/AvUB9AH/A/UB/wP1Af8D9QH/A/UB/wP1Af8C9gH1\n        Af8C9gH1Af8C9gH1Af8C9gH1Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wL2AfUB/wL2AfUB/wMqAUADDwEU\n        AwEBAjgAAZkB8gL/AZQB7QH7Af8BmAHyAf4B/wGYAfAB/gH/AZgB8AH+Af8BmAHwAf4B/wGYAfAB/gH/\n        AZcB8AH+Af8BlwHwAf4B/wGXAe8B/gH/AZcB7wH+Af8BlwHvAf4B/wGXAe8B/gH/AZcB7wH+Af8BPgGV\n        Aa0B/wEyAYUBogH/AT8BlgGyAf8BVwG1AdQB/wGEAdMB9wH/AYQB0wH2Af8BhAHTAfYB/wGDAdMB9gH/\n        AYMB0wH2Af8BgwHTAfYB/wGDAdMB9gH/AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHT\n        AfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGCAdMB9QH/\n        AUcBogG+Af9oAAGZAfIC/wGUAe0B+wH/AZgB8gH+Af8BmAHwAf4B/wGYAfAB/gH/AZgB8AH+Af8BmAHw\n        Af4B/wGXAfAB/gH/AZcB8AH+Af8BlwHvAf4B/wGXAe8B/gH/AZcB7wH+Af8BlwHvAf4B/wGXAe8B/gH/\n        AT4BlQGtAf8BMgGFAaIB/wE/AZYBsgH/AVcBtQHUAf8BhAHTAfcB/wGEAdMB9gH/AYQB0wH2Af8BgwHT\n        AfYB/wGDAdMB9gH/AYMB0wH2Af8BgwHTAfYB/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/\n        AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/AYMB0wH1Af8BgwHTAfUB/wGDAdMB9QH/AYMB0wH1Af8BggHT\n        AfUB/wFHAaIBvgH//wBVAAMBAQIDDwEUAyoBQAM+AWwE/wLqAekB/wLrAeoB/wLrAeoB/wLsAesB/wLs\n        AesB/wLtAewB/wLtAewB/wPtAf8C7gHtAf8C7gHtAf8C7wHuAf8C7wHuAf8D7wH/AvAB7wH/AvAB7wH/\n        A/AB/wLxAfAB/wLxAfAB/wPxAf8C8gHxAf8C8gHxAf8D8gH/A/IB/wLzAfIB/wLzAfIB/wPzAf8D8wH/\n        AvQB8wH/AvQB8wH/A/QB/wP0Af8D9AH/A/QB/wL1AfQB/wL1AfQB/wP1Af8D9QH/A/UB/wP1Af8D9QH/\n        A/UB/wP1Af8D9QH/A/UB/wP1Af8D9QH/A/UB/wMqAUADDwEUAwEBAjgAAZoB8wL/AZUB7gH7Af8BmQHz\n        Af4B/wGZAfIB/gH/AZkB8gH+Af8BmQHxAf4B/wGYAfEB/gH/AZgB8QH+Af8BmAHxAf4B/wGYAfEB/gH/\n        AZgB8QH+Af8BmAHwAf4B/wGYAfAB/gH/AZgB8AH+Af8BPgGVAa0B/wFPAaoByQH/AYEBzwHyAf8BhAHU\n        AfcB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/\n        AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHU\n        AfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHTAfYB/wGDAdMB9gH/AUcBogG+Af9oAAGaAfMC/wGVAe4B+wH/\n        AZkB8wH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8QH+Af8BmAHxAf4B/wGYAfEB/gH/AZgB8QH+Af8BmAHx\n        Af4B/wGYAfEB/gH/AZgB8AH+Af8BmAHwAf4B/wGYAfAB/gH/AT4BlQGtAf8BTwGqAckB/wGBAc8B8gH/\n        AYQB1AH3Af8BhAHUAfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHU\n        AfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/\n        AYQB1AH2Af8BhAHUAfYB/wGEAdQB9gH/AYQB0wH2Af8BgwHTAfYB/wFHAaIBvgH//wBVAAMBAQIDDwEU\n        AyoBQAM+AWwE/wHqAekB6AH/AuoB6QH/AusB6gH/AusB6gH/AuwB6wH/AuwB6wH/Au0B7AH/Au0B7AH/\n        Au0B7AH/Au4B7QH/Au4B7QH/A+4B/wLvAe4B/wLvAe4B/wPvAf8C8AHvAf8C8AHvAf8D8AH/AvEB8AH/\n        AvEB8AH/A/EB/wLyAfEB/wLyAfEB/wPyAf8D8gH/AvMB8gH/AvMB8gH/A/MB/wPzAf8D8wH/AvQB8wH/\n        AvQB8wH/AvQB8wH/A/QB/wP0Af8D9AH/A/QB/wP0Af8D9AH/A/QB/wL1AfQB/wL1AfQB/wL1AfQB/wL1\n        AfQB/wP0Af8D9AH/A/QB/wMqAUADDwEUAwEBAjgAAZoB8wL/AZUB7gH7Af8BmQHzAf4B/wGZAfIB/gH/\n        AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHy\n        Af4B/wGZAfIB/gH/AZkB8QH+Af8BPgGUAa0B/wGGAdcB+QH/AYUB1QH3Af8BhAHVAfcB/wGEAdUB9wH/\n        AYQB1QH3Af8BhAHVAfcB/wGEAdUB9wH/AYQB1QH3Af8BhAHVAfcB/wGEAdQB9wH/AYQB1AH3Af8BhAHU\n        AfcB/wGEAdQB9wH/AYQB1AH3Af8BhAHUAfcB/wGEAdQB9wH/AYQB1AH3Af8BhAHUAfcB/wGEAdQB9wH/\n        AYQB1AH3Af8BhAHUAfYB/wGDAdQB9gH/AUcBogG+Af9oAAGaAfMC/wGVAe4B+wH/AZkB8wH+Af8BmQHy\n        Af4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/\n        AZkB8gH+Af8BmQHyAf4B/wGZAfEB/gH/AT4BlAGtAf8BhgHXAfkB/wGFAdUB9wH/AYQB1QH3Af8BhAHV\n        AfcB/wGEAdUB9wH/AYQB1QH3Af8BhAHVAfcB/wGEAdUB9wH/AYQB1QH3Af8BhAHUAfcB/wGEAdQB9wH/\n        AYQB1AH3Af8BhAHUAfcB/wGEAdQB9wH/AYQB1AH3Af8BhAHUAfcB/wGEAdQB9wH/AYQB1AH3Af8BhAHU\n        AfcB/wGEAdQB9wH/AYQB1AH2Af8BgwHUAfYB/wFHAaIBvgH//wBVAAMBAQIDDwEUAyoBQAM+AWwE/wLp\n        AegB/wLpAegB/wLqAekB/wHrAeoB6QH/AusB6gH/AuwB6wH/AuwB6wH/AuwB6wH/Au0B7AH/Au0B7AH/\n        Au4B7QH/Au4B7QH/Au4B7QH/Au8B7gH/Au8B7gH/A+8B/wLwAe8B/wLwAe8B/wPwAf8D8AH/AvEB8AH/\n        AvEB8AH/A/EB/wLyAfEB/wLyAfEB/wLyAfEB/wPyAf8D8gH/AvMB8gH/AvMB8gH/AvMB8gH/A/MB/wPz\n        Af8D8wH/A/MB/wL0AfMB/wL0AfMB/wL0AfMB/wL0AfMB/wL0AfMB/wL0AfMB/wL0AfMB/wL0AfMB/wL0\n        AfMB/wL0AfMB/wL0AfMB/wL0AfMB/wMqAUADDwEUAwEBAjgAAZoB8wL/AZUB7gH7Af8BmQHzAf4B/wGZ\n        AfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+\n        Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BOwGQAagB/wGGAdYB+gH/AYUB1QH4Af8BhQHVAfgB/wGF\n        AdUB+AH/AYUB1QH4Af8BhQHVAfgB/wGFAdUB+AH/AYUB1QH4Af8BhQHVAfgB/wGFAdUB+AH/AYUB1QH4\n        Af8BhQHVAfgB/wGFAdUB+AH/AYUB1QH3Af8BhQHVAfcB/wGFAdUB9wH/AYUB1QH3Af8BhQHVAfcB/wGF\n        AdUB9wH/AYUB1QH3Af8BhAHVAfcB/wGDAdUB9wH/AVYBtAHTAf9oAAGaAfMC/wGVAe4B+wH/AZkB8wH+\n        Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZ\n        AfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/ATsBkAGoAf8BhgHWAfoB/wGFAdUB+AH/AYUB1QH4\n        Af8BhQHVAfgB/wGFAdUB+AH/AYUB1QH4Af8BhQHVAfgB/wGFAdUB+AH/AYUB1QH4Af8BhQHVAfgB/wGF\n        AdUB+AH/AYUB1QH4Af8BhQHVAfgB/wGFAdUB9wH/AYUB1QH3Af8BhQHVAfcB/wGFAdUB9wH/AYUB1QH3\n        Af8BhQHVAfcB/wGFAdUB9wH/AYQB1QH3Af8BgwHVAfcB/wFWAbQB0wH//wBVAAMBAQIDDwEUAyoBQAM+\n        AWwE/wLoAecB/wLpAegB/wLpAegB/wLqAekB/wLqAekB/wLrAeoB/wLsAesB/wLsAesB/wLsAesB/wLt\n        AewB/wLtAewB/wLtAewB/wLuAe0B/wLuAe0B/wPuAf8C7wHuAf8C7wHuAf8D7wH/AvAB7wH/AvAB7wH/\n        AvAB7wH/A/AB/wLxAfAB/wLxAfAB/wPxAf8D8QH/AvIB8QH/AvIB8QH/AvIB8QH/A/IB/wPyAf8D8gH/\n        AvMB8gH/AvMB8gH/AvMB8gH/AvMB8gH/A/MB/wPzAf8D8wH/A/MB/wPzAf8D8wH/A/MB/wPzAf8D8wH/\n        A/MB/wPzAf8DKgFAAw8BFAMBAQI4AAGaAfMC/wGVAe0B+wH/AZkB8wH+Af8BmQHyAf4B/wGZAfIB/gH/\n        AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHz\n        Af4B/wFkAcYB3QH/AV0BvQHdAf8BhgHWAfkB/wGGAdYB+QH/AYUB1gH5Af8BhQHWAfkB/wGFAdYB+QH/\n        AYUB1gH4Af8BhQHWAfgB/wGFAdYB+AH/AYUB1gH4Af8BhQHWAfgB/wGFAdYB+AH/AYUB1gH4Af8BhQHW\n        AfgB/wGFAdYB+AH/AYUB1gH4Af8BhQHWAfgB/wGFAdUB+AH/AYUB1QH4Af8BhQHVAfgB/wGFAdUB+AH/\n        AYUB1QH4Af8BhAHVAfgB/wFYAbYB1AH/aAABmgHzAv8BlQHtAfsB/wGZAfMB/gH/AZkB8gH+Af8BmQHy\n        Af4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/\n        AZkB8wH+Af8BZAHGAd0B/wFdAb0B3QH/AYYB1gH5Af8BhgHWAfkB/wGFAdYB+QH/AYUB1gH5Af8BhQHW\n        AfkB/wGFAdYB+AH/AYUB1gH4Af8BhQHWAfgB/wGFAdYB+AH/AYUB1gH4Af8BhQHWAfgB/wGFAdYB+AH/\n        AYUB1gH4Af8BhQHWAfgB/wGFAdYB+AH/AYUB1gH4Af8BhQHVAfgB/wGFAdUB+AH/AYUB1QH4Af8BhQHV\n        AfgB/wGFAdUB+AH/AYQB1QH4Af8BWAG2AdQB//8AVQADAQECAw8BFAMqAUADPgFsBP8B6AHnAeYB/wLo\n        AecB/wHpAegB5wH/AukB6AH/AuoB6QH/AuoB6QH/AusB6gH/AusB6gH/AuwB6wH/AuwB6wH/A+wB/wLt\n        AewB/wLtAewB/wLuAe0B/wLuAe0B/wLuAe0B/wPuAf8C7wHuAf8C7wHuAf8D7wH/AvAB7wH/AvAB7wH/\n        AvAB7wH/A/AB/wLxAfAB/wLxAfAB/wLxAfAB/wPxAf8D8QH/AvIB8QH/AvIB8QH/AvIB8QH/AvIB8QH/\n        A/IB/wPyAf8D8gH/A/IB/wPyAf8C8wHyAf8C8wHyAf8C8wHyAf8C8wHyAf8C8wHyAf8C8wHyAf8C8wHy\n        Af8C8wHyAf8C8wHyAf8DKgFAAw8BFAMBAQI4AAGaAfMC/wGVAe0B+wH/AZkB8wH+Af8BmQHyAf4B/wGZ\n        AfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfMB/gH/AWYBygHf\n        Af8BYQHDAeQB/wGGAdcB+QH/AYYB1wH5Af8BhgHXAfkB/wGGAdcB+QH/AYYB1wH5Af8BhgHXAfkB/wGG\n        AdcB+QH/AYYB1gH5Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5\n        Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHWAfkB/wGF\n        AdYB+QH/AYUB1gH5Af8BhAHWAfkB/wNhAeZoAAGaAfMC/wGVAe0B+wH/AZkB8wH+Af8BmQHyAf4B/wGZ\n        AfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfMB/gH/AWYBygHf\n        Af8BYQHDAeQB/wGGAdcB+QH/AYYB1wH5Af8BhgHXAfkB/wGGAdcB+QH/AYYB1wH5Af8BhgHXAfkB/wGG\n        AdcB+QH/AYYB1gH5Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5\n        Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHWAfkB/wGGAdYB+QH/AYYB1gH5Af8BhgHWAfkB/wGF\n        AdYB+QH/AYUB1gH5Af8BhAHWAfkB/wNhAeb/AFUAAwEBAgMPARQDKgFAAz4BbAT/AucB5gH/AegB5wHm\n        Af8C6AHnAf8B6QHoAecB/wLpAegB/wHqAekB6AH/AuoB6QH/AusB6gH/AusB6gH/AuwB6wH/AuwB6wH/\n        AuwB6wH/Au0B7AH/Au0B7AH/Au0B7AH/Au4B7QH/Au4B7QH/Au4B7QH/A+4B/wLvAe4B/wLvAe4B/wPv\n        Af8D7wH/AvAB7wH/AvAB7wH/A/AB/wPwAf8C8QHwAf8C8QHwAf8C8QHwAf8C8QHwAf8D8QH/A/EB/wPx\n        Af8C8gHxAf8C8gHxAf8C8gHxAf8C8gHxAf8C8gHxAf8C8gHxAf8C8gHxAf8C8gHxAf8C8gHxAf8C8gHx\n        Af8C8gHxAf8C8gHxAf8C8gHxAf8DKgFAAw8BFAMBAQI4AAGaAfMC/wGVAe0B+wH/AZkB8wH+Af8BmQHy\n        Af4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8wH+Af8BaQHOAeQB/wFkAccB6AH/\n        AYcB1wH6Af8BhwHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHX\n        AfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/\n        AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfkB/wGFAdcB+QH/AYUB1wH5Af8BhQHX\n        AfkB/wGdAd4B+wH/AbcB5wH8Af8BsQH0Af4B/wMKAQ1oAAGaAfMC/wGVAe0B+wH/AZkB8wH+Af8BmQHy\n        Af4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AZkB8wH+Af8BaQHOAeQB/wFkAccB6AH/\n        AYcB1wH6Af8BhwHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHX\n        AfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/\n        AYYB1wH6Af8BhgHXAfoB/wGGAdcB+gH/AYYB1wH6Af8BhgHXAfkB/wGFAdcB+QH/AYUB1wH5Af8BhQHX\n        AfkB/wGdAd4B+wH/AbcB5wH8Af8BsQH0Af4B/wMKAQ3/AFUAAwEBAgMPARQDKgFAAz4BbAT/AuYB5QH/\n        AecB5gHlAf8C5wHmAf8C6AHnAf8B6QHoAecB/wLpAegB/wLpAegB/wLqAekB/wLqAekB/wLrAeoB/wLr\n        AeoB/wLsAesB/wLsAesB/wLsAesB/wLtAewB/wLtAewB/wLtAewB/wLuAe0B/wLuAe0B/wLuAe0B/wPu\n        Af8C7wHuAf8C7wHuAf8C7wHuAf8D7wH/AvAB7wH/AvAB7wH/AvAB7wH/AvAB7wH/A/AB/wPwAf8C8QHw\n        Af8C8QHwAf8C8QHwAf8C8QHwAf8C8QHwAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx\n        Af8D8QH/A/EB/wMqAUADDwEUAwEBAjgAAZoB8wL/AZUB7QH7Af8BmQHzAf4B/wGZAfIB/gH/AZkB8gH+\n        Af8BmQHyAf4B/wGZAfIB/gH/AYIB0gHnAf8BZQHIAekB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGH\n        AdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/AYcB2AH7\n        Af8BhwHYAfsB/wGHAdgB+wH/AYYB2AH7Af8BhgHYAfoB/wGGAdgB+gH/AYwB2gH7Af8BqgHjAfwB/wG5\n        AewB/QH/Ab0B8QH+Af8BwwH5Av8BoQHoAfUB/wFcAl4B6gNVAa0DQAFwAyIBMnQAAZoB8wL/AZUB7QH7\n        Af8BmQHzAf4B/wGZAfIB/gH/AZkB8gH+Af8BmQHyAf4B/wGZAfIB/gH/AYIB0gHnAf8BZQHIAekB/wGH\n        AdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/AYcB2AH7\n        Af8BhwHYAfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/AYYB2AH7Af8BhgHYAfoB/wGG\n        AdgB+gH/AYwB2gH7Af8BqgHjAfwB/wG5AewB/QH/Ab0B8QH+Af8BwwH5Av8BoQHoAfUB/wFcAl4B6gNV\n        Aa0DQAFwAyIBMv8AYQADAQECAw8BFAMqAUADPgFsBP8B5gHlAeQB/wLmAeUB/wHnAeYB5QH/AucB5gH/\n        AegB5wHmAf8C6AHnAf8C6QHoAf8C6QHoAf8C6gHpAf8C6gHpAf8C6wHqAf8C6wHqAf8C7AHrAf8C7AHr\n        Af8C7AHrAf8D7AH/Au0B7AH/Au0B7AH/Au0B7AH/Au4B7QH/Au4B7QH/Au4B7QH/A+4B/wLvAe4B/wLv\n        Ae4B/wLvAe4B/wLvAe4B/wPvAf8D7wH/AvAB7wH/AvAB7wH/AvAB7wH/AvAB7wH/A/AB/wPwAf8D8AH/\n        A/AB/wLxAfAB/wLxAfAB/wLxAfAB/wLxAfAB/wLxAfAB/wLxAfAB/wLxAfAB/wLxAfAB/wLxAfAB/wLx\n        AfAB/wMqAUADDwEUAwEBAjgAAZoB8wL/AZUB7QH7Af8BmQHzAf4B/wGZAfIB/gH/AZkB8gH+Af8BgwHU\n        AegB/wFpAc0B7wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGHAdgB+wH/\n        AYcB2AH7Af8BhgHYAfsB/wGGAdgB+wH/AYYB2AH7Af8BmgHfAfwB/wG3AegB/QH/AbwB7wH+Af8BwwH1\n        Af4B/wG0AfIB+wH/AZEB4AHxAf8DXQHSA0wBkAMzAVMDEAEVlAABmgHzAv8BlQHtAfsB/wGZAfMB/gH/\n        AZkB8gH+Af8BmQHyAf4B/wGDAdQB6AH/AWkBzQHvAf8BhwHYAfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHY\n        AfsB/wGHAdgB+wH/AYcB2AH7Af8BhwHYAfsB/wGGAdgB+wH/AYYB2AH7Af8BhgHYAfsB/wGaAd8B/AH/\n        AbcB6AH9Af8BvAHvAf4B/wHDAfUB/gH/AbQB8gH7Af8BkQHgAfEB/wNdAdIDTAGQAzMBUwMQARX/AIEA\n        AwEBAgMNARIDKAE8AzsBZcD/AygBPAMNARIDAQECOAABmgHzAv8BlAHsAfoB/wGZAfMB/gH/AYYB2AHr\n        Af8BaQHNAe8B/wGHAdgB+wH/AYYB2AH7Af8BhgHYAfsB/wGIAdkB+wH/AaYB4gH8Af8BuQHsAf0B/wG/\n        AfIB/gH/AcMB+AL/AaUB6gH3Af8BZwFqAW8B8gNVAbUDQwF4AycBOrgAAZoB8wL/AZQB7AH6Af8BmQHz\n        Af4B/wGGAdgB6wH/AWkBzQHvAf8BhwHYAfsB/wGGAdgB+wH/AYYB2AH7Af8BiAHZAfsB/wGmAeIB/AH/\n        AbkB7AH9Af8BvwHyAf4B/wHDAfgC/wGlAeoB9wH/AWcBagFvAfIDVQG1A0MBeAMnATr/AKgAAQEDCgEN\n        Ax8BLAMvAUoDNQFWAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFY\n        AzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFY\n        AzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFYAzUBWAM1AVgDNQFY\n        AzUBWAM1AVgDNQFYAzUBVgMvAUoDHwEsAwoBDQMAAQE4AAFfAZIBlwH7AYUB1gHrAf8BugHpAfcB/wHB\n        AfQC/wG5AfQB/QH/AZUB4gHzAf8DXgHVA04BmQM3AVsDFQEd2AABXwGSAZcB+wGFAdYB6wH/AboB6QH3\n        Af8BwQH0Av8BuQH0Af0B/wGVAeIB8wH/A14B1QNOAZkDNwFbAxUBHf8AyQADBAEGAw8BFAMYASEDHAEn\n        AxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEo\n        AxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEo\n        AxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEoAxwBKAMcASgDHAEo\n        AxwBJwMYASEDDwEUAwQBBv8A/wD/ADIAAQEDAwQEBAYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMG\n        AQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMG\n        AQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMG\n        AQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBgEIAwYBCAMGAQgDBAEGAwMBBAMAAQH/AP8A/wD/AP8A\n        /wD/AB8AAUIBTQE+BwABPgMAASgEAAEBAgABQAMAAQEBAAEBBgABCBYAA/8BABj/CAAB/AQABf8B4Af/\n        AeAF/wgAAfgEAAE/BP8BgAF/Bv8BgAF/BP8IAAHwBAABHwT/AQABHwH/AYABPwP/AQABHwH/AYABPwH/\n        CAAB8AQAAQ8D/wH+AQABDwH4AQABDwL/Af4BAAEPAfgBAAEPAf8IAAHwBAABBwP/AfwBAAEHAYABAAEH\n        Av8B/AEAAQcBgAEAAQcB/wgAAfAEAAEBA/8B+AQAAQMC/wH4BAABAwH/CAAB8AUAA/8B8AQAAQEC/wHw\n        BAABAQH/CAAB8AUAAX8C/wHgBQAC/wHgBQAB/wgAAfAFAAE/Av8BwAUAAX8B/wHABQABfwgAAfAFAAEf\n        Av8BgAUAAT8B/wGABQABPwgAAfAFAAEPAv8GAAEfAf8GAAEfCAAB8AUAAQcC/wYAAQ8B/wYAAQ8IAAHw\n        BQABAwL/BgABBwH/BgABBwgAAfAFAAEBAv8GAAEDAf8GAAEDCAAB8AUAAQEC/wGABQABAQH/AYAFAAEB\n        CAAB8AYAAv8BgAYAAf8BgA4AAfAGAAF/Af8BgAYAAf8BgA4AAfAGAAE/Af8BgAYAAf8BgA4AAfAGAAE/\n        Af8BgAYAAf8BgA4AAfAGAAEfAf8BgAUAAQEB/wGABQABAQgAAfAGAAEfAf8BgAUAAX8B/wGABQABAwgA\n        AfAGAAEfAf8BgAQAAS8C/wGABAABIAEDCAAB8AYAAR8B/wGABAABPwL/AYAEAAE4AQMIAAHwBgABHwH/\n        AYAEAAE/Av8BgAQAATwBAwgAAfAGAAEfAf8BgAQAAT8C/wGABAABPAEDCAAB8AYAAR8B/wGABAABfwL/\n        AYAEAAFwAQMIAAHwBgABHwH/AYADAAEBA/8BgAUAAQMIAAHwBgABHwH/AYADAAEBA/8BgAUAAQMIAAHw\n        BgABHwH/AYADAAEBA/8BgAUAAQMIAAHwBgABHwH/AYADAAEBA/8BgAUAAQMIAAHwBgABHwH/AYADAAEB\n        A/8BgAUAAQMIAAHwBgABHwH/AYADAAEBA/8BgAUAAQMIAAHwBgABHwH/AYADAAEBA/8BgAUAAQcIAAHw\n        BgABHwH/AYADAAEBA/8BgAUAAQ8IAAHwBgABHwH/AYADAAEBA/8BgAUAAR8IAAHwBgABHwH/AYADAAEB\n        A/8BgAUAAT8IAAHwBgABHwH/AYADAAEBA/8BgAUAAf8IAAHwBgABHwH/AYADAAEBA/8BgAQAAQMB/wgA\n        AfAGAAEfAf8BgAMAAQED/wGABAABPwH/CAAB8AYAAR8B/wGAAwABAQP/AYADAAEBAv8IAAHwBgABHwH/\n        AYADAAEBA/8BgAMAAQEC/wgAAfAGAAEfAf8BgAMAAQED/wGAAwABAQL/CAAB8AYAAR8B/wGAAwABAQP/\n        AYADAAEBAv8IAAHwBgABHwH/AYADAAEBA/8BgAMAAQEC/wgAAfAGAAEfAf8BgAMAAQED/wGAAwABAQL/\n        CAAB8AYAAR8B/wGAAwABAQP/AYADAAEBAv8IAAHwBgABHwH/AYADAAEBA/8BgAMAAQEC/wgAAfAGAAEf\n        Af8BgAMAAQED/wGAAwABAQL/CAAB8AYAAR8B/wGAAwABAQP/AYADAAEBAv8IAAHwBgABHwH/AYADAAEB\n        A/8BgAMAAQEC/wgAAfAGAAEfAf8BgAMAAQED/wGAAwABAQL/CAAB8AYAAR8B/wGAAwABAQP/AYADAAEB\n        Av8IAAHwBgABHwH/AYADAAEBA/8BgAMAAQEC/wgAAfAGAAEfAf8BgAMAAQED/wGAAwABAQL/CAAB8AYA\n        AR8B/wGAAwABAQP/AYADAAEBAv8IAAHwBgABHwH/AYADAAEBA/8BgAMAAQEC/wgAAfAGAAEfAf8BgAMA\n        AQ8D/wGAAwABDwL/CAAB8AYAAR8B/wGAAgABDwT/AYACAAEPA/8IAAHwBgABHwH/AYABAAEfBf8BgAEA\n        AR8E/wgAAfAGAAEfAf8BgAEfBv8BgAEfBf8IAAH4BgABPxD/CAAB+AYAAT8Q/wgAGP8IAAs=\n</value>\n  </data>\n  <metadata name=\"SharedWithMeContextMenu.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>318, 17</value>\n  </metadata>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveGraphDeviceLoginForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OneDriveGraphDeviceLoginForm));\n            this.MicrosoftLogoPictureBox = new System.Windows.Forms.PictureBox();\n            this.StatusLabel = new System.Windows.Forms.Label();\n            this.DeviceIdTextBox = new System.Windows.Forms.TextBox();\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.DeviceAuthLinkLabel = new System.Windows.Forms.LinkLabel();\n            this.OpenBrowserButton = new System.Windows.Forms.Button();\n            this.CopyDeviceIdButton = new System.Windows.Forms.Button();\n            this.CancelButton = new System.Windows.Forms.Button();\n            this.StartSessionTimer = new System.Windows.Forms.Timer(this.components);\n            this.AuthenticationCheckTimer = new System.Windows.Forms.Timer(this.components);\n            this.AuthenticationCompleteTimer = new System.Windows.Forms.Timer(this.components);\n            this.MoreInformationLinkLabel = new System.Windows.Forms.LinkLabel();\n            ((System.ComponentModel.ISupportInitialize)(this.MicrosoftLogoPictureBox)).BeginInit();\n            this.SuspendLayout();\n            // \n            // MicrosoftLogoPictureBox\n            // \n            this.MicrosoftLogoPictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.MicrosoftLogoPictureBox.BackColor = System.Drawing.Color.White;\n            this.MicrosoftLogoPictureBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;\n            this.MicrosoftLogoPictureBox.Location = new System.Drawing.Point(12, 12);\n            this.MicrosoftLogoPictureBox.Name = \"MicrosoftLogoPictureBox\";\n            this.MicrosoftLogoPictureBox.Size = new System.Drawing.Size(497, 103);\n            this.MicrosoftLogoPictureBox.TabIndex = 0;\n            this.MicrosoftLogoPictureBox.TabStop = false;\n            // \n            // StatusLabel\n            // \n            this.StatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.StatusLabel.Location = new System.Drawing.Point(12, 244);\n            this.StatusLabel.Name = \"StatusLabel\";\n            this.StatusLabel.Size = new System.Drawing.Size(497, 31);\n            this.StatusLabel.TabIndex = 1;\n            this.StatusLabel.Text = \"Initializing\";\n            this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // DeviceIdTextBox\n            // \n            this.DeviceIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.DeviceIdTextBox.BackColor = System.Drawing.SystemColors.Control;\n            this.DeviceIdTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.DeviceIdTextBox.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 24F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.DeviceIdTextBox.Location = new System.Drawing.Point(10, 284);\n            this.DeviceIdTextBox.Name = \"DeviceIdTextBox\";\n            this.DeviceIdTextBox.Size = new System.Drawing.Size(497, 37);\n            this.DeviceIdTextBox.TabIndex = 2;\n            this.DeviceIdTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;\n            this.DeviceIdTextBox.Visible = false;\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(12, 121);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(497, 85);\n            this.ExplanationLabel.TabIndex = 3;\n            this.ExplanationLabel.Text = \"A unique device ID will be retrieved from Microsoft to perform your logon to OneDrive or OneDrive for Business through the Microsoft Graph in your favorite web browser. Once the device ID is shown below, click on the link that shows up on this form to open your default browser, paste in the device ID and perform the authentication to continue with setting up your KeePass synchronization. Leave this form open while you authenticate in your browser. Once you've authenticated in your browser, you may close your browser and this application should automatically proceed.\";\n            this.ExplanationLabel.UseMnemonic = false;\n            // \n            // DeviceAuthLinkLabel\n            // \n            this.DeviceAuthLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.DeviceAuthLinkLabel.Location = new System.Drawing.Point(12, 220);\n            this.DeviceAuthLinkLabel.Name = \"DeviceAuthLinkLabel\";\n            this.DeviceAuthLinkLabel.Size = new System.Drawing.Size(497, 23);\n            this.DeviceAuthLinkLabel.TabIndex = 4;\n            this.DeviceAuthLinkLabel.TabStop = true;\n            this.DeviceAuthLinkLabel.Text = \"Unknown\";\n            this.DeviceAuthLinkLabel.UseMnemonic = false;\n            this.DeviceAuthLinkLabel.Visible = false;\n            this.DeviceAuthLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.DeviceAuthLinkLabel_LinkClicked);\n            // \n            // OpenBrowserButton\n            // \n            this.OpenBrowserButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.OpenBrowserButton.Enabled = false;\n            this.OpenBrowserButton.Location = new System.Drawing.Point(10, 334);\n            this.OpenBrowserButton.Name = \"OpenBrowserButton\";\n            this.OpenBrowserButton.Size = new System.Drawing.Size(106, 37);\n            this.OpenBrowserButton.TabIndex = 5;\n            this.OpenBrowserButton.Text = \"&Open in browser\";\n            this.OpenBrowserButton.UseVisualStyleBackColor = true;\n            this.OpenBrowserButton.Click += new System.EventHandler(this.OpenBrowserButton_Click);\n            // \n            // CopyDeviceIdButton\n            // \n            this.CopyDeviceIdButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.CopyDeviceIdButton.Enabled = false;\n            this.CopyDeviceIdButton.Location = new System.Drawing.Point(131, 334);\n            this.CopyDeviceIdButton.Name = \"CopyDeviceIdButton\";\n            this.CopyDeviceIdButton.Size = new System.Drawing.Size(106, 37);\n            this.CopyDeviceIdButton.TabIndex = 6;\n            this.CopyDeviceIdButton.Text = \"&Copy Device ID\";\n            this.CopyDeviceIdButton.UseVisualStyleBackColor = true;\n            this.CopyDeviceIdButton.Click += new System.EventHandler(this.CopyDeviceIdButton_Click);\n            // \n            // CancelButton\n            // \n            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.CancelButton.Location = new System.Drawing.Point(403, 334);\n            this.CancelButton.Name = \"CancelButton\";\n            this.CancelButton.Size = new System.Drawing.Size(106, 37);\n            this.CancelButton.TabIndex = 7;\n            this.CancelButton.Text = \"C&ancel\";\n            this.CancelButton.UseVisualStyleBackColor = true;\n            this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click);\n            // \n            // StartSessionTimer\n            // \n            this.StartSessionTimer.Interval = 1000;\n            this.StartSessionTimer.Tick += new System.EventHandler(this.StartSessionTimer_Tick);\n            // \n            // AuthenticationCheckTimer\n            // \n            this.AuthenticationCheckTimer.Interval = 1000;\n            this.AuthenticationCheckTimer.Tick += new System.EventHandler(this.AuthenticationCheckTimer_Tick);\n            // \n            // AuthenticationCompleteTimer\n            // \n            this.AuthenticationCompleteTimer.Interval = 3000;\n            this.AuthenticationCompleteTimer.Tick += new System.EventHandler(this.AuthenticationCompleteTimer_Tick);\n            // \n            // MoreInformationLinkLabel\n            // \n            this.MoreInformationLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.MoreInformationLinkLabel.AutoSize = true;\n            this.MoreInformationLinkLabel.Location = new System.Drawing.Point(259, 346);\n            this.MoreInformationLinkLabel.Name = \"MoreInformationLinkLabel\";\n            this.MoreInformationLinkLabel.Size = new System.Drawing.Size(85, 13);\n            this.MoreInformationLinkLabel.TabIndex = 8;\n            this.MoreInformationLinkLabel.TabStop = true;\n            this.MoreInformationLinkLabel.Text = \"More information\";\n            this.MoreInformationLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.MoreInformationLinkLabel_LinkClicked);\n            // \n            // OneDriveGraphDeviceLoginForm\n            // \n            this.AcceptButton = this.OpenBrowserButton;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(521, 383);\n            this.Controls.Add(this.MoreInformationLinkLabel);\n            this.Controls.Add(this.CancelButton);\n            this.Controls.Add(this.CopyDeviceIdButton);\n            this.Controls.Add(this.OpenBrowserButton);\n            this.Controls.Add(this.DeviceAuthLinkLabel);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Controls.Add(this.DeviceIdTextBox);\n            this.Controls.Add(this.StatusLabel);\n            this.Controls.Add(this.MicrosoftLogoPictureBox);\n            this.Margin = new System.Windows.Forms.Padding(2);\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(459, 422);\n            this.Name = \"OneDriveGraphDeviceLoginForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Authenticate to OneDrive\";\n            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OneDriveGraphDeviceLoginForm_FormClosed);\n            ((System.ComponentModel.ISupportInitialize)(this.MicrosoftLogoPictureBox)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.PictureBox MicrosoftLogoPictureBox;\n        private System.Windows.Forms.Label StatusLabel;\n        private System.Windows.Forms.TextBox DeviceIdTextBox;\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.LinkLabel DeviceAuthLinkLabel;\n        private System.Windows.Forms.Button OpenBrowserButton;\n        private System.Windows.Forms.Button CopyDeviceIdButton;\n        private System.Windows.Forms.Button CancelButton;\n        private System.Windows.Forms.Timer StartSessionTimer;\n        private System.Windows.Forms.Timer AuthenticationCheckTimer;\n        private System.Windows.Forms.Timer AuthenticationCompleteTimer;\n        private System.Windows.Forms.LinkLabel MoreInformationLinkLabel;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Windows.Forms;\nusing KoenZomers.OneDrive.Api;\nusing Newtonsoft.Json;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    /// <summary>\n    /// Performs authentication against the Microsoft Graph API using the Device Code Flow (https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code)\n    /// </summary>\n    public partial class OneDriveGraphDeviceLoginForm : Form\n    {\n        /// <summary>\n        /// URL to link the More information link to\n        /// </summary>\n        private const string _moreInformationUrl = \"https://github.com/KoenZomers/KeePassOneDriveSync/wiki/FAQ#how-does-the-microsoft-graph-any-browser-option-work\";\n\n        /// <summary>\n        /// URL to send a POST request to in order to retrieve a Device ID Code from Microsoft Graph\n        /// </summary>\n        private const string _microsoftGraphDeviceAuthorizationInitiationUrl = \"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode\";\n\n        /// <summary>\n        /// URL to send a POST request to in order to verify if the device session has been authenticated already\n        /// </summary>\n        private const string _microsoftGraphDeviceAuthorizationStatusUrl = \"https://login.microsoftonline.com/common/oauth2/v2.0/token\";\n\n        /// <summary>\n        /// Counter to keep track of how many seconds there are left to authenticate the session\n        /// </summary>\n        private int _authenticatedCheckCountDownCount;\n\n        /// <summary>\n        /// Counter to keep track of how many checks to wait before actually contacting the Microsoft Graph API again to validate if the authentication has succeeded\n        /// </summary>\n        private int _authenticationCheckSkipCounter;\n\n        /// <summary>\n        /// Amount of validation checks to wait before actually contacting the Microsoft Graph API again to validate if the authentication has succeeded\n        /// </summary>\n        private int _authenticationCheckSkipValue;\n\n        /// <summary>\n        /// HTTP Client to use to communicate with the Microsoft Graph\n        /// </summary>\n        private HttpClient _httpClient;\n\n        /// <summary>\n        /// OneDrive Graph API instance\n        /// </summary>\n        public OneDriveGraphApi OneDriveApi { get; private set; }\n\n        /// <summary>\n        /// Returns the Refresh Token obtained through the Device ID login\n        /// </summary>\n        public string RefreshToken { get; private set; }\n\n        public OneDriveGraphDeviceLoginForm(OneDriveApi oneDriveApi)\n        {\n            InitializeComponent();\n\n            // Cast the OneDrive instance to a Graph API instance so it can be used in this form\n            OneDriveApi = (OneDriveGraphApi)oneDriveApi;\n\n            // When the form is being closed, ensure the Timer processes are being stopped to avoid exceptions\n            FormClosing += OneDriveGraphDeviceLoginForm_FormClosing;\n\n            // Set the defaults of the components on the form\n            StatusLabel.Text = \"Communicating with the Microsoft Graph API...\";\n            DeviceAuthLinkLabel.Visible = false;\n            DeviceIdTextBox.Visible = false;\n            OpenBrowserButton.Enabled = false;\n            CopyDeviceIdButton.Enabled = false;\n            AuthenticationCheckTimer.Enabled = false;\n            AuthenticationCompleteTimer.Enabled = false;\n\n            // Set the Microsoft logo on the form\n            MicrosoftLogoPictureBox.BackgroundImage = Resources.MicrosoftLogo;\n\n            // Set up a HttpClient obeying the possible proxy settings to communicate with the Microsoft Graph API\n            _httpClient = CreateHttpClient();\n\n            // Enable a timer to initiate the communication with Microsoft Graph so the UI thread doesn't block\n            StartSessionTimer.Enabled = true;\n        }\n\n        /// <summary>\n        /// When the form is closed, ensure Timer resources are being stopped\n        /// </summary>\n        private void OneDriveGraphDeviceLoginForm_FormClosing(object sender, FormClosingEventArgs e)\n        {\n            if(AuthenticationCheckTimer != null && AuthenticationCheckTimer.Enabled)\n            {\n                AuthenticationCheckTimer.Enabled = false;\n            }\n            if(StartSessionTimer != null && StartSessionTimer.Enabled)\n            {\n                StartSessionTimer.Enabled = false;\n            }\n            if (AuthenticationCompleteTimer != null && AuthenticationCompleteTimer.Enabled)\n            {\n                AuthenticationCompleteTimer.Enabled = false;\n            }\n        }\n\n        /// <summary>\n        /// Makes a request to the Microsoft Graph API to set up a new device code flow session and shows the results on the form\n        /// </summary>\n        private void GetMicrosoftGraphDeviceId()\n        {\n            // Construct the mandatory form post parameters to send\n            var postFormValues = new List<KeyValuePair<string, string>>();\n            postFormValues.Add(new KeyValuePair<string, string>(\"client_id\", KoenZomersKeePassOneDriveSyncExt.GraphApiApplicationId));\n            postFormValues.Add(new KeyValuePair<string, string>(\"scope\", OneDriveApi.DefaultScopes.Aggregate((x, y) => string.Format(\"{0} {1}\", x, y))));\n\n            StatusLabel.Text = \"Requesting Device ID code...\";\n\n            // Construct the message towards the Microsoft Graph API\n            using (var request = new HttpRequestMessage(HttpMethod.Post, _microsoftGraphDeviceAuthorizationInitiationUrl))\n            {\n                request.Content = new FormUrlEncodedContent(postFormValues);\n\n                // Request the response from the webservice\n                HttpResponseMessage response;\n                try\n                {\n                    response = _httpClient.SendAsync(request).Result;\n                }\n                catch(Exception e)\n                {\n                    while (e.InnerException != null) e = e.InnerException;\n                    StatusLabel.Text = string.Format(\"Failed to connect to the Graph API ({0})\", e.Message);\n                    return;\n                }\n\n                Providers.MicrosoftGraph.MicrosoftGraphDeviceCodeResponse microsoftGraphDeviceCodeResponse;\n                try\n                {                    \n                    microsoftGraphDeviceCodeResponse = JsonConvert.DeserializeObject<Providers.MicrosoftGraph.MicrosoftGraphDeviceCodeResponse>(response.Content.ReadAsStringAsync().Result);\n                }\n                catch(Exception e)\n                {\n                    while (e.InnerException != null) e = e.InnerException;\n                    StatusLabel.Text = string.Format(\"Failed to parse the Graph API response ({0})\", e.Message);\n                    return;\n                }\n\n                // Ensure the required information has been received\n                if (microsoftGraphDeviceCodeResponse != null && !string.IsNullOrEmpty(microsoftGraphDeviceCodeResponse.DeviceCode) && !string.IsNullOrEmpty(microsoftGraphDeviceCodeResponse.UserCode) && microsoftGraphDeviceCodeResponse.VerificationUri != null)\n                {\n                    DeviceIdTextBox.Text = microsoftGraphDeviceCodeResponse.UserCode;\n                    DeviceIdTextBox.Tag = microsoftGraphDeviceCodeResponse.DeviceCode;\n                    DeviceIdTextBox.Visible = true;\n\n                    DeviceAuthLinkLabel.Text = microsoftGraphDeviceCodeResponse.VerificationUri.AbsoluteUri;\n                    DeviceAuthLinkLabel.Visible = true;\n\n                    CopyDeviceIdButton.Enabled = true;\n                    OpenBrowserButton.Enabled = true;\n                    OpenBrowserButton.Focus();\n\n                    _authenticatedCheckCountDownCount = microsoftGraphDeviceCodeResponse.ExpiresIn.GetValueOrDefault(180);\n\n                    _authenticationCheckSkipValue = microsoftGraphDeviceCodeResponse.Interval.GetValueOrDefault(2);\n\n                    AuthenticationCheckTimer.Enabled = true;\n                }\n                else\n                {\n                    StatusLabel.Text = \"Invalid response received from Microsoft Graph\";\n                }\n            }\n        }\n\n        /// <summary>\n        /// Tries to parse the provided JSON string into the provided type T\n        /// </summary>\n        /// <typeparam name=\"T\">Type to try to parse the JSON structure in</typeparam>\n        /// <param name=\"json\">JSON as a string to parse</param>\n        /// <param name=\"result\">Object of type T containing the parsed JSON</param>\n        /// <returns>True if the parsing succeeded, false if it failed</returns>\n        public static bool TryParseJson<T>(string json, out T result)\n        {\n            bool success = true;\n            var settings = new JsonSerializerSettings\n            {\n                Error = (sender, args) => { success = false; args.ErrorContext.Handled = true; },\n                MissingMemberHandling = MissingMemberHandling.Error\n            };\n            result = JsonConvert.DeserializeObject<T>(json, settings);\n            return success;\n        }\n\n        /// <summary>\n        /// Makes a request to the Microsoft Graph API to validate if the device code session has authenticated already\n        /// </summary>\n        /// <returns>NULL if the authentication did not take place yet or a refresh token if it has</returns>\n        private string HasUserAuthenticated()\n        {\n            // Construct the mandatory form post parameters to send\n            var postFormValues = new List<KeyValuePair<string, string>>();\n            postFormValues.Add(new KeyValuePair<string, string>(\"grant_type\", \"urn:ietf:params:oauth:grant-type:device_code\"));\n            postFormValues.Add(new KeyValuePair<string, string>(\"device_code\", DeviceIdTextBox.Tag.ToString()));\n            postFormValues.Add(new KeyValuePair<string, string>(\"client_id\", KoenZomersKeePassOneDriveSyncExt.GraphApiApplicationId));\n\n            // Construct the message towards the Microsoft Graph API\n            using (var request = new HttpRequestMessage(HttpMethod.Post, _microsoftGraphDeviceAuthorizationStatusUrl))\n            {\n                request.Content = new FormUrlEncodedContent(postFormValues);\n\n                // Request the response from the Microsoft Graph API\n                using (var response = _httpClient.SendAsync(request).Result)\n                {\n                    var responseString = response.Content.ReadAsStringAsync().Result;\n\n                    // Try and see if the result can be parsed as an error result typically indicating that the authentication did not take place yet\n                    Providers.MicrosoftGraph.MicrosoftGraphDeviceCodeAuthCheckFailedResponse failedResult;\n                    if (TryParseJson(responseString, out failedResult))\n                    {\n                        switch (failedResult.Error)\n                        {\n                            case \"authorization_pending\":\n                                // all good, just wait for it to be done\n                                break;\n\n                            case \"authorization_declined\":\n                                AuthenticationCheckTimer.Enabled = false;\n                                StatusLabel.Text = \"Authorization declined\";\n                                break;\n\n                            case \"expired_token\":\n                                AuthenticationCheckTimer.Enabled = false;\n                                StatusLabel.Text = \"Authentication timed out\";\n                                break;\n\n                            case \"bad_verification_code\":\n                                AuthenticationCheckTimer.Enabled = false;\n                                StatusLabel.Text = \"Device code not recognized\";\n                                break;\n\n                            default:\n                                AuthenticationCheckTimer.Enabled = false;\n                                StatusLabel.Text = string.Format(\"Unexpected error: {0}\", failedResult.ErrorDescription);\n                                break;\n                        }\n                        return null;\n                    }\n\n                    // Try and see if the result can be parsed as a successful result indicating that the authentication has taken place\n                    Providers.MicrosoftGraph.MicrosoftGraphDeviceCodeAuthCheckSucceededResponse succeededResult;\n                    if (TryParseJson(responseString, out succeededResult))\n                    {\n                        return succeededResult.RefreshToken;\n                    }\n\n                    // Unknown response received\n                    AuthenticationCheckTimer.Enabled = false;\n                    StatusLabel.Text = \"Unknown response received\";\n                    return null;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Instantiates a new HttpClient preconfigured for use. Note that the caller is responsible for disposing this object.\n        /// </summary>\n        /// <returns>HttpClient instance</returns>\n        private HttpClient CreateHttpClient()\n        {\n            var proxySettings = Utilities.GetProxySettings();\n            var proxyCredentials = Utilities.GetProxyCredentials();\n\n            // Define the HttpClient settings\n            var httpClientHandler = new HttpClientHandler\n            {\n                UseDefaultCredentials = proxyCredentials == null,\n                UseProxy = proxySettings != null,\n                Proxy = proxySettings\n            };\n\n            // Check if we need specific credentials for the proxy\n            if (proxyCredentials != null && httpClientHandler.Proxy != null)\n            {\n                httpClientHandler.Proxy.Credentials = proxyCredentials;\n            }\n\n            // Create the new HTTP Client\n            var httpClient = new HttpClient(httpClientHandler);\n            return httpClient;\n        }\n\n        private void CancelButton_Click(object sender, EventArgs e)\n        {\n            AuthenticationCheckTimer.Enabled = false;\n\n            Close();\n        }\n\n        /// <summary>\n        /// Triggers when the communication with the Microsoft Graph should start\n        /// </summary>\n        private void StartSessionTimer_Tick(object sender, EventArgs e)\n        {\n            // Only perform this action once\n            StartSessionTimer.Enabled = false;\n\n            // Initiate the retrieval of a Device ID\n            GetMicrosoftGraphDeviceId();\n        }\n\n        /// <summary>\n        /// Triggers to validate if the device id session has been authenticated\n        /// </summary>\n        private void AuthenticationCheckTimer_Tick(object sender, EventArgs e)\n        {\n            _authenticatedCheckCountDownCount--;\n\n            if(_authenticatedCheckCountDownCount == 0)\n            {\n                StatusLabel.Text = \"Session authentication has timed out\";\n                AuthenticationCheckTimer.Enabled = false;\n                return;\n            }\n\n            var timeRemaining = TimeSpan.FromSeconds(_authenticatedCheckCountDownCount);\n            StatusLabel.Text = string.Format(\"Waiting for authentication to complete ({0:D2}:{1:D2})\", timeRemaining.Minutes, timeRemaining.Seconds);\n\n            // Don't connect to the Microsoft Graph API every second as otherwise it will throw an error. Wait for the amount of times as instructed by the Microsoft Graph API when setting up the device login session.\n            _authenticationCheckSkipCounter++;\n            if(_authenticationCheckSkipCounter < _authenticationCheckSkipValue)\n            {\n                return;\n            }\n            _authenticationCheckSkipCounter = 0;\n\n            var result = HasUserAuthenticated();\n            if (result != null)\n            {\n                AuthenticationCheckTimer.Enabled = false;\n                RefreshToken = result;\n                DialogResult = DialogResult.OK;\n                StatusLabel.Text = \"Authentication successful\";\n                AuthenticationCompleteTimer.Enabled = true;\n            }\n        }\n\n        /// <summary>\n        /// Copies the Device ID to the Windows Clipboard\n        /// </summary>\n        private void CopyDeviceIdButton_Click(object sender, EventArgs e)\n        {\n            if (!DeviceIdTextBox.Enabled) return;\n\n            Clipboard.SetText(DeviceIdTextBox.Text);\n        }\n\n        private void OpenBrowserButton_Click(object sender, EventArgs e)\n        {\n            if (!OpenBrowserButton.Enabled) return;\n\n            System.Diagnostics.Process.Start(DeviceAuthLinkLabel.Text);\n        }\n\n        private void DeviceAuthLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            if (!DeviceAuthLinkLabel.Visible) return;\n\n            System.Diagnostics.Process.Start(DeviceAuthLinkLabel.Text);\n        }\n\n        private void OneDriveGraphDeviceLoginForm_FormClosed(object sender, FormClosedEventArgs e)\n        {\n            if (_httpClient != null)\n            {\n                _httpClient.Dispose();\n            }\n        }\n\n        private void AuthenticationCompleteTimer_Tick(object sender, EventArgs e)\n        {\n            AuthenticationCompleteTimer.Enabled = false;\n            Close();\n        }\n\n        private void MoreInformationLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            System.Diagnostics.Process.Start(_moreInformationUrl);\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ExplanationLabel.Text\" xml:space=\"preserve\">\n    <value>A unique device ID will be retrieved from Microsoft to perform your logon to OneDrive or OneDrive for Business through the Microsoft Graph in your favorite web browser. Once the device ID is shown below, click on the link that shows up on this form to open your default browser, paste in the device ID and perform the authentication to continue with setting up your KeePass synchronization. Leave this form open while you authenticate in your browser. Once you've authenticated in your browser, you may close your browser and this application should automatically proceed.</value>\n  </data>\n  <metadata name=\"StartSessionTimer.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <metadata name=\"AuthenticationCheckTimer.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>166, 17</value>\n  </metadata>\n  <metadata name=\"AuthenticationCompleteTimer.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>362, 17</value>\n  </metadata>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm1.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace KoenZomersKeePassOneDriveSync.Forms {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"15.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class OneDriveGraphDeviceLoginForm {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal OneDriveGraphDeviceLoginForm() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"KoenZomersKeePassOneDriveSync.Forms.OneDriveGraphDeviceLoginForm\", typeof(OneDriveGraphDeviceLoginForm).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Point similar to {X=166,Y=17}.\n        /// </summary>\n        public static System.Drawing.Point AuthenticationCheckTimer_TrayLocation {\n            get {\n                object obj = ResourceManager.GetObject(\"AuthenticationCheckTimer.TrayLocation\", resourceCulture);\n                return ((System.Drawing.Point)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Point similar to {X=362,Y=17}.\n        /// </summary>\n        public static System.Drawing.Point AuthenticationCompleteTimer_TrayLocation {\n            get {\n                object obj = ResourceManager.GetObject(\"AuthenticationCompleteTimer.TrayLocation\", resourceCulture);\n                return ((System.Drawing.Point)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to A unique device ID will be retrieved from Microsoft to perform your logon to OneDrive or OneDrive for Business through the Microsoft Graph in your favorite web browser. Once the device ID is shown below, click on the link that shows up on this form to open your default browser, paste in the device ID and perform the authentication to continue with setting up your KeePass synchronization. Leave this form open while you authenticate in your browser. Once you&apos;ve authenticated in your browser, you may close you [rest of string was truncated]&quot;;.\n        /// </summary>\n        public static string ExplanationLabel_Text {\n            get {\n                return ResourceManager.GetString(\"ExplanationLabel.Text\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Point similar to {X=17,Y=17}.\n        /// </summary>\n        public static System.Drawing.Point StartSessionTimer_TrayLocation {\n            get {\n                object obj = ResourceManager.GetObject(\"StartSessionTimer.TrayLocation\", resourceCulture);\n                return ((System.Drawing.Point)(obj));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveRefreshTokenStorageDialog\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.InKeePassDatabaseRadio = new System.Windows.Forms.RadioButton();\n            this.OnDiskRadio = new System.Windows.Forms.RadioButton();\n            this.FinishButton = new System.Windows.Forms.Button();\n            this.HelpMeChooseLinkLabel = new System.Windows.Forms.LinkLabel();\n            this.SuspendLayout();\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(14, 11);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(744, 43);\n            this.ExplanationLabel.TabIndex = 0;\n            this.ExplanationLabel.Text = \"You\\'ve successfully authenticated to OneDrive. Where should KeePassOneDriveSync store\" +\n    \" the OneDrive Refresh Token so it can keep your local database in sync with its \" +\n    \"equivalent on OneDrive?\";\n            // \n            // InKeePassDatabaseRadio\n            // \n            this.InKeePassDatabaseRadio.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.InKeePassDatabaseRadio.AutoSize = true;\n            this.InKeePassDatabaseRadio.Location = new System.Drawing.Point(18, 76);\n            this.InKeePassDatabaseRadio.Name = \"InKeePassDatabaseRadio\";\n            this.InKeePassDatabaseRadio.Size = new System.Drawing.Size(250, 24);\n            this.InKeePassDatabaseRadio.TabIndex = 2;\n            this.InKeePassDatabaseRadio.Text = \"In the KeePass database itself\";\n            this.InKeePassDatabaseRadio.UseVisualStyleBackColor = true;\n            // \n            // OnDiskRadio\n            // \n            this.OnDiskRadio.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.OnDiskRadio.AutoSize = true;\n            this.OnDiskRadio.Checked = true;\n            this.OnDiskRadio.Location = new System.Drawing.Point(18, 108);\n            this.OnDiskRadio.Name = \"OnDiskRadio\";\n            this.OnDiskRadio.Size = new System.Drawing.Size(186, 24);\n            this.OnDiskRadio.TabIndex = 3;\n            this.OnDiskRadio.TabStop = true;\n            this.OnDiskRadio.Text = \"On my local computer\";\n            this.OnDiskRadio.UseVisualStyleBackColor = true;\n            // \n            // FinishButton\n            // \n            this.FinishButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.FinishButton.Location = new System.Drawing.Point(278, 194);\n            this.FinishButton.Name = \"FinishButton\";\n            this.FinishButton.Size = new System.Drawing.Size(195, 63);\n            this.FinishButton.TabIndex = 5;\n            this.FinishButton.Text = \"&Finish\";\n            this.FinishButton.UseVisualStyleBackColor = true;\n            this.FinishButton.Click += new System.EventHandler(this.FinishButton_Click);\n            // \n            // HelpMeChooseLinkLabel\n            // \n            this.HelpMeChooseLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.HelpMeChooseLinkLabel.AutoSize = true;\n            this.HelpMeChooseLinkLabel.Location = new System.Drawing.Point(20, 157);\n            this.HelpMeChooseLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);\n            this.HelpMeChooseLinkLabel.Name = \"HelpMeChooseLinkLabel\";\n            this.HelpMeChooseLinkLabel.Size = new System.Drawing.Size(228, 20);\n            this.HelpMeChooseLinkLabel.TabIndex = 7;\n            this.HelpMeChooseLinkLabel.TabStop = true;\n            this.HelpMeChooseLinkLabel.Text = \"I have no idea, help me choose\";\n            this.HelpMeChooseLinkLabel.UseMnemonic = false;\n            this.HelpMeChooseLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.HelpMeChooseLinkLabel_LinkClicked);\n            // \n            // OneDriveRefreshTokenStorageDialog\n            // \n            this.AcceptButton = this.FinishButton;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(771, 283);\n            this.Controls.Add(this.HelpMeChooseLinkLabel);\n            this.Controls.Add(this.FinishButton);\n            this.Controls.Add(this.OnDiskRadio);\n            this.Controls.Add(this.InKeePassDatabaseRadio);\n            this.Controls.Add(this.ExplanationLabel);\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(602, 313);\n            this.Name = \"OneDriveRefreshTokenStorageDialog\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Where to store the OneDrive Refresh Token\";\n            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OneDriveRefreshTokenStorageDialog_FormClosing);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.Button FinishButton;\n        private System.Windows.Forms.RadioButton InKeePassDatabaseRadio;\n        private System.Windows.Forms.RadioButton OnDiskRadio;\n        private System.Windows.Forms.LinkLabel HelpMeChooseLinkLabel;\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partial class OneDriveRefreshTokenStorageDialog : Form\n    {\n        /// <summary>\n        /// Configuration of the database for which this question is being asked for\n        /// </summary>\n        private readonly Configuration _configuration;\n\n        public OneDriveRefreshTokenStorageDialog(Configuration configuration)\n        {\n            InitializeComponent();\n            \n            _configuration = configuration;\n        }\n\n        private void HelpMeChooseLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            System.Diagnostics.Process.Start(\"https://github.com/KoenZomers/KeePassOneDriveSync/wiki/OneDrive-Refresh-Token\");\n        }\n\n        private void FinishButton_Click(object sender, EventArgs e)\n        {\n            Close();\n        }\n\n        private void OneDriveRefreshTokenStorageDialog_FormClosing(object sender, FormClosingEventArgs e)\n        {\n            if (InKeePassDatabaseRadio.Checked)\n            {\n                _configuration.RefreshTokenStorage = OneDriveRefreshTokenStorage.KeePassDatabase;\n            }\n            if (OnDiskRadio.Checked)\n            {\n                _configuration.RefreshTokenStorage = OneDriveRefreshTokenStorage.DiskEncrypted;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRemoteLocationDialog.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class OneDriveRequestInputDialog\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.InputTextBox = new System.Windows.Forms.TextBox();\n            this.CancelButton = new System.Windows.Forms.Button();\n            this.OKButton = new System.Windows.Forms.Button();\n            this.SuspendLayout();\n            // \n            // InputTextBox\n            // \n            this.InputTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.InputTextBox.Location = new System.Drawing.Point(9, 10);\n            this.InputTextBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.InputTextBox.Name = \"InputTextBox\";\n            this.InputTextBox.Size = new System.Drawing.Size(301, 20);\n            this.InputTextBox.TabIndex = 0;\n            this.InputTextBox.TextChanged += new System.EventHandler(this.InputTextBoxTextBox_TextChanged);\n            this.InputTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.InputTextBox_KeyPress);\n            this.InputTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.InputTextBox_KeyUp);\n            // \n            // CancelButton\n            // \n            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.CancelButton.Location = new System.Drawing.Point(237, 41);\n            this.CancelButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.CancelButton.Name = \"CancelButton\";\n            this.CancelButton.Size = new System.Drawing.Size(72, 32);\n            this.CancelButton.TabIndex = 7;\n            this.CancelButton.Text = \"&Cancel\";\n            this.CancelButton.UseVisualStyleBackColor = true;\n            this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click);\n            // \n            // OKButton\n            // \n            this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK;\n            this.OKButton.Enabled = false;\n            this.OKButton.Location = new System.Drawing.Point(160, 41);\n            this.OKButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.OKButton.Name = \"OKButton\";\n            this.OKButton.Size = new System.Drawing.Size(72, 32);\n            this.OKButton.TabIndex = 6;\n            this.OKButton.Text = \"&OK\";\n            this.OKButton.UseVisualStyleBackColor = true;\n            this.OKButton.Click += new System.EventHandler(this.OKButton_Click);\n            // \n            // OneDriveRequestInputDialog\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(318, 82);\n            this.ControlBox = false;\n            this.Controls.Add(this.CancelButton);\n            this.Controls.Add(this.OKButton);\n            this.Controls.Add(this.InputTextBox);\n            this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"OneDriveRequestInputDialog\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.TextBox InputTextBox;\n        private System.Windows.Forms.Button CancelButton;\n        private System.Windows.Forms.Button OKButton;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync.Forms\n{\n    public partial class OneDriveRequestInputDialog : Form\n    {\n        /// <summary>\n        /// Gets or sets the value in the textbox\n        /// </summary>\n        public string InputValue\n        {\n            get { return InputTextBox.Text; }\n            set { InputTextBox.Text = value; }\n        }\n\n        /// <summary>\n        /// Title shown on the dialog\n        /// </summary>\n        public string FormTitle\n        {\n            get { return Text; }\n            set { Text = value; }\n        }\n\n        public OneDriveRequestInputDialog()\n        {\n            InitializeComponent();\n        }\n\n        private void OKButton_Click(object sender, EventArgs e)\n        {\n            DialogResult = DialogResult.OK;\n            Close();\n        }\n\n        private void CancelButton_Click(object sender, EventArgs e)\n        {\n            Close();\n        }\n\n        private void InputTextBoxTextBox_TextChanged(object sender, EventArgs e)\n        {\n            OKButton.Enabled = InputTextBox.Text.Length > 0;\n        }\n\n        private void InputTextBox_KeyPress(object sender, KeyPressEventArgs e)\n        {\n            \n        }\n\n        private void InputTextBox_KeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.Enter) OKButton_Click(sender, e);\n            if (e.KeyCode == Keys.Escape) Close();\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class SharePointCredentialsForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.label1 = new System.Windows.Forms.Label();\n            this.SharePointUrlTextBox = new System.Windows.Forms.TextBox();\n            this.label2 = new System.Windows.Forms.Label();\n            this.ClientIdTextBox = new System.Windows.Forms.TextBox();\n            this.ClientSecretTextBox = new System.Windows.Forms.TextBox();\n            this.label3 = new System.Windows.Forms.Label();\n            this.CancelButton = new System.Windows.Forms.Button();\n            this.OKButton = new System.Windows.Forms.Button();\n            this.TestButton = new System.Windows.Forms.Button();\n            this.SuspendLayout();\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(9, 7);\n            this.ExplanationLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(423, 29);\n            this.ExplanationLabel.TabIndex = 1;\n            this.ExplanationLabel.Text = \"Enter the details of the SharePoint 2013, 2016, 2019 or Online environment you wi\" +\n    \"sh to store the KeePass database on.\";\n            // \n            // label1\n            // \n            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.label1.Location = new System.Drawing.Point(9, 54);\n            this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(113, 19);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"SharePoint site URL:\";\n            // \n            // SharePointUrlTextBox\n            // \n            this.SharePointUrlTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.SharePointUrlTextBox.Location = new System.Drawing.Point(121, 54);\n            this.SharePointUrlTextBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.SharePointUrlTextBox.Name = \"SharePointUrlTextBox\";\n            this.SharePointUrlTextBox.Size = new System.Drawing.Size(312, 20);\n            this.SharePointUrlTextBox.TabIndex = 0;\n            this.SharePointUrlTextBox.TextChanged += new System.EventHandler(this.SharePointUrlTextBox_TextChanged);\n            this.SharePointUrlTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.SharePointUrlTextBox_KeyUp);\n            // \n            // label2\n            // \n            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.label2.Location = new System.Drawing.Point(9, 80);\n            this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(113, 19);\n            this.label2.TabIndex = 4;\n            this.label2.Text = \"Client Id:\";\n            // \n            // ClientIdTextBox\n            // \n            this.ClientIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ClientIdTextBox.Location = new System.Drawing.Point(121, 78);\n            this.ClientIdTextBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.ClientIdTextBox.Name = \"ClientIdTextBox\";\n            this.ClientIdTextBox.Size = new System.Drawing.Size(312, 20);\n            this.ClientIdTextBox.TabIndex = 1;\n            this.ClientIdTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ClientIdTextBox_KeyUp);\n            // \n            // ClientSecretTextBox\n            // \n            this.ClientSecretTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ClientSecretTextBox.Location = new System.Drawing.Point(121, 101);\n            this.ClientSecretTextBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.ClientSecretTextBox.Name = \"ClientSecretTextBox\";\n            this.ClientSecretTextBox.Size = new System.Drawing.Size(312, 20);\n            this.ClientSecretTextBox.TabIndex = 2;\n            this.ClientSecretTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ClientSecretTextBox_KeyUp);\n            // \n            // label3\n            // \n            this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.label3.Location = new System.Drawing.Point(9, 103);\n            this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);\n            this.label3.Name = \"label3\";\n            this.label3.Size = new System.Drawing.Size(113, 19);\n            this.label3.TabIndex = 6;\n            this.label3.Text = \"Client Secret:\";\n            // \n            // CancelButton\n            // \n            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.CancelButton.Location = new System.Drawing.Point(320, 131);\n            this.CancelButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.CancelButton.Name = \"CancelButton\";\n            this.CancelButton.Size = new System.Drawing.Size(112, 28);\n            this.CancelButton.TabIndex = 5;\n            this.CancelButton.Text = \"Cancel\";\n            this.CancelButton.UseVisualStyleBackColor = true;\n            this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click);\n            // \n            // OKButton\n            // \n            this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.OKButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.OKButton.Location = new System.Drawing.Point(204, 131);\n            this.OKButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.OKButton.Name = \"OKButton\";\n            this.OKButton.Size = new System.Drawing.Size(112, 28);\n            this.OKButton.TabIndex = 4;\n            this.OKButton.Text = \"OK\";\n            this.OKButton.UseVisualStyleBackColor = true;\n            this.OKButton.Click += new System.EventHandler(this.OKButton_Click);\n            // \n            // TestButton\n            // \n            this.TestButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.TestButton.Location = new System.Drawing.Point(88, 131);\n            this.TestButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.TestButton.Name = \"TestButton\";\n            this.TestButton.Size = new System.Drawing.Size(112, 28);\n            this.TestButton.TabIndex = 3;\n            this.TestButton.Text = \"Test Connection\";\n            this.TestButton.UseVisualStyleBackColor = true;\n            this.TestButton.Click += new System.EventHandler(this.TestButton_Click);\n            // \n            // SharePointCredentialsForm\n            // \n            this.AcceptButton = this.OKButton;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(441, 168);\n            this.Controls.Add(this.TestButton);\n            this.Controls.Add(this.OKButton);\n            this.Controls.Add(this.CancelButton);\n            this.Controls.Add(this.ClientSecretTextBox);\n            this.Controls.Add(this.label3);\n            this.Controls.Add(this.ClientIdTextBox);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.SharePointUrlTextBox);\n            this.Controls.Add(this.label1);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"SharePointCredentialsForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Provide SharePoint details\";\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.TextBox SharePointUrlTextBox;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.TextBox ClientIdTextBox;\n        private System.Windows.Forms.TextBox ClientSecretTextBox;\n        private System.Windows.Forms.Label label3;\n        private System.Windows.Forms.Button CancelButton;\n        private System.Windows.Forms.Button OKButton;\n        private System.Windows.Forms.Button TestButton;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync.Forms\n{\n    public partial class SharePointCredentialsForm : Form\n    {\n        #region Properties\n\n        /// <summary>\n        /// The entered SharePoint URL\n        /// </summary>\n        public string SharePointUrl {  get { return SharePointUrlTextBox.Text; } }\n\n        /// <summary>\n        /// The entered SharePoint Client Id\n        /// </summary>\n        public string SharePointClientId { get { return ClientIdTextBox.Text; } }\n\n        /// <summary>\n        /// The entered SharePoint Client Secret\n        /// </summary>\n        public string SharePointClientSecret { get { return ClientSecretTextBox.Text; } }\n\n        /// <summary>\n        /// Boolean indicating if the SharePointUrl, SharePointClientId and SharePointClientSecret fields all contain a value\n        /// </summary>\n        public bool AllFieldsContainText { get { return !string.IsNullOrWhiteSpace(SharePointUrlTextBox.Text) && !string.IsNullOrWhiteSpace(ClientIdTextBox.Text) && !string.IsNullOrWhiteSpace(ClientSecretTextBox.Text); } }\n        #endregion\n\n        public SharePointCredentialsForm()\n        {\n            InitializeComponent();\n        }\n\n        /// <summary>\n        /// Triggered when the user clicks the OK button\n        /// </summary>\n        private void OKButton_Click(object sender, EventArgs e)\n        {\n            if(!EnsureAllFieldsEntered())\n            {\n                DialogResult = DialogResult.None;\n            }\n            DialogResult = DialogResult.OK;\n        }\n\n        /// <summary>\n        /// Validates if all fields contain a value and if not, will display a notification to the nd user\n        /// </summary>\n        /// <returns>True if all fields contain a value, False if this is not the case</returns>\n        private bool EnsureAllFieldsEntered()\n        {\n            var allChecksPassed = AllFieldsContainText;\n\n            if(!allChecksPassed)\n            {\n                MessageBox.Show(this, \"All fields are required fields\", \"Please enter all fields\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n            }\n            return allChecksPassed;\n        }\n\n        /// <summary>\n        /// Uses the information provided in the form to try to establish a connection with SharePoint\n        /// </summary>\n        private async void TestButton_Click(object sender, EventArgs e)\n        {\n            // Ensure all fields contain a value\n            if(!EnsureAllFieldsEntered())\n            {\n                return;\n            }\n\n            // Ensure the entered URL is a valid URI\n            Uri SharePointUri;\n            if (!Uri.TryCreate(SharePointUrl, UriKind.Absolute, out SharePointUri))\n            {\n                MessageBox.Show(this, \"SharePoint site URL field does not contain a valid URL\", \"Invalid data entered\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n                SharePointUrlTextBox.SelectAll();\n                SharePointUrlTextBox.Focus();\n                return;\n            }\n\n            // Test the connection\n            try\n            {\n                using (var clientContext = Providers.SharePointProvider.CreateSharePointHttpClient(SharePointUri, SharePointClientId, SharePointClientSecret))\n                {\n                    if (await Providers.SharePointProvider.TestConnection(clientContext))\n                    {\n                        MessageBox.Show(\"Connection successful\", \"Testing SharePoint Connectivity\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n                    }\n                    else\n                    {\n                        MessageBox.Show(\"Connection failed\", \"Testing SharePoint Connectivity\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n                    }\n                }\n            }\n            catch(Exception ex)\n            {\n                MessageBox.Show(\"Connection failed: '\" + ex.Message + \"'. Check your entered Client ID and Client Secret.\", \"Testing SharePoint Connectivity\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n                ClientIdTextBox.SelectAll();\n                ClientIdTextBox.Focus();\n                return;\n            }\n        }\n\n        private void SharePointUrlTextBox_KeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.V && e.Control)\n            {\n                var clipText = Clipboard.GetText();\n                var clipTextSplitted = clipText.Split(new[] { '\\r', '\\n' });\n                if (clipTextSplitted.Length == 5)\n                {\n                    SharePointUrlTextBox.Text = clipTextSplitted[0];\n                    ClientIdTextBox.Text = clipTextSplitted[2];\n                    ClientSecretTextBox.Text = clipTextSplitted[4];\n                    e.SuppressKeyPress = false;\n                }                \n            }\n            e.SuppressKeyPress = true;\n        }\n\n        private void CancelButton_Click(object sender, EventArgs e)\n        {\n            DialogResult = DialogResult.Cancel;\n        }\n\n        private void SharePointUrlTextBox_TextChanged(object sender, EventArgs e)\n        {\n\n        }\n\n        private void ClientIdTextBox_KeyUp(object sender, KeyEventArgs e)\n        {\n            SharePointUrlTextBox_KeyUp(sender, e);\n        }\n\n        private void ClientSecretTextBox_KeyUp(object sender, KeyEventArgs e)\n        {\n            SharePointUrlTextBox_KeyUp(sender, e);\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.Designer.cs",
    "content": "﻿namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class SharePointDocumentLibraryPickerDialog\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SharePointDocumentLibraryPickerDialog));\n            this.SharePointDocumentLibraryPicker = new System.Windows.Forms.ListView();\n            this.ListViewContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);\n            this.refreshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.goToRootToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.goupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();\n            this.newFoldertoolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();\n            this.showHiddenLibrariesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.IconsList = new System.Windows.Forms.ImageList(this.components);\n            this.CancelButton = new System.Windows.Forms.Button();\n            this.OKButton = new System.Windows.Forms.Button();\n            this.CloudLocationPath = new System.Windows.Forms.TextBox();\n            this.ExplanationLabel = new System.Windows.Forms.Label();\n            this.FileNameLabel = new System.Windows.Forms.Label();\n            this.FileNameTextBox = new System.Windows.Forms.TextBox();\n            this.UpButton = new System.Windows.Forms.Button();\n            this.ListViewContextMenu.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // SharePointDocumentLibraryPicker\n            // \n            this.SharePointDocumentLibraryPicker.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.SharePointDocumentLibraryPicker.ContextMenuStrip = this.ListViewContextMenu;\n            this.SharePointDocumentLibraryPicker.HideSelection = false;\n            this.SharePointDocumentLibraryPicker.LargeImageList = this.IconsList;\n            this.SharePointDocumentLibraryPicker.Location = new System.Drawing.Point(14, 65);\n            this.SharePointDocumentLibraryPicker.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);\n            this.SharePointDocumentLibraryPicker.MultiSelect = false;\n            this.SharePointDocumentLibraryPicker.Name = \"SharePointDocumentLibraryPicker\";\n            this.SharePointDocumentLibraryPicker.ShowItemToolTips = true;\n            this.SharePointDocumentLibraryPicker.Size = new System.Drawing.Size(679, 386);\n            this.SharePointDocumentLibraryPicker.SmallImageList = this.IconsList;\n            this.SharePointDocumentLibraryPicker.TabIndex = 0;\n            this.SharePointDocumentLibraryPicker.TileSize = new System.Drawing.Size(244, 70);\n            this.SharePointDocumentLibraryPicker.UseCompatibleStateImageBehavior = false;\n            this.SharePointDocumentLibraryPicker.SelectedIndexChanged += new System.EventHandler(this.SharePointDocumentLibraryPicker_SelectedIndexChanged);\n            this.SharePointDocumentLibraryPicker.DoubleClick += new System.EventHandler(this.SharePointDocumentLibraryPicker_DoubleClick);\n            // \n            // ListViewContextMenu\n            // \n            this.ListViewContextMenu.ImageScalingSize = new System.Drawing.Size(20, 20);\n            this.ListViewContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.refreshToolStripMenuItem,\n            this.goToRootToolStripMenuItem,\n            this.goupToolStripMenuItem,\n            this.toolStripSeparator2,\n            this.newFoldertoolStripMenuItem,\n            this.renameToolStripMenuItem,\n            this.deleteToolStripMenuItem,\n            this.toolStripSeparator1,\n            this.showHiddenLibrariesToolStripMenuItem});\n            this.ListViewContextMenu.Name = \"ListViewContextMenu\";\n            this.ListViewContextMenu.Size = new System.Drawing.Size(255, 240);\n            // \n            // refreshToolStripMenuItem\n            // \n            this.refreshToolStripMenuItem.Name = \"refreshToolStripMenuItem\";\n            this.refreshToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5;\n            this.refreshToolStripMenuItem.Size = new System.Drawing.Size(254, 32);\n            this.refreshToolStripMenuItem.Text = \"&Refresh\";\n            this.refreshToolStripMenuItem.Click += new System.EventHandler(this.refreshToolStripMenuItem_Click);\n            // \n            // goToRootToolStripMenuItem\n            // \n            this.goToRootToolStripMenuItem.Name = \"goToRootToolStripMenuItem\";\n            this.goToRootToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.H)));\n            this.goToRootToolStripMenuItem.Size = new System.Drawing.Size(254, 32);\n            this.goToRootToolStripMenuItem.Text = \"&Go to root\";\n            this.goToRootToolStripMenuItem.Click += new System.EventHandler(this.goToRootToolStripMenuItem_Click);\n            // \n            // goupToolStripMenuItem\n            // \n            this.goupToolStripMenuItem.Enabled = false;\n            this.goupToolStripMenuItem.Name = \"goupToolStripMenuItem\";\n            this.goupToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U)));\n            this.goupToolStripMenuItem.Size = new System.Drawing.Size(254, 32);\n            this.goupToolStripMenuItem.Text = \"Go &up\";\n            this.goupToolStripMenuItem.Click += new System.EventHandler(this.goupToolStripMenuItem_Click);\n            // \n            // toolStripSeparator2\n            // \n            this.toolStripSeparator2.Name = \"toolStripSeparator2\";\n            this.toolStripSeparator2.Size = new System.Drawing.Size(251, 6);\n            // \n            // newFoldertoolStripMenuItem\n            // \n            this.newFoldertoolStripMenuItem.Name = \"newFoldertoolStripMenuItem\";\n            this.newFoldertoolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));\n            this.newFoldertoolStripMenuItem.Size = new System.Drawing.Size(254, 32);\n            this.newFoldertoolStripMenuItem.Text = \"&New Folder\";\n            this.newFoldertoolStripMenuItem.Click += new System.EventHandler(this.newFoldertoolStripMenuItem_Click);\n            // \n            // renameToolStripMenuItem\n            // \n            this.renameToolStripMenuItem.Name = \"renameToolStripMenuItem\";\n            this.renameToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));\n            this.renameToolStripMenuItem.Size = new System.Drawing.Size(254, 32);\n            this.renameToolStripMenuItem.Text = \"&Rename\";\n            this.renameToolStripMenuItem.Click += new System.EventHandler(this.renameToolStripMenuItem_Click);\n            // \n            // deleteToolStripMenuItem\n            // \n            this.deleteToolStripMenuItem.Name = \"deleteToolStripMenuItem\";\n            this.deleteToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;\n            this.deleteToolStripMenuItem.Size = new System.Drawing.Size(254, 32);\n            this.deleteToolStripMenuItem.Text = \"&Delete\";\n            this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click);\n            // \n            // toolStripSeparator1\n            // \n            this.toolStripSeparator1.Name = \"toolStripSeparator1\";\n            this.toolStripSeparator1.Size = new System.Drawing.Size(251, 6);\n            // \n            // showHiddenLibrariesToolStripMenuItem\n            // \n            this.showHiddenLibrariesToolStripMenuItem.Name = \"showHiddenLibrariesToolStripMenuItem\";\n            this.showHiddenLibrariesToolStripMenuItem.Size = new System.Drawing.Size(254, 32);\n            this.showHiddenLibrariesToolStripMenuItem.Text = \"Show hidden libraries\";\n            this.showHiddenLibrariesToolStripMenuItem.Click += new System.EventHandler(this.showHiddenLibrariesToolStripMenuItem_Click);\n            // \n            // IconsList\n            // \n            this.IconsList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject(\"IconsList.ImageStream\")));\n            this.IconsList.TransparentColor = System.Drawing.Color.Transparent;\n            this.IconsList.Images.SetKeyName(0, \"File\");\n            this.IconsList.Images.SetKeyName(1, \"Folder\");\n            this.IconsList.Images.SetKeyName(2, \"DocLib\");\n            // \n            // CancelButton\n            // \n            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.CancelButton.Location = new System.Drawing.Point(585, 461);\n            this.CancelButton.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);\n            this.CancelButton.Name = \"CancelButton\";\n            this.CancelButton.Size = new System.Drawing.Size(108, 49);\n            this.CancelButton.TabIndex = 3;\n            this.CancelButton.Text = \"&Cancel\";\n            this.CancelButton.UseVisualStyleBackColor = true;\n            // \n            // OKButton\n            // \n            this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.OKButton.Enabled = false;\n            this.OKButton.Location = new System.Drawing.Point(469, 461);\n            this.OKButton.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);\n            this.OKButton.Name = \"OKButton\";\n            this.OKButton.Size = new System.Drawing.Size(108, 49);\n            this.OKButton.TabIndex = 2;\n            this.OKButton.Text = \"&OK\";\n            this.OKButton.UseVisualStyleBackColor = true;\n            this.OKButton.Click += new System.EventHandler(this.OKButton_Click);\n            // \n            // CloudLocationPath\n            // \n            this.CloudLocationPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.CloudLocationPath.BackColor = System.Drawing.SystemColors.Control;\n            this.CloudLocationPath.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.CloudLocationPath.Location = new System.Drawing.Point(17, 39);\n            this.CloudLocationPath.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);\n            this.CloudLocationPath.Name = \"CloudLocationPath\";\n            this.CloudLocationPath.Size = new System.Drawing.Size(607, 19);\n            this.CloudLocationPath.TabIndex = 6;\n            this.CloudLocationPath.TabStop = false;\n            // \n            // ExplanationLabel\n            // \n            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.ExplanationLabel.Location = new System.Drawing.Point(14, 11);\n            this.ExplanationLabel.Name = \"ExplanationLabel\";\n            this.ExplanationLabel.Size = new System.Drawing.Size(679, 46);\n            this.ExplanationLabel.TabIndex = 8;\n            this.ExplanationLabel.Text = \"Select the document library in which you want to store the KeePass database.\";\n            // \n            // FileNameLabel\n            // \n            this.FileNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));\n            this.FileNameLabel.Location = new System.Drawing.Point(14, 471);\n            this.FileNameLabel.Name = \"FileNameLabel\";\n            this.FileNameLabel.Size = new System.Drawing.Size(87, 28);\n            this.FileNameLabel.TabIndex = 11;\n            this.FileNameLabel.Text = \"Filename:\";\n            // \n            // FileNameTextBox\n            // \n            this.FileNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.FileNameTextBox.Location = new System.Drawing.Point(107, 471);\n            this.FileNameTextBox.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);\n            this.FileNameTextBox.Name = \"FileNameTextBox\";\n            this.FileNameTextBox.Size = new System.Drawing.Size(355, 26);\n            this.FileNameTextBox.TabIndex = 1;\n            this.FileNameTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.FileNameTextBox_KeyUp);\n            // \n            // UpButton\n            // \n            this.UpButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.UpButton.Enabled = false;\n            this.UpButton.Location = new System.Drawing.Point(631, 8);\n            this.UpButton.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);\n            this.UpButton.Name = \"UpButton\";\n            this.UpButton.Size = new System.Drawing.Size(62, 50);\n            this.UpButton.TabIndex = 4;\n            this.UpButton.Text = \"Up\";\n            this.UpButton.UseVisualStyleBackColor = true;\n            this.UpButton.Click += new System.EventHandler(this.UpButton_Click);\n            // \n            // SharePointDocumentLibraryPickerDialog\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(706, 521);\n            this.Controls.Add(this.UpButton);\n            this.Controls.Add(this.FileNameLabel);\n            this.Controls.Add(this.FileNameTextBox);\n            this.Controls.Add(this.ExplanationLabel);\n            this.Controls.Add(this.CloudLocationPath);\n            this.Controls.Add(this.CancelButton);\n            this.Controls.Add(this.OKButton);\n            this.Controls.Add(this.SharePointDocumentLibraryPicker);\n            this.KeyPreview = true;\n            this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);\n            this.MinimizeBox = false;\n            this.MinimumSize = new System.Drawing.Size(406, 228);\n            this.Name = \"SharePointDocumentLibraryPickerDialog\";\n            this.ShowIcon = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n            this.Text = \"Select location\";\n            this.ListViewContextMenu.ResumeLayout(false);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.ListView SharePointDocumentLibraryPicker;\n        private System.Windows.Forms.Button CancelButton;\n        private System.Windows.Forms.Button OKButton;\n        private System.Windows.Forms.TextBox CloudLocationPath;\n        private System.Windows.Forms.ImageList IconsList;\n        private System.Windows.Forms.Label ExplanationLabel;\n        private System.Windows.Forms.Label FileNameLabel;\n        private System.Windows.Forms.TextBox FileNameTextBox;\n        private System.Windows.Forms.Button UpButton;\n        private System.Windows.Forms.ContextMenuStrip ListViewContextMenu;\n        private System.Windows.Forms.ToolStripMenuItem refreshToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem goToRootToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem goupToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;\n        private System.Windows.Forms.ToolStripMenuItem showHiddenLibrariesToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem newFoldertoolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;\n        private System.Windows.Forms.ToolStripMenuItem renameToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem;\n    }\n}"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Newtonsoft.Json.Linq;\n\nnamespace KoenZomersKeePassOneDriveSync.Forms\n{\n    public partial class SharePointDocumentLibraryPickerDialog : System.Windows.Forms.Form\n    {\n        #region Properties\n\n        /// <summary>\n        /// Returns the server relative URL of the selected SharePoint Document Library\n        /// </summary>\n        public string SelectedDocumentLibraryServerRelativeUrl { get { return currentViewServerRelativeUrl ?? (SharePointDocumentLibraryPicker.SelectedItems.Count > 0 ? SharePointDocumentLibraryPicker.SelectedItems[0].Tag.ToString() : null); } }\n\n        /// <summary>\n        /// Gets or sets the filename in the textbox on the screen\n        /// </summary>\n        public string FileName\n        {\n            get { return FileNameTextBox.Text; }\n            set { FileNameTextBox.Text = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets the text shown at the top of the form\n        /// </summary>\n        public string ExplanationText\n        {\n            get { return ExplanationLabel.Text; }\n            set { ExplanationLabel.Text = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets if the user can enter a filename which does not exist yet on their OneDrive\n        /// </summary>\n        public bool AllowEnteringNewFileName\n        {\n            get { return FileNameTextBox.Enabled; }\n            set { FileNameTextBox.Enabled = value; }\n        }\n\n        /// <summary>\n        /// Gets or sets if hidden document libraries should be shown\n        /// </summary>\n        public bool ShowHiddenLibraries { get; set; }\n\n        #endregion\n\n        /// <summary>\n        /// Instance of the HttpClient that can be used to communicate with SharePoint\n        /// </summary>\n        private readonly HttpClient _httpClient;\n\n        /// <summary>\n        /// The server relative url of the currently selected document library\n        /// </summary>\n        private string documentLibraryServerRelativeUrl = null;\n\n        /// <summary>\n        /// The server relative url of the currently shown view\n        /// </summary>\n        private string currentViewServerRelativeUrl = null;\n\n        public SharePointDocumentLibraryPickerDialog(HttpClient httpClient)\n        {\n            InitializeComponent();\n\n            _httpClient = httpClient;\n        }\n\n        /// <summary>\n        /// Gets the document library items and renders them in the form\n        /// </summary>\n        public async Task LoadDocumentLibraryItems()\n        {\n            SharePointDocumentLibraryPicker.Items.Clear();\n            currentViewServerRelativeUrl = \"\";\n\n            // Request all document libraries\n            var response = await _httpClient.GetAsync(\"web/lists?$select=Title,RootFolder/ServerRelativeUrl&$filter=BaseTemplate eq 101\" + (ShowHiddenLibraries ? \"\" : \" and Hidden eq false\") + \"&$expand=RootFolder\");\n\n            // Validate if the request was successful\n            if (!response.IsSuccessStatusCode)\n            {\n                // Request was unsuccessful\n                return;\n            }\n\n            // Request was succesful. Parse the JSON result.\n            var responseJson = JObject.Parse(await response.Content.ReadAsStringAsync());\n\n            // Loop through each document library in the result\n            foreach (var listViewItem in responseJson[\"value\"])\n            {\n                // Create a new tile in the form for each document library\n                SharePointDocumentLibraryPicker.Items.Add(new ListViewItem\n                {\n                    Text = listViewItem[\"Title\"].ToString(),\n                    Tag = listViewItem[\"RootFolder\"][\"ServerRelativeUrl\"].ToString(),\n                    ImageKey = \"DocLib\",\n                    Selected = listViewItem[\"Title\"].ToString().Equals(FileNameTextBox.Text, StringComparison.InvariantCultureIgnoreCase)\n                });\n            }\n\n            // Do not allow the use of the up button or the root context menu option as this is the highest level\n            UpButton.Enabled = false;\n            goupToolStripMenuItem.Enabled = false;\n            goToRootToolStripMenuItem.Enabled = false;\n            deleteToolStripMenuItem.Enabled = false;\n            renameToolStripMenuItem.Enabled = false;\n        }\n\n        /// <summary>\n        /// Gets the folders and files inside a document library items and renders them in the form\n        /// </summary>\n        public async Task LoadDocumentLibraryFileAndFolderItems(string serverRelativeUrl)\n        {\n            currentViewServerRelativeUrl = serverRelativeUrl;\n\n            SharePointDocumentLibraryPicker.Items.Clear();\n\n            // Request all folders\n            using (var foldersResponse = await _httpClient.GetAsync(\"web/GetFolderByServerRelativeUrl('\" + serverRelativeUrl + \"')/Folders?$select=Name,ServerRelativeUrl,ItemCount,TimeCreated,TimeLastModified\"))\n            {\n                // Validate if the request was successful\n                if (!foldersResponse.IsSuccessStatusCode)\n                {\n                    // Request was unsuccessful\n                    return;\n                }\n\n                // Request was succesful. Parse the JSON result.\n                var foldersResponseJson = JObject.Parse(await foldersResponse.Content.ReadAsStringAsync());\n\n                // Loop through each document library in the result\n                foreach (var listViewItem in foldersResponseJson[\"value\"])\n                {\n                    // Create a new tile in the form for each document library\n                    var folderItem = new ListViewItem\n                    {\n                        Text = listViewItem[\"Name\"].ToString(),\n                        Tag = listViewItem[\"ServerRelativeUrl\"].ToString(),\n                        ImageKey = \"Folder\"                        \n                    };\n\n                    long itemCount;\n                    if (listViewItem[\"ItemCount\"] != null && long.TryParse(listViewItem[\"ItemCount\"].ToString(), out itemCount))\n                    {\n                        folderItem.ToolTipText += string.Format(\"Items inside: {0}\", itemCount) + Environment.NewLine;\n                    }\n                    DateTime created;\n                    if (listViewItem[\"TimeCreated\"] != null && DateTime.TryParse(listViewItem[\"TimeCreated\"].ToString(), out created))\n                    {\n                        folderItem.ToolTipText += string.Format(\"Created: {0:d MMMM yyyy HH:mm:ss}\", created) + Environment.NewLine;\n                    }\n                    DateTime lastModified;\n                    if (listViewItem[\"TimeLastModified\"] != null && DateTime.TryParse(listViewItem[\"TimeLastModified\"].ToString(), out lastModified))\n                    {\n                        folderItem.ToolTipText += string.Format(\"Last modified: {0:d MMMM yyyy HH:mm:ss}\", lastModified) + Environment.NewLine;\n                    }\n\n                    SharePointDocumentLibraryPicker.Items.Add(folderItem);\n                }\n            }\n\n            // Request all files\n            using (var filesResponse = await _httpClient.GetAsync(\"web/GetFolderByServerRelativeUrl('\" + serverRelativeUrl + \"')/Files?$select=Name,ServerRelativeUrl,TimeLastModified,TimeCreated,UIVersionLabel,Length\"))\n            {\n                // Validate if the request was successful\n                if (!filesResponse.IsSuccessStatusCode)\n                {\n                    // Request was unsuccessful\n                    return;\n                }\n\n                // Request was succesful. Parse the JSON result.\n                var filesResponseJson = JObject.Parse(await filesResponse.Content.ReadAsStringAsync());\n\n                // Loop through each file in the result\n                foreach (var listViewItem in filesResponseJson[\"value\"])\n                {\n                    // Create a new tile in the form for each file\n                    var fileItem = new ListViewItem\n                    {\n                        Text = listViewItem[\"Name\"].ToString(),\n                        Tag = listViewItem[\"ServerRelativeUrl\"].ToString(),\n                        ImageKey = \"File\",\n                        Selected = listViewItem[\"Name\"].ToString().Equals(FileNameTextBox.Text, StringComparison.InvariantCultureIgnoreCase)\n                    };\n\n                    long fileSize;\n                    if (listViewItem[\"Length\"] != null && long.TryParse(listViewItem[\"Length\"].ToString(), out fileSize))\n                    {\n                        fileItem.ToolTipText += string.Format(\"Size: {0:n0} bytes\", fileSize) + Environment.NewLine;\n                    }\n                    if (listViewItem[\"UIVersionLabel\"] != null && listViewItem[\"UIVersionLabel\"].ToString().Length > 0)\n                    {\n                        fileItem.ToolTipText += string.Format(\"Version: {0}\", listViewItem[\"UIVersionLabel\"]) + Environment.NewLine;\n                    }\n                    DateTime created;\n                    if (listViewItem[\"TimeCreated\"] != null && DateTime.TryParse(listViewItem[\"TimeCreated\"].ToString(), out created))\n                    {\n                        fileItem.ToolTipText += string.Format(\"Created: {0:d MMMM yyyy HH:mm:ss}\", created) + Environment.NewLine;\n                    }\n                    DateTime lastModified;\n                    if (listViewItem[\"TimeLastModified\"] != null && DateTime.TryParse(listViewItem[\"TimeLastModified\"].ToString(), out lastModified))\n                    {\n                        fileItem.ToolTipText += string.Format(\"Last modified: {0:d MMMM yyyy HH:mm:ss}\", lastModified) + Environment.NewLine;\n                    }\n\n                    SharePointDocumentLibraryPicker.Items.Add(fileItem);\n                }\n            }\n\n            // Allow the use of the up button and root context menu option as you can always navigate up to the document library list level\n            UpButton.Enabled = true;\n            goupToolStripMenuItem.Enabled = true;\n            goToRootToolStripMenuItem.Enabled = true;\n            deleteToolStripMenuItem.Enabled = false;\n            renameToolStripMenuItem.Enabled = false;\n        }\n\n        private async void SharePointDocumentLibraryPicker_DoubleClick(object sender, EventArgs e)\n        {\n            if (SharePointDocumentLibraryPicker.SelectedItems.Count == 0) return;\n            var selectedItem = SharePointDocumentLibraryPicker.SelectedItems[0];\n\n            switch (selectedItem.ImageKey)\n            {\n                case \"DocLib\":\n                    documentLibraryServerRelativeUrl = selectedItem.Tag.ToString();\n                    await LoadDocumentLibraryFileAndFolderItems(selectedItem.Tag.ToString());\n                    break;\n\n                case \"Folder\":\n                    await LoadDocumentLibraryFileAndFolderItems(selectedItem.Tag.ToString());\n                    break;\n\n                case \"File\":\n                    if (OKButton.Enabled)\n                    {\n                        OKButton_Click(sender, e);\n                    }\n                    break;\n            }\n        }\n\n        private void OKButton_Click(object sender, EventArgs e)\n        {\n            if(string.IsNullOrEmpty(SelectedDocumentLibraryServerRelativeUrl))\n            {\n                MessageBox.Show(AllowEnteringNewFileName ? \"Select a document library to store the KeePass database in\" : \"Select the KeePass file to download\", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);\n                return;\n            }\n\n            if(string.IsNullOrWhiteSpace(FileName))\n            {\n                MessageBox.Show(AllowEnteringNewFileName ? \"Enter the filename under which you wish to store the database\" : \"Select the KeePass file to download\", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);\n                return;\n            }\n\n            DialogResult = DialogResult.OK;\n            Close();\n        }\n\n        private void SharePointDocumentLibraryPicker_SelectedIndexChanged(object sender, EventArgs e)\n        {\n            if (SharePointDocumentLibraryPicker.SelectedItems.Count > 0 && SharePointDocumentLibraryPicker.SelectedItems[0].ImageKey == \"File\")\n            {\n                FileName = SharePointDocumentLibraryPicker.SelectedItems[0].Text;\n            }\n            \n            // Enable the OK button only when an item has been selected and a filename has been provided\n            OKButton.Enabled = SharePointDocumentLibraryPicker.SelectedItems.Count > 0 && !string.IsNullOrEmpty(FileName);\n\n            // Don't allow deletion or renames of complete document libraries\n            deleteToolStripMenuItem.Enabled = renameToolStripMenuItem.Enabled = SharePointDocumentLibraryPicker.SelectedItems.Count > 0 && SharePointDocumentLibraryPicker.SelectedItems[0].ImageKey != \"DocLib\";\n        }\n\n        private void showHiddenLibrariesToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            ShowHiddenLibraries = !ShowHiddenLibraries;\n            showHiddenLibrariesToolStripMenuItem.Checked = ShowHiddenLibraries;\n\n            refreshToolStripMenuItem_Click(sender, e);\n        }\n\n        private async void refreshToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (!string.IsNullOrEmpty(currentViewServerRelativeUrl))\n            {\n                await LoadDocumentLibraryFileAndFolderItems(currentViewServerRelativeUrl);\n            }\n            else\n            {\n                await LoadDocumentLibraryItems();\n            }\n        }\n\n        private async void UpButton_Click(object sender, EventArgs e)\n        {\n            var newServerRelativeUrl = currentViewServerRelativeUrl.Remove(currentViewServerRelativeUrl.LastIndexOf('/'));\n            if(newServerRelativeUrl.Length < documentLibraryServerRelativeUrl.Length)\n            {\n                await LoadDocumentLibraryItems();\n            }\n            else\n            {\n                await LoadDocumentLibraryFileAndFolderItems(newServerRelativeUrl);\n            }\n        }\n\n        private async void goToRootToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            await LoadDocumentLibraryItems();\n        }\n\n        private void goupToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            UpButton_Click(sender, e);\n        }\n\n        private void FileNameTextBox_KeyUp(object sender, KeyEventArgs e)\n        {\n            if(e.KeyCode == Keys.Enter && OKButton.Enabled)\n            {\n                OKButton_Click(sender, e);\n            }\n        }\n\n        private async void newFoldertoolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            var newFolderDialog = new OneDriveRequestInputDialog\n            {\n                FormTitle = \"Create new folder\"\n            };\n            newFolderDialog.ShowDialog(this);\n            if (newFolderDialog.DialogResult != DialogResult.OK) return;\n\n            try\n            {\n                var newFolderServerRelativeUrl = await Providers.SharePointProvider.CreateFolder(newFolderDialog.InputValue, SelectedDocumentLibraryServerRelativeUrl, _httpClient);\n                MessageBox.Show(\"Folder has been created\", \"New Folder\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n\n                // Refresh the items shown\n                refreshToolStripMenuItem_Click(sender, e);\n            }\n            catch (Exception ex)\n            {\n                MessageBox.Show(\"Folder could not be created (\" + ex.Message + \")\", \"New Folder\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n            }\n        }\n\n        private async void deleteToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (SharePointDocumentLibraryPicker.SelectedItems.Count == 0 || SharePointDocumentLibraryPicker.SelectedItems[0].ImageKey == \"DocLib\") return;\n\n            var selectedItem = SharePointDocumentLibraryPicker.SelectedItems[0];\n            var confirm = MessageBox.Show(\"Are you sure you want to delete the selected \" + selectedItem.ImageKey.ToLowerInvariant() + \"? \" + (selectedItem.ImageKey == \"Folder\" ? \"Note that folders can only be removed if there's nothing inside anymore. \" : \"\"), \"Confirm deletion\", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);\n            if (confirm != DialogResult.Yes) return;\n\n            bool operationSuccessful = false;\n            switch(selectedItem.ImageKey)\n            {\n                case \"File\":\n                    operationSuccessful = await Providers.SharePointProvider.DeleteFile(selectedItem.Tag.ToString(), _httpClient);\n                    break;\n\n                case \"Folder\":\n                    operationSuccessful = await Providers.SharePointProvider.DeleteFolder(selectedItem.Tag.ToString(), _httpClient);\n                    break;\n\n                default:\n                    MessageBox.Show(\"Item type '\" + selectedItem.ImageKey + \"' is not implemented for this operation.\", \"Delete item\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n                    return;\n            }\n\n            if(operationSuccessful)\n            { \n                MessageBox.Show(selectedItem.ImageKey + \" has been deleted\", \"Delete item\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n            }\n            else\n            {\n                MessageBox.Show(\"Unable to delete \" + selectedItem.ImageKey.ToLowerInvariant(), \"Delete item\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n            }\n\n            // Refresh the items shown\n            refreshToolStripMenuItem_Click(sender, e);\n        }\n\n        private async void renameToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (SharePointDocumentLibraryPicker.SelectedItems.Count == 0 || SharePointDocumentLibraryPicker.SelectedItems[0].ImageKey == \"DocLib\") return;\n\n            var selectedItem = SharePointDocumentLibraryPicker.SelectedItems[0];\n\n            var renameItemDialog = new OneDriveRequestInputDialog\n            {\n                FormTitle = \"Enter new name\",\n                InputValue = selectedItem.Text\n            };\n            renameItemDialog.ShowDialog(this);\n            if (renameItemDialog.DialogResult != DialogResult.OK) return;\n\n            bool operationSuccessful = false;\n            switch (selectedItem.ImageKey)\n            {\n                case \"File\":\n                    operationSuccessful = await Providers.SharePointProvider.RenameFile(renameItemDialog.InputValue, selectedItem.Tag.ToString(), _httpClient);\n                    break;\n\n                case \"Folder\":\n                    operationSuccessful = await Providers.SharePointProvider.RenameFolder(renameItemDialog.InputValue, selectedItem.Tag.ToString(), _httpClient);\n                    break;\n\n                default:\n                    MessageBox.Show(\"Item type '\" + selectedItem.ImageKey + \"' is not implemented for this operation.\", \"Rename item\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n                    return;\n            }\n\n            if (operationSuccessful)\n            {\n                MessageBox.Show(selectedItem.ImageKey + \" has been renamed\", \"Rename item\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n            }\n            else\n            {\n                MessageBox.Show(\"Unable to rename \" + selectedItem.ImageKey.ToLowerInvariant(), \"Rename item\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n            }\n\n            // Refresh the items shown\n            refreshToolStripMenuItem_Click(sender, e);\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"ListViewContextMenu.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>140, 17</value>\n  </metadata>\n  <metadata name=\"IconsList.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>21, 14</value>\n  </metadata>\n  <data name=\"IconsList.ImageStream\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n    <value>\n        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w\n        LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0\n        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABK\n        uAAAAk1TRnQBSQFMAgEBAwEAAXgBAAF4AQABQAEAAUABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgEAAEB\n        AgABQAMAAQEBAAEgBwABAREA/////wL/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEA\n        /////wL/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEA/////wL/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf//AAEA/////wL/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AdEBeQFAAf8B2wGaAWgB/wHbAZsBaQH/AdwBmwFqAf8B3AGcAWoB/wHc\n        AZwBawH/AdwBnAFrAf8B3AGdAWwB/wHcAZ0BbQH/Ad0BngFuAf8B3QGeAW4B/wHdAZ8BbwH/Ad0BnwFw\n        Af8B3QGgAXAB/wHdAaABcQH/Ad4BoQFyAf8B3gGhAXIB/wHeAaIBcwH/Ad4BogF0Af8B3gGjAXUB/wHe\n        AaMBdQH/Ad0BoAFxAf8ByAFfARsB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af//AAEA/////wL/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AeUBtAGTAf8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/AfsB9QHxAf8BzQFs\n        AS4B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEA/////wL/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AeQBtAGTAf8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/AfsB9QHxAf8BzQFtAS8B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEA/////wL/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AeQBswGSAf8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/AfsB9QHxAf8BzQFuATAB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf//AAEA/////wL/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AeQBswGSAf8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/AfsB9gHx\n        Af8BzgFuATEB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEAPP8D/QH/\n        A/wB/wP7Af8D+gH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/\n        A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/\n        A/kB/wP7Af8D/QH/A/4B/wP+//82/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHkAbMBkQH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH7\n        AfYB8QH/Ac4BbwEyAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/\n        A/QB/wPoAf8D3gH/A9MB/wPNAf8DzQH/A80B/wPNAf8DzQH/A80B/wPNAf8DzQH/A80B/wPNAf8DzQH/\n        A80B/wPNAf8DzQH/A80B/wPNAf8DzQH/A80B/wPNAf8DzQH/A80B/wPNAf8DzQH/A80B/wPNAf8DzQH/\n        A80B/wPRAf8D4AH/A+8B/wP2Af8D/f//Nv8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8B5AGyAZAB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B+wH2AfEB/wHOAXABMwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQA8/wPqAf8D1QH/A8AB/wOsAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/\n        A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/\n        A6EB/wOhAf8DqAH/A8YB/wPiAf8D7wH/A/v//zb/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AeQBsgGQAf8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/AfsB9gHxAf8BzgFxATUB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af//AAEAPP8D5QH/A8sB/wO1Af8DnwH/A5cB/wOgAf8DpgH/A6YB/wOmAf8DpgH/A6YB/wOmAf8DpgH/\n        A6YB/wOmAf8DpgH/A6YB/wOmAf8DpgH/A6YB/wOmAf8DpgH/A6YB/wOmAf8DpgH/A6YB/wOmAf8DpQH/\n        A6QB/wOfAf8DlQH/A5cB/wO5Af8D2wH/A+sB/wP7//82/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHjAbEBjwH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH7AfYB8gH/Ac8BcQE1Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH//wABADz/A+EB/wPDAf8DqwH/A5UB/wORAf8DpAH/A7MB/wOzAf8DswH/A7MB/wOzAf8DswH/\n        A7MB/wOzAf8DswH/A7MB/wOzAf8DswH/A7MB/wOzAf8DswH/A7MB/wOzAf8DswH/A7MB/wOzAf8DswH/\n        A7EB/wOuAf8DogH/A40B/wOIAf8DrwH/A9YB/wPoAf8D+v//Nv8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B4wGxAY4B/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B+wH2AfIB/wHPAXIBNwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B//8AAQA8/wPgAf8DwAH/A6oB/wOWAf8DmAH/A7UB/wPLAf8DywH/A8sB/wPLAf8DywH/\n        A8sB/wPLAf8DywH/A8sB/wPLAf8DywH/A8sB/wPLAf8DywH/A8sB/wPLAf8DywH/A8sB/wPLAf8DywH/\n        A8sB/wPIAf8DxAH/A7EB/wORAf8DhAH/A6wB/wPUAf8D5wH/A/r//zb/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AeMBsAGNAf8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/AfsB9gHyAf8BzwFzATgB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf//AAEAPP8D4AH/A8AB/wOtAf8DngH/A6YB/wPMAf8D6wH/A+sB/wPrAf8D6wH/\n        A+sB/wPrAf8D6wH/A+sB/wPrAf8D6wH/A+sB/wPrAf8D6wH/A+sB/wPrAf8D6wH/A+sB/wPrAf8D6wH/\n        A+sB/wPrAf8D5wH/A+EB/wPIAf8DnAH/A4cB/wOuAf8D1AH/A+cB/wP6//82/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFXAQ8B/wHF\n        AVcBDwH/AcUBWAEPAf8BxQFYARAB/wHFAVgBEAH/AcUBWAEQAf8BxQFYARAB/wHFAVgBEAH/AcUBWAEQ\n        Af8BxQFYARAB/wHGAVgBEQH/AcYBWAERAf8BxgFZAREB/wHGAVkBEQH/AcYBWQERAf8BxgFZAREB/wHG\n        AVkBEQH/AcYBWQESAf8BxgFZARIB/wHGAVkBEgH/AcYBWQESAf8BxgFZARIB/wHGAVoBEgH/AcYBWgES\n        Af8BxgFaARMB/wHGAVoBEwH/AcYBWQESAf8BxQFWAQ0B/wHjAbABjQH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH7AfYB8gH/Ac8BdAE5Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D21X/A/oB/wPzAf8D1gH/\n        A6MB/wOJAf8DrgH/A9QB/wPnAf8D+v//Nv8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHHAV0BFwH/AeQBtAGTAf8B5wG8AZ4B/wHnAb0BoAH/AecBvQGh\n        Af8B6AG+AaIB/wHoAb8BowH/AegBwAGkAf8B6QHAAaUB/wHpAcEBpwH/AekBwgGnAf8B6QHDAakB/wHq\n        AcQBqQH/AeoBxQGrAf8B6gHFAawB/wHrAcYBrQH/AesBxwGuAf8B6wHIAa8B/wHrAcgBsAH/AewByQGy\n        Af8B7AHKAbIB/wHsAcsBtAH/AewBywG1Af8B7QHMAbYB/wHtAc0BtwH/Ae0BzgG4Af8B7QHOAbkB/wHo\n        Ab0BoAH/AcYBWwEUAf8B4wGvAYwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B+wH2AfIB/wHQAXQBOgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQA8/wPgAf8DwAH/A68B/wOiAf8DrwH/A9tV/wP6Af8D8wH/A9YB/wOjAf8DiQH/A64B/wPUAf8D5wH/\n        A/pp/wH1AfsB/QH/AekB9QH8Af8B5wH0AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/\n        AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0\n        AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/\n        AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0\n        AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0AfwB/wHnAfQB/AH/AecB9AH8Af8B5wH0AfwB/wHrAfYB/AH/\n        AfAB+AH9Af8B+QH8Af4x/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AckBYwEfAf8B+gHyAe0B/wH9AfsB+QH/AfsB9AHwAf8B+wH0AfAB/wH7AfQB7wH/\n        AfsB8wHuAf8B+gHzAe0B/wH6AfIB7QH/AfoB8gHsAf8B+gHxAesB/wH6AfEB6gH/AfkB8AHqAf8B+QHw\n        AekB/wH5Ae8B6AH/AfkB7wHoAf8B+QHuAecB/wH5Ae4B5gH/AfgB7QHmAf8B+AHtAeUB/wH4AewB5AH/\n        AfgB7AHjAf8B+AHrAeMB/wH4AesB4gH/AfcB6gHhAf8B9wHqAeEB/wH3AeoB4AH/Ae8B1AHBAf8BxwFc\n        ARYB/wHjAa8BjAH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH7AfYB8gH/\n        AdABdQE7Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPA\n        Af8DrwH/A6IB/wOvAf8D21X/A/oB/wPzAf8D1gH/A6MB/wOJAf8DrgH/A9QB/wPnAf8D+mn/AekB9QH8\n        Af8BzAHoAfgB/wHGAeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHG\n        AeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3\n        Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHG\n        AeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3\n        Af8BxgHmAfcB/wHGAeYB9wH/AcYB5gH3Af8BxgHmAfcB/wHIAecB+AH/AdEB6gH5Af8B3QHvAfoB/wHw\n        AfgB/TH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8ByQFiAR8B/wH6AfIB7QH/Ae0BzQG3Af8BzwF0ATkB/wHPAXQBOAH/Ac8BcwE3Af8BzwFzATcB/wHP\n        AXIBNgH/Ac8BcgE1Af8BzgFxATQB/wHOAXEBNAH/Ac4BcAEzAf8BzgFwATMB/wHOAW8BMgH/Ac4BbwEx\n        Af8BzQFuATAB/wHNAW4BMAH/Ac0BbQEvAf8BzQFtAS4B/wHNAWwBLQH/AcwBbAEtAf8BzAFrASwB/wHM\n        AWsBLAH/AcwBagErAf8BzAFqASoB/wHMAWoBKQH/AcsBaQEpAf8BygFmASQB/wHFAVYBDgH/AeIBrgGL\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/AfsB9gHyAf8B0AF2ATwB/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEAPP8D4AH/A8AB/wOvAf8DogH/\n        A68B/wPbVf8D+gH/A/MB/wPWAf8DowH/A4kB/wOuAf8D1AH/A+cB/wP6af8B3QHwAfoB/wGwAdwB9AH/\n        AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHY\n        AfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/\n        AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHY\n        AfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/\n        AaYB2AHzAf8BpgHYAfMB/wGmAdgB8wH/AakB2QHzAf8BtwHfAfUB/wHJAecB9wH/AekB9QH8Mf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHJAWIBHwH/\n        AfoB8gHsAf8B6QHBAaYB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B4gGuAYoB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B+wH3AfMB/wHRAXcBPQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQA8/wPgAf8DwAH/A68B/wOiAf8DrwH/A9tV/wP6\n        Af8D8wH/A9YB/wOjAf8DiQH/A64B/wPUAf8D5wH/A/pp/wHQAeoB+AH/AZMBzwHwAf8BhgHJAe4B/wGG\n        AckB7gH/AYYByQHuAf8BhgHJAe4B/wGGAckB7gH/AYYByQHuAf8BhgHJAe4B/wGGAckB7gH/AYYByQHu\n        Af8BhgHJAe4B/wGGAckB7gH/AYYByQHuAf8BhgHJAe4B/wGGAckB7gH/AYYByQHuAf8BhgHJAe4B/wGG\n        AckB7gH/AYYByQHuAf8BhgHJAe4B/wGGAckB7gH/AYYByQHuAf8BhgHJAe4B/wGGAckB7gH/AYYByQHu\n        Af8BhgHJAe4B/wGGAckB7gH/AYYByQHuAf8BhgHJAe4B/wGGAckB7gH/AYYByQHuAf8BhgHJAe4B/wGG\n        AckB7gH/AYYByQHuAf8BigHLAe8B/wGdAdMB8QH/AbUB3gH1Af8B4AHxAfox/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AckBYgEfAf8B+gHyAewB/wHp\n        AcIBpwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHiAa0BiQH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH7AfcB8wH/AdEBdwE+Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D21X/A/oB/wPzAf8D1gH/\n        A6MB/wOJAf8DrgH/A9QB/wPnAf8D+mn/Ac4B6QH4Af8BjgHNAe8B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGEAckB7gH/AZcB0QHxAf8BsQHdAfQB/wHfAfEB+jH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8ByQFiAR4B/wH6AfIB7AH/AekBwgGnAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AeIBrQGJAf8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/AfsB9wHzAf8B0QF4AUAB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf//AAEAPP8D4AH/A8AB/wOvAf8DogH/A68B/wPbVf8D+gH/A/MB/wPWAf8DowH/A4kB/wOu\n        Af8D1AH/A+cB/wP6af8BzgHpAfgB/wGOAc0B7wH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYQByQHu\n        Af8BlwHRAfEB/wGxAd0B9AH/Ad8B8QH6Mf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHJAWIBHgH/AfoB8QHsAf8B6QHDAagB/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8B4gGsAYgB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B+wH3AfMB/wHRAXkBQAH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQA8/wPgAf8DwAH/A68B/wOiAf8DrwH/A9tV/wP6Af8D8wH/A9YB/wOjAf8DiQH/A64B/wPUAf8D5wH/\n        A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/\n        AbEB3QH0Af8B3wHxAfox/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AckBYgEeAf8B+gHxAewB/wHqAcMBqQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHiAawBhwH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH7AfcB8wH/\n        AdIBegFCAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPA\n        Af8DrwH/A6IB/wOvAf8D21X/A/oB/wPzAf8D1gH/A6MB/wOJAf8DrgH/A9QB/wPnAf8D+mn/Ac4B6QH4\n        Af8BjgHNAe8B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGEAckB7gH/AZcB0QHxAf8BsQHdAfQB/wHf\n        AfEB+jH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8ByQFiAR4B/wH6AfEB7AH/AeoBxAGpAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AeIBrAGH\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/AfsB9wHzAf8B0gF6AUMB/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEAPP8D4AH/A8AB/wOvAf8DogH/\n        A68B/wPbVf8D+gH/A/MB/wPWAf8DowH/A4kB/wOuAf8D1AH/A+cB/wP6af8BzgHpAfgB/wGOAc0B7wH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYQByQHuAf8BlwHRAfEB/wGxAd0B9AH/Ad8B8QH6Mf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHJAWIBHgH/\n        AfoB8QHsAf8B6gHEAaoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B4gGsAYcB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH4AesB4gH/AeABqAGCAf8B3gGjAXUB/wHeAaIBdAH/\n        Ad4BoQFzAf8B3QGhAXMB/wHdAaABcQH/Ad0BnwFxAf8B3AGcAWwB/wHKAWYBJAH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQA8/wPgAf8DwAH/A68B/wOiAf8DrwH/A9tV/wP6\n        Af8D8wH/A9YB/wOjAf8DiQH/A64B/wPUAf8D5wH/A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0Af8B3wHxAfox/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AckBYgEeAf8B+gHxAewB/wHq\n        AcUBqwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHhAasBhgH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/AfIB3QHNAf8ByAFeARkB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D21X/A/oB/wPzAf8D1gH/\n        A6MB/wOJAf8DrgH/A9QB/wPnAf8D+mn/Ac4B6QH4Af8BjgHNAe8B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGEAckB7gH/AZcB0QHxAf8BsQHdAfQB/wHfAfEB+jH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8ByQFiAR4B/wH6AfEB6wH/AeoBxQGsAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AeEBqwGGAf8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B8wHdAc4B/wHIAV8BGgH/AdcBjwFYAf8B8gHcAc0B/wHzAd4B0AH/AfMB3gHQAf8B8wHe\n        AdEB/wHxAdgBxwH/AeEBqgGFAf8ByQFiAR4B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf//AAEAPP8D4AH/A8AB/wOvAf8DogH/A68B/wPbVf8D+gH/A/MB/wPWAf8DowH/A4kB/wOu\n        Af8D1AH/A+cB/wP6af8BzgHpAfgB/wGOAc0B7wH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYQByQHu\n        Af8BlwHRAfEB/wGxAd0B9AH/Ad8B8QH6Mf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHJAWIBHgH/AfoB8QHrAf8B6gHGAawB/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8B4QGqAYUB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wHz\n        Ad4BzwH/AcgBXwEbAf8B2wGaAWkB/wH9AfoB+AH/Af4B/QH8Af8B/gH9AfwB/wH8AfcB9AH/AesByAGv\n        Af8B0AF1ATsB/wHFAVYBDgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQA8/wPgAf8DwAH/A68B/wOiAf8DrwH/A9tV/wP6Af8D8wH/A9YB/wOjAf8DiQH/A64B/wPUAf8D5wH/\n        A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/\n        AbEB3QH0Af8B3wHxAfox/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AckBYQEdAf8B+gHxAesB/wHrAcYBrQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHhAaoBhAH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/AfMB3gHQAf8ByAFg\n        ARwB/wHbAZkBZwH/Af0B+gH4Af8B/gH9AfwB/wH9AfoB9wH/AewBywG0Af8B0AF2ATsB/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPA\n        Af8DrwH/A6IB/wOvAf8D21X/A/oB/wPzAf8D1gH/A6MB/wOJAf8DrgH/A9QB/wPnAf8D+mn/Ac4B6QH4\n        Af8BjgHNAe8B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGEAckB7gH/AZcB0QHxAf8BsQHdAfQB/wHf\n        AfEB+jH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8ByQFhAR0B/wH6AfEB6wH/AesBxwGtAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AeEBqQGD\n        Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B8wHfAdAB/wHIAWABHAH/AdoBmQFm\n        Af8B/QH6AfgB/wH8AfcB9AH/AesByQGyAf8BzwFzATgB/wHFAVgBEAH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEAPP8D4AH/A8AB/wOvAf8DogH/\n        A68B/wPbVf8D+gH/A/MB/wPWAf8DowH/A4kB/wOuAf8D1AH/A+cB/wP6af8BzgHpAfgB/wGOAc0B7wH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYQByQHuAf8BlwHRAfEB/wGxAd0B9AH/Ad8B8QH6Mf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHJAWEBHQH/\n        AfoB8QHrAf8B6wHHAa4B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B4QGpAYMB/wH+Af0B/AH/\n        Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9\n        AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wHzAd8B0QH/AckBYQEdAf8B2gGYAWUB/wH7AfUB8AH/\n        AesBxwGvAf8B0AF3AT0B/wHFAVcBDwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQA8/wPgAf8DwAH/A68B/wOiAf8DrwH/A9tV/wP6\n        Af8D8wH/A9YB/wOjAf8DiQH/A64B/wPUAf8D5wH/A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0Af8B3wHxAfox/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AckBYQEdAf8B+gHwAesB/wHr\n        AcgBrwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHgAagBggH/Af4B/QH8Af8B/gH9AfwB/wH+\n        Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8Af8B/gH9AfwB/wH+Af0B/AH/Af4B/QH8\n        Af8B/gH9AfwB/wH+Af0B/AH/AfMB3wHSAf8ByQFhAR4B/wHZAZUBYQH/AesByAGvAf8B0QF4AT8B/wHO\n        AW8BMQH/AcUBVwEQAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D21X/A/oB/wPzAf8D1gH/\n        A6MB/wOJAf8DrgH/A9QB/wPnAf8D+mn/Ac4B6QH4Af8BjgHNAe8B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGEAckB7gH/AZcB0QHxAf8BsQHdAfQB/wHfAfEB+jH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8ByQFhAR0B/wH5AfAB6gH/AesByAGwAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AdsBmQFnAf8B8gHdAc4B/wHyAdwBzQH/AfIB3AHMAf8B8gHb\n        AcsB/wHxAdoBygH/AfEB2gHJAf8B8QHZAcgB/wHxAdgBxwH/AfAB2AHGAf8B8AHXAcUB/wHwAdYBxAH/\n        AfAB1gHDAf8B6AG/AaMB/wHIAV8BGgH/Ac0BbgEvAf8BzwFyATcB/wHVAYgBTgH/Ae8B0gG/Af8ByAFg\n        ARsB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf//AAEAPP8D4AH/A8AB/wOvAf8DogH/A68B/wPbVf8D+gH/A/MB/wPWAf8DowH/A4kB/wOu\n        Af8D1AH/A+cB/wP6af8BzgHpAfgB/wGOAc0B7wH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYQByQHu\n        Af8BlwHRAfEB/wGxAd0B9AH/Ad8B8QH6Mf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHJAWEBHQH/AfkB8AHqAf8B6wHJAbAB/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxgFbARQB/wHIAWABHAH/AcgBYAEbAf8ByAFgARsB/wHIAV8BGwH/AcgBXwEa\n        Af8ByAFfARoB/wHIAV4BGQH/AcgBXgEZAf8BxwFeARgB/wHHAV4BGAH/AccBXQEYAf8BxwFdARcB/wHH\n        AVsBFQH/AcUBVgENAf8BxQFXAQ4B/wHFAVcBDgH/AegBvgGhAf8B+QHvAegB/wHJAWEBHQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQA8/wPgAf8DwAH/A68B/wOiAf8DrwH/A9tV/wP6Af8D8wH/A9YB/wOjAf8DiQH/A64B/wPUAf8D5wH/\n        A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/\n        AbEB3QH0Af8B3wHxAfox/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcgBYQEcAf8B+QHwAeoB/wHsAckBsQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8B6gHGAawB/wH6AfEB6wH/AckBYgEeAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPA\n        Af8DrwH/A6IB/wOvAf8D2zn/A/4B/wP9Af8D/QH/A/wB/wP8Af8D/AH/A/wB/wP3Af8D8QH/A9QB/wOi\n        Af8DiAH/A64B/wPUAf8D5wH/A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0Af8B3wHxAfox/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcgBYQEcAf8B+QHwAeoB/wHsAcoBsgH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B6gHFAawB/wH6AfEB6wH/AckBYgEe\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D2zn/A/oB/wP0Af8D7gH/A+sB/wPpAf8D6QH/\n        A+kB/wPlAf8D3wH/A8YB/wObAf8DhwH/A60B/wPUAf8D5wH/A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0Af8B3wHxAfox/wHFAVgBEAH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcgBYQEcAf8B+QHw\n        AeoB/wHsAcoBswH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B6gHF\n        AasB/wH6AfEB7AH/AckBYgEeAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D2zn/A/cB/wPq\n        Af8D4AH/A9sB/wPWAf8D1gH/A9YB/wPSAf8DzgH/A7gB/wOUAf8DhQH/A60B/wPUAf8D5wH/A/pp/wHO\n        AekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0\n        Af8B3wHxAfox/wHMAWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcgBYQEcAf8B+QHwAeoB/wHsAcsBswH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8B6gHEAaoB/wH6AfEB7AH/AckBYgEeAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/\n        A6IB/wOvAf8D2zn/A/AB/wPWAf8DwgH/A7kB/wOwAf8DsAH/A7EB/wOuAf8DqgH/A50B/wOKAf8DhgH/\n        A64B/wPVAf8D6AH/A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BhAHJ\n        Ae4B/wGXAdEB8QH/AbEB3QH0Af8B3wHxAfox/wHMAWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcgBYAEcAf8B+QHwAeoB/wHsAcsBtAH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B6gHEAakB/wH6AfEB7AH/AckBYgEeAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        /wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D2zn/A+cB/wPAAf8DogH/A5QB/wOGAf8DiAH/A4kB/wOH\n        Af8DgwH/A4AB/wN5Af8DiAH/A7AB/wPYAf8D6QH/A/pp/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0Af8B3wHxAfox/wHMAWoBKgH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcgBYAEcAf8B+QHwAeoB/wHs\n        AcsBtAH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B6gHEAakB/wH6\n        AfEB7AH/AckBYgEeAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D2zn/A+QB/wO4Af8DmQH/\n        A5AB/wOIAf8DjQH/A5IB/wOKAf8DegH/A4EB/wOQAf8DowH/A8MB/wPiAf8D7wH/A/tp/wHOAekB+AH/\n        AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0Af8B3wHx\n        Afox/wHMAWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcgBYAEcAf8B+QHwAekB/wHtAcwBtQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8B6QHDAagB/wH6AfEB7AH/AckBYgEeAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOv\n        Af8D2zn/A+QB/wO4Af8DnAH/A58B/wOhAf8DqwH/A7UB/wOlAf8DjgH/A5QB/wOyAf8DzQH/A98B/wPx\n        Af8D9wH/A/1p/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGA\n        AccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHu\n        Af8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BhAHJAe4B/wGX\n        AdEB8QH/AbEB3QH0Af8B3wHxAfox/wHMAWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcgBYAEcAf8B+QHvAekB/wHtAcwBtgH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B6QHCAacB/wH6AfIB7AH/AckBYgEeAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/\n        A+AB/wPAAf8DrwH/A6IB/wOvAf8D2zn/A+QB/wO4Af8DngH/A6QB/wOrAf8DuQH/A8cB/wO4Af8DoQH/\n        A6oB/wPOAf8D6gH/A/MB/wP7Af8D/QH/A/5p/wHOAekB+AH/AY4BzQHvAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHH\n        Ae4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/AYABxwHuAf8BgAHHAe4B/wGAAccB7gH/\n        AYABxwHuAf8BhAHJAe4B/wGXAdEB8QH/AbEB3QH0Af8B3wHxAfox/wHMAWoBKgH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcgBYAEbAf8B+QHvAegB/wHtAc0BtwH/\n        AcUBVgEOAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8B6QHCAacB/wH6AfIB7AH/\n        AckBYgEfAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrwH/A6IB/wOvAf8D2zn/A+QB/wO4Af8DmwH/A5sB/wOb\n        Af8DqwH/A7sB/wO9Af8DvQH/A8kB/wPhAf8D8wH/A/gB/wP9Af8D/gH/A/5p/wHRAeoB+AH/AZUB0AHw\n        Af8BhwHKAe8B/wGHAcoB7wH/AYcBygHvAf8BhwHKAe8B/wGHAcoB7wH/AYcBygHvAf8BhwHKAe8B/wGH\n        AcoB7wH/AYcBygHvAf8BhwHKAe8B/wGHAcoB7wH/AYcBygHvAf8BhwHKAe8B/wGHAcoB7wH/AYcBygHv\n        Af8BhwHKAe8B/wGHAcoB7gH/AYYBygHuAf8BgwHIAe4B/wGAAccB7gH/AYMByAHuAf8BhQHJAe4B/wGG\n        AckB7gH/AYcBygHvAf8BhwHKAe8B/wGHAcoB7wH/AYcBygHvAf8BhwHKAe8B/wGHAcoB7wH/AYcBygHv\n        Af8BhwHKAe8B/wGHAcoB7gH/AYUByQHuAf8BhwHKAe8B/wGZAdIB8QH/AbEB3QH0Af8B3wHxAfox/wHM\n        AWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcgBXgEZ\n        Af8B8wHdAc4B/wHxAdkByAH/AdEBeAE+Af8BxgFaARQB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8B6QHBAaYB/wH6AfIB7AH/AckBYgEfAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+AB/wPAAf8DrgH/A6EB/wOtAf8D2AH/\n        A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D+wH/A/sB/wP7Af8D4QH/\n        A7YB/wOYAf8DkgH/A40B/wOgAf8DswH/A8QB/wPWAf8D5QH/A/IB/wP7Af8D/XX/AeIB8gH7Af8BvQHh\n        AfYB/wG1Ad4B9QH/AbUB3gH1Af8BtQHeAfUB/wG1Ad4B9QH/AbUB3gH1Af8BtQHeAfUB/wG1Ad4B9QH/\n        AbUB3gH1Af8BtQHeAfUB/wG1Ad4B9QH/AbUB3gH1Af8BtQHeAfUB/wG1Ad4B9QH/AbUB3gH1Af8BtQHe\n        AfUB/wG1Ad4B9QH/AbIB3QH0Af8BrwHbAfQB/wGZAdIB8QH/AYYByQHuAf8BlgHQAfAB/wGlAdcB8gH/\n        Aa0B2wH0Af8BtQHeAfUB/wG1Ad4B9QH/AbUB3gH1Af8BtQHeAfUB/wG1Ad4B9QH/AbUB3gH1Af8BtQHe\n        AfUB/wG1Ad4B9QH/AbIB3QH0Af8BpAHXAfIB/wGbAdMB8QH/AaEB1gHyAf8BsQHdAfQB/wHfAfEB+jH/\n        AcwBagEqAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxgFb\n        ARMB/wHfAaYBegH/AfcB6QHfAf8B7gHRAb0B/wHeAaQBdgH/AdsBmwFqAf8B2wGbAWoB/wHbAZwBbAH/\n        AdwBnQFsAf8B3AGeAW4B/wHcAZ4BbgH/AdwBnwFwAf8B3QGfAXAB/wHdAaABcgH/Ad0BoQFzAf8B3QGi\n        AXQB/wHeAaIBdAH/Ad4BowF1Af8B3gGjAXYB/wHeAaQBdwH/Ad8BpQF4Af8B3wGlAXkB/wHfAaYBegH/\n        Ad8BpwGAAf8B4AGoAYEB/wHgAagBggH/AeABqQGDAf8B4AGpAYQB/wHgAaoBhQH/AeEBqwGGAf8B4QGs\n        AYcB/wHhAawBiAH/AeEBrQGJAf8B4gGtAYoB/wHiAa4BiwH/AeIBrwGLAf8B4gGwAY0B/wHjAbABjQH/\n        AeMBsQGPAf8B4wGyAY8B/wHjAbIBkQH/AeQBswGRAf8B5AG0AZMB/wHkAbQBkwH/AeQBtQGVAf8B5QG2\n        AZUB/wH1AeQB2AH/AfoB8gHtAf8ByQFiAR8B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf//AAEAPP8D4AH/A8AB/wOrAf8DmgH/A58B/wPA\n        Af8D2wH/A9sB/wPbAf8D2wH/A9sB/wPbAf8D2wH/A9sB/wPbAf8D2wH/A9sB/wPbAf8D2wH/A9sB/wPH\n        Af8DpgH/A5EB/wORAf8DkwH/A6kB/wO/Af8D0wH/A+UB/wPxAf8D+AH/A/0B/wP+df8B8QH5Af0B/wHg\n        AfEB+wH/AdwB7wH6Af8B3AHvAfoB/wHcAe8B+gH/AdwB7wH6Af8B3AHvAfoB/wHcAe8B+gH/AdwB7wH6\n        Af8B3AHvAfoB/wHcAe8B+gH/AdwB7wH6Af8B3AHvAfoB/wHcAe8B+gH/AdwB7wH6Af8B3AHvAfoB/wHc\n        Ae8B+gH/AdwB7wH6Af8B2AHtAfoB/wHTAesB+QH/AbAB3AH0Af8BkAHOAe8B/wGoAdgB8wH/Ab4B4gH2\n        Af8BywHoAfgB/wHWAewB+QH/AdYB7AH5Af8B1gHsAfkB/wHWAewB+QH/AdYB7AH5Af8B1gHsAfkB/wHW\n        AewB+QH/AdYB7AH5Af8B0QHqAfkB/wG7AeEB9gH/AaoB2gHzAf8BpwHYAfMB/wGxAd0B9AH/Ad8B8QH6\n        Mf8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AckBYwEfAf8B4gGsAYgB/wH1AeUB2gH/Af0B+gH4qf8B+gHyAe0B/wHJAWMBHwH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQA8/wPgAf8DwAH/A6gB/wOSAf8DkQH/A6gB/wO7Af8DuwH/A7sB/wO7Af8DuwH/A7sB/wO7Af8DuwH/\n        A7sB/wO7Af8DuwH/A7sB/wO7Af8DuwH/A60B/wOWAf8DiQH/A5AB/wOZAf8DsgH/A8wB/wPgAf8D9AH/\n        A/0B/wP+Af8D/gH/A/51/wH5AfwB/gH/AfEB+QH9Af8B8AH4Af0B/wHwAfgB/QH/AfAB+AH9Af8B8AH4\n        Af0B/wHwAfgB/QH/AfAB+AH9Af8B8AH4Af0B/wHwAfgB/QH/AfAB+AH9Af8B8AH4Af0B/wHwAfgB/QH/\n        AfAB+AH9Af8B8AH4Af0B/wHwAfgB/QH/AfAB+AH9Af8B8AH4Af0B/wHsAfYB/AH/AegB9AH8Af8BygHn\n        AfcB/wGuAdsB8wH/AbcB3wH1Af8BvgHiAfYB/wHEAeUB9wH/AckB5wH4Af8ByQHnAfgB/wHJAecB+AH/\n        AckB5wH4Af8ByQHnAfgB/wHJAecB+AH/AckB5wH4Af8ByQHnAfgB/wHFAeUB9wH/AbIB3QH0Af8BpAHX\n        AfIB/wGlAdcB8gH/AbEB3QH0Af8B3wHxAfox/wHMAWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHIAWEBHAH/AdABdgE7Af8B0wGE\n        AUgB/wHTAYUBSgH/AdMBhQFKAf8B0wGEAUkB/wHTAYQBSQH/AdMBhAFIAf8B0wGEAUgB/wHTAYMBRwH/\n        AdMBgwFHAf8B0gGDAUcB/wHSAYIBRgH/AdIBggFGAf8B0gGCAUYB/wHSAYEBRQH/AdIBgQFFAf8B0gGB\n        AUQB/wHSAYEBRAH/AdIBgQFEAf8B5gG5AZsB/wH6AfMB7wH/AfsB9AHwAf8B5QG1AZQB/wHVAYgBTgH/\n        AdEBegFBAf8B0QF5AUAB/wHRAXkBQAH/AdEBeQFAAf8B0QF5AT8B/wHRAXgBPwH/AdABeAE/Af8B0AF4\n        AT4B/wHQAXcBPgH/AdABdwE9Af8B0AF3AT0B/wHQAXYBPAH/AdABdgE8Af8B0AF2ATsB/wHQAXYBOwH/\n        AdABdQE7Af8BzwF1AToB/wHPAXUBOgH/Ac8BdQE6Af8B7QHMAbUB/wH6AfIB7QH/AckBYwEfAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        /wABADz/A+MB/wPHAf8DsAH/A5oB/wOUAf8DogH/A60B/wOtAf8DrQH/A60B/wOtAf8DrQH/A60B/wOt\n        Af8DrQH/A60B/wOtAf8DrQH/A60B/wOtAf8DpQH/A5cB/wOSAf8DoAH/A64B/wPGAf8D3wH/A+0B/wP5\n        zf8B/AH9Af4B/wH5AfwB/gH/AeIB8gH6Af8BzAHoAfcB/wHFAeUB9wH/Ab8B4wH2Af8BvQHiAfYB/wG8\n        AeEB9gH/AbwB4QH2Af8BvAHhAfYB/wG8AeEB9gH/AbwB4QH2Af8BvAHhAfYB/wG8AeEB9gH/AbwB4QH2\n        Af8BuQHgAfYB/wGrAdoB8wH/AaEB1QHyAf8BpgHXAfIB/wG0Ad4B9QH/AeAB8QH6Mf8BzAFqASoB/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcsBaQEpAf8B4QGrAYYB/wH4\n        AewB5AH/AfUB5QHaAf8B3AGcAWsB/wHHAV4BGQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AegBwAGj\n        Af8B+gHyAe0B/wHJAWMBHwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQA8/wPnAf8D0AH/A7oB/wOkAf8DmgH/A50B/wOgAf8DoAH/\n        A6AB/wOgAf8DoAH/A6AB/wOgAf8DoAH/A6AB/wOgAf8DoAH/A6AB/wOgAf8DoAH/A54B/wOaAf8DngH/\n        A7IB/wPFAf8D3AH/A/MB/wP6Af8D/c3/Af0C/gH/AfwB/QH+Af8B8gH5Af0B/wHoAfUB+wH/AdMB7AH5\n        Af8BvwHjAfYB/wG2Ad8B9QH/Aa8B3AH0Af8BrwHcAfQB/wGvAdwB9AH/Aa8B3AH0Af8BrwHcAfQB/wGv\n        AdwB9AH/Aa8B3AH0Af8BrwHcAfQB/wGuAdsB9AH/AagB2AHzAf8BpgHXAfIB/wGvAdwB9AH/AcAB4wH2\n        Af8B5QHzAfsx/wHMAWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHHAV8BGQH/Ad0BoAFxAf8B+AHqAeEB/wH3AeoB4QH/AdwBngFtAf8ByAFhAR0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8B6AG/AaMB/wH6AfIB7QH/AckBYwEfAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A+8B/wPfAf8DzwH/\n        A8AB/wO3Af8DtwH/A7cB/wO3Af8DtwH/A7cB/wO3Af8DtwH/A7cB/wO3Af8DtwH/A7cB/wO3Af8DtwH/\n        A7cB/wO3Af8DtwH/A7cB/wO8Af8DzAH/A9sB/wPrAf8D/OH/Af0C/gH/AeIB8gH7Af8ByAHnAfcB/wG8\n        AeEB9gH/AbEB3QH0Af8BsQHdAfQB/wGxAd0B9AH/AbEB3QH0Af8BsQHdAfQB/wGxAd0B9AH/AbEB3QH0\n        Af8BsQHdAfQB/wGxAd0B9AH/AbEB3QH0Af8BtAHeAfUB/wHAAeMB9gH/AdAB6gH5Af8B6wH2Afwx/wHM\n        AWoBKgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AccBXgEaAf8B2QGVAWEB/wHzAd0BzgH/AfkB8QHqAf8B4gGvAYwB/wHLAWcBJgH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8B6AG/AaIB/wH6AfIB7QH/AckBYwEgAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH//wABADz/A/kB/wPyAf8D7AH/A+YB/wPjAf8D4wH/\n        A+MB/wPjAf8D4wH/A+MB/wPjAf8D4wH/A+MB/wPjAf8D4wH/A+MB/wPjAf8D4wH/A+MB/wPjAf8D4wH/\n        A+MB/wPlAf8D6wH/A/EB/wP3Af8D/eH/A/4B/wHzAfkB/QH/AegB9QH8Af8B4wHzAfsB/wHfAfEB+gH/\n        Ad8B8QH6Af8B3wHxAfoB/wHfAfEB+gH/Ad8B8QH6Af8B3wHxAfoB/wHfAfEB+gH/Ad8B8QH6Af8B3wHx\n        AfoB/wHfAfEB+gH/AeAB8QH6Af8B5QHzAfsB/wHrAfYB/AH/AfcB+wH9Mf8BzAFqASoB/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcYBWwEUAf8B1wGPAVgB/wHyAdoBygH/AfgB7QHlAf8B5AG0AZIB/wHNAW4BMAH/AcUBWAEQAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFXAQ4B/wHJAWMBIAH/AesBxwGuAf8B+AHr\n        AeMB/wHJAWIBHgH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxgFaARMB/wHP\n        AXUBOgH/Ae8B0QG9Af8B+gHxAesB/wHrAcYBrQH/AdEBegFBAf8BygFlASMB/wHJAWMBIAH/AckBYwEg\n        Af8ByQFjASAB/wHJAWMBIAH/AckBYwEgAf8ByQFkASAB/wHKAWQBIQH/AcoBZAEhAf8BygFkASEB/wHK\n        AWQBIQH/AcoBZAEhAf8BzAFsAS0B/wHhAaoBhQH/AfYB6AHeAf8B7AHKAbMB/wHIAV4BGQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVcBDgH/Ac4BcAEyAf8B6QHA\n        AaUB/wH4AewB5AH/AfoB8gHtAf8B+gHzAe4B/wH6AfMB7gH/AfoB8wHuAf8B+gHzAe4B/wH6AfMB7gH/\n        AfoB8wHuAf8B+gHzAe4B/wH6AfMB7gH/AfsB8wHvAf8B+wHzAe8B/wH7AfMB7wH/AfsB9AHvAf8B+wH0\n        Ae4B/wH5AfAB6QH/AfAB1gHEAf8B1AGFAUoB/wHFAVgBDwH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVwEPAf8BywFoASgB/wHZAZUBYQH/AeUBtwGX\n        Af8B5wG9AaAB/wHnAb0BnwH/AecBvAGeAf8B5wG8AZ4B/wHnAbsBnQH/AecBuwGdAf8B5gG6AZwB/wHm\n        AboBmwH/AeYBuQGaAf8B5gG5AZoB/wHmAbgBmQH/AeYBuAGYAf8B5QG1AZQB/wHeAaQBdwH/AdABdgE8\n        Af8BxgFZARIB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B//8AAQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFq\n        ASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQD/////\n        Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8A\n        AQD/////Av8BzAFqASoB/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFW\n        AQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/\n        AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B//8AAQD/////Av8BzAFqASoB/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHF\n        AVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgENAf8BxQFWAQ0B/wHFAVYBDQH/AcUBVgEN\n        Af8BywFoAScB/wHMAWoBKgH/AcwBagEqAf8BzAFqASoB/wHMAWoBKgH/AcwBagEqAf8BzAFqASoB/wHM\n        AWoBKgH/AcwBagEqAf8BzAFqASoB/wHMAWoBKgH/AcwBagEqAf8BzAFqASoB/wHMAWoBKgH/AcwBagEq\n        Af8BzAFqASoB/wHMAWoBKgH/AcwBagEqAf8BzAFqASoB/wHMAWoBKgH/AcwBagEqAf8BzAFqASoB/wHM\n        AWoBKgH/AcwBagEqAf8BzAFqASoB//8AAQABQgFNAT4HAAE+AwABKAQAAQECAAFAAwABAQEAAQEGAAEI\n        FgAD//8A/wD/AP8A/wD/AP8A/wAJAAs=\n</value>\n  </data>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KeePass.exe.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n\t<startup>\n\t\t<supportedRuntime version=\"v4.5\" />\n\t\t<supportedRuntime version=\"v4.0\" />\n\t\t<supportedRuntime version=\"v2.0.50727\" />\n\t</startup>\n\t<runtime>\n\t\t<assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n\t\t\t<dependentAssembly>\n\t\t\t\t<assemblyIdentity name=\"KeePass\"\n\t\t\t\t\tpublicKeyToken=\"fed2ed7716aecf5c\"\n\t\t\t\t\tculture=\"neutral\" />\n\t\t\t\t<bindingRedirect oldVersion=\"2.0.9.0-2.30.0.0\"\n\t\t\t\t\tnewVersion=\"2.30.0.15916\" />\n\t\t\t</dependentAssembly>\n\t\t</assemblyBinding>\n\t\t<enforceFIPSPolicy enabled=\"false\" />\n\t\t<loadFromRemoteSources enabled=\"true\" />\n\t</runtime>\n\t<appSettings>\n\t\t<add key=\"EnableWindowsFormsHighDpiAutoResizing\" value=\"true\" />\n\t</appSettings>\n</configuration>\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KeePassDatabase.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing KeePass.DataExchange;\nusing KeePassLib.Serialization;\nusing KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    /// <summary>\n    /// Methods that regard the KeePass database\n    /// </summary>\n    public static class KeePassDatabase\n    {\n        /// <summary>\n        /// Allows a KeePass database to be opened directly from a cloud service\n        /// </summary>\n        /// <param name=\"updateStatus\">Method to call to update the status</param> \n        public static async Task OpenDatabaseFromCloudService(Action<string> updateStatus)\n        {\n            // Ask which cloud service to connect to\n            var cloudStorageProviderForm = new OneDriveCloudTypeForm {ExplanationText = \"Choose the cloud service you wish to open the KeePass database from:\"};\n            cloudStorageProviderForm.ShowDialog();\n\n            if (cloudStorageProviderForm.DialogResult != DialogResult.OK) return;\n\n            // Create a new database configuration entry\n            var databaseConfig = new Configuration\n            {\n                CloudStorageType = cloudStorageProviderForm.ChosenCloudStorageType\n            };\n\n            // Verify the config object is ready to be used\n            if (!databaseConfig.CloudStorageType.HasValue)\n            {\n                UpdateStatus(\"Invalid cloud storage provider chosen\");\n                return;\n            }\n\n            string localKeePassDatabasePath = null;\n            switch (databaseConfig.CloudStorageType)\n            {\n                case CloudStorageType.MicrosoftGraph:\n                case CloudStorageType.OneDriveConsumer:\n                case CloudStorageType.MicrosoftGraphDeviceLogin:\n                    localKeePassDatabasePath = await Providers.OneDriveProvider.OpenFromOneDriveCloudProvider(databaseConfig, updateStatus);\n                    break;\n\n                case CloudStorageType.SharePoint:\n                    localKeePassDatabasePath = await Providers.SharePointProvider.OpenFromSharePoint(databaseConfig, updateStatus);\n                    break;\n            }\n            \n            if(localKeePassDatabasePath == null)\n            {\n                return;\n            }\n\n            // Register the KeePass database sync information\n            UpdateStatus(\"Configuring KeePass database\");\n            databaseConfig.LocalFileHash = Utilities.GetDatabaseFileHash(localKeePassDatabasePath);\n            databaseConfig.LastSyncedAt = DateTime.Now;\n            databaseConfig.LastCheckedAt = DateTime.Now;\n\n            // Add the new configuration to the database configuration set in memory\n            Configuration.SetPasswordDatabaseConfiguration(localKeePassDatabasePath, databaseConfig);\n\n            // Save the database configuration set to persistent storage\n            Configuration.Save();\n\n            UpdateStatus(\"Opening KeePass database\");\n\n            // Open the KeePass database\n            var databaseFile = IOConnectionInfo.FromPath(localKeePassDatabasePath);\n            KoenZomersKeePassOneDriveSyncExt.Host.MainWindow.OpenDatabase(databaseFile, null, false);\n\n            UpdateStatus(\"KeePass database is ready to be used\");\n        }\n\n        /// <summary>\n        /// Checks if a newer database exists on OneDrive compared to the locally opened version and syncs them if so\n        /// </summary>\n        /// <param name=\"localKeePassDatabasePath\">Full path or relative path from the KeePass executable folder to where the KeePass database resides locally</param>\n        /// <param name=\"updateStatus\">Method to call to update the status</param>\n        /// <param name=\"forceSync\">If True, no attempts will be made to validate if the local copy differs from the remote copy and it will always sync. If False, it will try to validate if there are any changes and not sync if there are no changes.</param>\n        public static async Task SyncDatabase(string localKeePassDatabasePath, Action<string> updateStatus, bool forceSync, Configuration databaseConfig)\n        {\n            try\n            {\n                // Retrieve the KeePassOneDriveSync settings\n                if (databaseConfig == null)\n                {\n                    databaseConfig = Configuration.GetPasswordDatabaseConfiguration(localKeePassDatabasePath);\n                }\n\n                // If this database is already syncing, abort this attempt. This happens when the Import saves the resulting KeePass database. That by itself triggers another sync which doesn't have to go through the sync process as it just regards the temp database.\n                if (databaseConfig.IsCurrentlySyncing)\n                {\n                    UpdateStatus(string.Format(\"A synchronization is already in progress for database {0}\", databaseConfig.KeePassDatabase.Name));\n                    return;\n                }                \n\n                // Check if this database explicitly does not allow to be synced with OneDrive and if syncing is enabled on this database\n                if (databaseConfig.DoNotSync || !databaseConfig.SyncingEnabled)\n                {\n                    return;\n                }\n\n                UpdateStatus(string.Format(\"Starting database synchronization for database {0}\", databaseConfig.KeePassDatabase.Name));\n                databaseConfig.IsCurrentlySyncing = true;\n\n                // Check if the current database is synced with OneDrive\n                if (string.IsNullOrEmpty(databaseConfig.RemoteDatabasePath) && string.IsNullOrEmpty(databaseConfig.RemoteFolderId) && string.IsNullOrEmpty(databaseConfig.RemoteFileName))\n                {\n                    var cloudStorageType = AskIfShouldBeSynced(databaseConfig);\n                    \n                    if(!cloudStorageType.HasValue)\n                    {\n                        // No decission has been taken whether to sync the database or not\n                        // Set flag to indicate that the database is currently not syncing\n                        databaseConfig.IsCurrentlySyncing = false;\n\n                        UpdateStatus(string.Format(\"Canceled database synchronization for database {0}\", databaseConfig.KeePassDatabase.Name));\n\n                        return;\n                    }\n                    if (cloudStorageType.Value == CloudStorageType.None)\n                    {\n                        // Database should not be synchronized\n                        // Set flag to indicate that the database is currently not syncing\n                        databaseConfig.IsCurrentlySyncing = false;\n\n                        UpdateStatus(string.Format(\"Database {0} will not be synchronized\", databaseConfig.KeePassDatabase.Name));\n\n                        return;\n                    }\n\n                    databaseConfig.CloudStorageType = cloudStorageType.Value;\n                    Configuration.Save();\n                }\n\n                // Start the sync operation using one of the Cloud Storage Providers\n                bool syncSuccessful = false;\n\n                switch(databaseConfig.CloudStorageType)\n                {\n                    case CloudStorageType.MicrosoftGraph:\n                    case CloudStorageType.MicrosoftGraphDeviceLogin:\n                    case CloudStorageType.OneDriveConsumer:\n                        syncSuccessful = await Providers.OneDriveProvider.SyncUsingOneDriveCloudProvider(databaseConfig, localKeePassDatabasePath, forceSync, updateStatus);\n                        break;\n\n                    case CloudStorageType.SharePoint:\n                        syncSuccessful = await Providers.SharePointProvider.SyncUsingSharePointPlatform(databaseConfig, localKeePassDatabasePath, forceSync, updateStatus);\n                        break;\n                }\n\n                if(!syncSuccessful)\n                {\n                    // Set flag to allow exiting KeePass\n                    databaseConfig.IsCurrentlySyncing = false;\n                    return;\n                }\n\n                // Update the KeePass UI so it shows the new entries\n                KoenZomersKeePassOneDriveSyncExt.Host.MainWindow.UpdateUI(false, null, true, null, true, null, false);\n\n                updateStatus(string.Format(\"KeePass database {0} has successfully been synchronized and uploaded\", databaseConfig.KeePassDatabase.Name));\n\n                databaseConfig.LocalFileHash = Utilities.GetDatabaseFileHash(localKeePassDatabasePath);\n                //databaseConfig.ETag = uploadResult.ETag;\n                databaseConfig.LastSyncedAt = DateTime.Now;\n                databaseConfig.LastCheckedAt = DateTime.Now;\n                Configuration.Save();\n            }\n            catch(Exception e)\n            {\n                updateStatus(string.Format(\"Failed to sync database {0}: {1}\", databaseConfig.KeePassDatabase.Name, e.Message));\n            }\n\n            // Set flag to allow exiting KeePass\n            databaseConfig.IsCurrentlySyncing = false;\n        }\n\n        /// <summary>\n        /// Asks if the database should be synced and if yes with which storage provider\n        /// </summary>\n        /// <param name=\"databaseConfig\">Database to sync for</param>\n        /// <returns>Storage type to sync with or NULL if it should not be synced</returns>\n        private static CloudStorageType? AskIfShouldBeSynced(Configuration databaseConfig)\n        {\n            // Current database is not being syned with OneDrive, ask if it should be synced\n            var oneDriveAskToStartSyncingForm = new OneDriveAskToStartSyncingDialog(databaseConfig);\n            if (oneDriveAskToStartSyncingForm.ShowDialog() != DialogResult.OK)\n            {\n                // Dialog has been canceled. Return NULL to indicate no choice has been made.\n                return null;\n            }\n\n            if(databaseConfig.DoNotSync)\n            {\n                // Don't sync and don't ask again has been chosen\n                return CloudStorageType.None;\n            }\n\n            // Ask which cloud service to connect to\n            var oneDriveCloudTypeForm = new OneDriveCloudTypeForm { ExplanationText = string.Format(\"Choose the cloud service you wish to store the KeePass database {0} on:\", databaseConfig.KeePassDatabase.Name) };\n            if (oneDriveCloudTypeForm.ShowDialog() != DialogResult.OK)\n            {\n                // Dialog has been canceled. Return NULL to indicate no choice has been made.\n                return null;\n            }\n\n            return oneDriveCloudTypeForm.ChosenCloudStorageType;\n        }\n\n        /// <summary>\n        /// Merges the KeePass database at the provided path with the current database\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration of the database to merge the KeePass database with</param>\n        /// <param name=\"tempDatabasePath\">Path to the KeePass database to merge with the currently open database</param>\n        /// <returns>True if successful, false if failed to merge</returns>\n        public static bool MergeDatabases(Configuration databaseConfig, string tempDatabasePath)\n        {\n            var connectionInfo = IOConnectionInfo.FromPath(tempDatabasePath);\n            var formatter = KoenZomersKeePassOneDriveSyncExt.Host.FileFormatPool.Find(\"KeePass KDBX (2.x)\");\n\n            // Temporarily switch off syncing for this database to avoid the import operation, which causes a save, to create and endless loop\n            databaseConfig.SyncingEnabled = false;\n\n            // Import the current database with the downloaded database. Import causes a one way sync, syncing would try to update both ends which won't work for OneDrive.\n            var importSuccessful = ImportUtil.Import(databaseConfig.KeePassDatabase, formatter, new[] { connectionInfo }, true, KoenZomersKeePassOneDriveSyncExt.Host.MainWindow, false, KoenZomersKeePassOneDriveSyncExt.Host.MainWindow);\n\n            // Enable syncing of this database again\n            databaseConfig.SyncingEnabled = true;\n\n            // Remove the temporary database from the Most Recently Used (MRU) list in KeePass as its added automatically on the import action\n            KoenZomersKeePassOneDriveSyncExt.Host.MainWindow.FileMruList.RemoveItem(tempDatabasePath);\n\n            return importSuccessful.GetValueOrDefault(false);\n        }\n\n        /// <summary>\n        /// Displays a status message on the bottom bar\n        /// </summary>\n        /// <param name=\"message\">Message to show</param>\n        public static void UpdateStatus(string message)\n        {\n            KoenZomersKeePassOneDriveSyncExt.Host.MainWindow.SetStatusEx(message);\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KoenZomers.KeePass.OneDriveSync.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{ED981431-32EA-4FC8-BF5B-D5A29B3AD52E}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>KoenZomersKeePassOneDriveSync</RootNamespace>\n    <AssemblyName>KoenZomersKeePassOneDriveSync</AssemblyName>\n    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <TargetFrameworkProfile />\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>none</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n    <LangVersion>5</LangVersion>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"CredentialManagement, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL\">\n      <SpecificVersion>False</SpecificVersion>\n      <HintPath>.\\CredentialManagement.dll</HintPath>\n    </Reference>\n    <Reference Include=\"KeePass\">\n      <HintPath>..\\..\\..\\..\\Program Files\\KeePass Password Safe 2\\KeePass.exe</HintPath>\n    </Reference>\n    <Reference Include=\"KoenZomers.OneDrive.Api, Version=2.3.0.3, Culture=neutral, PublicKeyToken=c94340d84666bdcb, processorArchitecture=MSIL\">\n      <HintPath>Packages\\KoenZomers.OneDrive.Api.2.3.0.3\\lib\\net452\\KoenZomers.OneDrive.Api.dll</HintPath>\n    </Reference>\n    <Reference Include=\"Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>Packages\\Microsoft.IdentityModel.6.1.7600.16394\\lib\\net35\\Microsoft.IdentityModel.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Microsoft.IdentityModel.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=69c3241e6f0468ca, processorArchitecture=MSIL\">\n      <HintPath>Packages\\Microsoft.Identity.Model.Extensions.2.0.1459.0\\lib\\Microsoft.IdentityModel.Extensions.dll</HintPath>\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>Packages\\Newtonsoft.Json.8.0.1\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Configuration\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Drawing\" />\n    <Reference Include=\"System.IdentityModel\" />\n    <Reference Include=\"System.Net\" />\n    <Reference Include=\"System.Net.Http\">\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Net.Http.WebRequest\">\n      <Private>True</Private>\n    </Reference>\n    <Reference Include=\"System.Runtime.Serialization\" />\n    <Reference Include=\"System.Security\" />\n    <Reference Include=\"System.ServiceModel\" />\n    <Reference Include=\"System.Web\" />\n    <Reference Include=\"System.Web.Extensions\" />\n    <Reference Include=\"System.Windows.Forms\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Configuration.cs\" />\n    <Compile Include=\"Enums\\OneDriveRefreshTokenStorage.cs\" />\n    <Compile Include=\"Enums\\CloudStorageType.cs\" />\n    <Compile Include=\"Forms\\OneDriveGraphDeviceLoginForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveGraphDeviceLoginForm.Designer.cs\">\n      <DependentUpon>OneDriveGraphDeviceLoginForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveGraphDeviceLoginForm1.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DesignTime>True</DesignTime>\n      <DependentUpon>OneDriveGraphDeviceLoginForm.resx</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\SharePointDocumentLibraryPickerDialog.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\SharePointDocumentLibraryPickerDialog.Designer.cs\">\n      <DependentUpon>SharePointDocumentLibraryPickerDialog.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveFilePickerDialog.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveFilePickerDialog.Designer.cs\">\n      <DependentUpon>OneDriveFilePickerDialog.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveRequestInputDialog.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveRequestInputDialog.Designer.cs\">\n      <DependentUpon>OneDriveRequestInputDialog.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\SharePointCredentialsForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\SharePointCredentialsForm.Designer.cs\">\n      <DependentUpon>SharePointCredentialsForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"KeePassDatabase.cs\" />\n    <Compile Include=\"KoenZomersKeePassOneDriveSyncExt.cs\" />\n    <Compile Include=\"Forms\\OneDriveAboutForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveAboutForm.Designer.cs\">\n      <DependentUpon>OneDriveAboutForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveCloudTypeForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveCloudTypeForm.Designer.cs\">\n      <DependentUpon>OneDriveCloudTypeForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveRefreshTokenStorageDialog.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveRefreshTokenStorageDialog.Designer.cs\">\n      <DependentUpon>OneDriveRefreshTokenStorageDialog.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveAskToStartSyncingDialog.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveAskToStartSyncingDialog.Designer.cs\">\n      <DependentUpon>OneDriveAskToStartSyncingDialog.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveAuthenticateForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveAuthenticateForm.Designer.cs\">\n      <DependentUpon>OneDriveAuthenticateForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveConfigDetailsForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveConfigDetailsForm.Designer.cs\">\n      <DependentUpon>OneDriveConfigDetailsForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveConfigForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\OneDriveConfigForm.Designer.cs\">\n      <DependentUpon>OneDriveConfigForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Providers\\MicrosoftGraph\\MicrosoftGraphDeviceCodeAuthCheckSucceededResponse.cs\" />\n    <Compile Include=\"Providers\\MicrosoftGraph\\MicrosoftGraphDeviceCodeAuthCheckFailedResponse.cs\" />\n    <Compile Include=\"Providers\\MicrosoftGraph\\MicrosoftGraphDeviceCodeResponse.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Providers\\OneDriveProvider.cs\" />\n    <Compile Include=\"Providers\\SharePointProvider.cs\" />\n    <Compile Include=\"Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DesignTime>True</DesignTime>\n      <DependentUpon>Resources.resx</DependentUpon>\n    </Compile>\n    <Compile Include=\"TokenHelper.cs\" />\n    <Compile Include=\"Utilities.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <EmbeddedResource Include=\"Forms\\OneDriveAboutForm.resx\">\n      <DependentUpon>OneDriveAboutForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveGraphDeviceLoginForm.resx\">\n      <DependentUpon>OneDriveGraphDeviceLoginForm.cs</DependentUpon>\n      <Generator>PublicResXFileCodeGenerator</Generator>\n      <LastGenOutput>OneDriveGraphDeviceLoginForm1.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveCloudTypeForm.resx\">\n      <DependentUpon>OneDriveCloudTypeForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\SharePointDocumentLibraryPickerDialog.resx\">\n      <DependentUpon>SharePointDocumentLibraryPickerDialog.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveFilePickerDialog.resx\">\n      <DependentUpon>OneDriveFilePickerDialog.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveRequestInputDialog.resx\">\n      <DependentUpon>OneDriveRequestInputDialog.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveRefreshTokenStorageDialog.resx\">\n      <DependentUpon>OneDriveRefreshTokenStorageDialog.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveAskToStartSyncingDialog.resx\">\n      <DependentUpon>OneDriveAskToStartSyncingDialog.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveAuthenticateForm.resx\">\n      <DependentUpon>OneDriveAuthenticateForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveConfigDetailsForm.resx\">\n      <DependentUpon>OneDriveConfigDetailsForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\OneDriveConfigForm.resx\">\n      <DependentUpon>OneDriveConfigForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\SharePointCredentialsForm.resx\">\n      <DependentUpon>SharePointCredentialsForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"KeePass.exe.config\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Resources\\SharePoint.pdn\" />\n  </ItemGroup>\n  <ItemGroup />\n  <ItemGroup>\n    <Content Include=\"Images\\KeePassLive.png\" />\n    <Content Include=\"Images\\KeePassO365.png\" />\n    <Content Include=\"Images\\OneDriveConsumer.png\" />\n    <Content Include=\"Images\\OneDriveForBusiness.png\" />\n    <Content Include=\"Resources\\DocLib.png\" />\n    <Content Include=\"Resources\\File.png\" />\n    <Content Include=\"Resources\\Folder.png\" />\n    <Content Include=\"Resources\\OneDriveBothClouds.png\" />\n    <None Include=\"Resources\\mslogo.png\" />\n    <None Include=\"Resources\\SharePoint.png\" />\n    <None Include=\"Resources\\MSGraph.pdn\" />\n    <None Include=\"Resources\\OneDriveForBusiness.png\" />\n    <None Include=\"Resources\\OneDrive.png\" />\n    <None Include=\"Resources\\MSGraph.png\" />\n    <None Include=\"packages.config\" />\n    <None Include=\"Resources\\OneDriveIcon.png\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <PropertyGroup>\n    <PostBuildEvent>REM $(SolutionDir)create-plgx.cmd</PostBuildEvent>\n  </PropertyGroup>\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KoenZomersKeePassOneDriveSyncExt.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\nusing KeePass.Forms;\nusing KeePass.Plugins;\nusing KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    /// <summary>\n    /// Plugin for KeePass to allow synchronization with OneDrive\n    /// </summary>\n    /// <remarks>KeePass SDK documentation: http://keepass.info/help/v2_dev/plg_index.html</remarks>\n    public class KoenZomersKeePassOneDriveSyncExt : Plugin\n    {\n        #region Constants\n\n        /// <summary>\n        /// Client ID to use for communication with the OneDrive Consumer API\n        /// </summary>\n        internal const string OneDriveConsumerClientId = \"000000004813F265\";\n\n        /// <summary>\n        /// Client Secret to use for communication with the OneDrive Consumer API\n        /// </summary>\n        internal const string OneDriveConsumerClientSecret = \"GXpsZ6DX4AaNjRWFovMLIp1xS-FpbPgO\";\n\n        /// <summary>\n        /// Client ID to use for communication with the OneDrive for Business API\n        /// </summary>\n        internal const string OneDriveForBusinessClientId = \"c1b42b56-2aa9-4f01-ad76-11644ae1a859\";\n\n        /// <summary>\n        /// Client Secret to use for communication with the OneDrive for Business API\n        /// </summary>\n        internal const string OneDriveForBusinessClientSecret = \"ezb/qt5Iat0aE8S+ZWBtxhDtQLISEaPCkZ5agQv9MgM=\";\n\n        /// <summary>\n        /// Application ID to use for communication with the Microsoft Graph API\n        /// </summary>\n        internal const string GraphApiApplicationId = \"7bcec80a-2ffe-4713-b9ea-0150361c8209\";\n\n        #endregion\n\n        #region Properties\n\n        /// <summary>\n        /// Reference to the KeePass instance\n        /// </summary>\n        public static IPluginHost Host;\n\n        #endregion\n\n        #region Fields\n\n        /// <summary>\n        /// Separator line in the tools menu\n        /// </summary>\n        private ToolStripSeparator _toolsMenuSeparator;\n\n        /// <summary>\n        /// Config option item in the Tools menu\n        /// </summary>\n        private ToolStripMenuItem _toolsMenuConfigMenuItem;\n\n        /// <summary>\n        /// Open from OneDrive option in File > Open menu\n        /// </summary>\n        private ToolStripMenuItem _fileOpenMenuItem;\n\n        /// <summary>\n        /// Offline OneDrive option in File menu\n        /// </summary>\n        private ToolStripMenuItem _fileOfflineMenuItem;\n\n\n        #endregion\n\n        /// <summary>\n        /// Returns the URL where KeePass can check for updates of this plugin\n        /// </summary>\n        public override string UpdateUrl\n        {\n            get { return \"https://raw.githubusercontent.com/KoenZomers/KeePassOneDriveSync/master/version.txt\"; }\n        }\n\n        /// <summary>\n        /// Called when the Plugin is being loaded which happens on startup of KeePass\n        /// </summary>\n        /// <returns>True if the plugin loaded successfully, false if not</returns>\n        public override bool Initialize(IPluginHost pluginHost)\n        {\n            Host = pluginHost;\n\n            // Enable TLS 1.2\n            System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;\n\n            // Load the configuration\n            Configuration.Load();                       \n\n            // Bind to the events for loading and saving databases\n            Host.MainWindow.FileOpened += OnKeePassDatabaseOpened;\n            Host.MainWindow.FileSaved += MainWindowOnFileSaved;\n            Host.MainWindow.FileClosed += OnKeePassDatabaseClosed;\n            Host.MainWindow.FileClosingPost += OnKeePassDatabaseClosing;\n\n            // Add the menu option for configuration under Tools\n            var toolsmenu = Host.MainWindow.ToolsMenu.DropDownItems;\n\n            _toolsMenuSeparator = new ToolStripSeparator();\n            _toolsMenuConfigMenuItem = new ToolStripMenuItem(\"OneDriveSync Options\", Resources.OneDriveIcon);\n            _toolsMenuConfigMenuItem.Click += MenuOptionsOnClick;\n            toolsmenu.Add(_toolsMenuConfigMenuItem);\n\n            // Add the menu option for configuration under File > Open\n            var filemenu = Host.MainWindow.MainMenu.Items[\"m_menuFile\"] as ToolStripMenuItem;\n            if (filemenu != null)\n            {\n                var openmenu = filemenu.DropDownItems[\"m_menuFileOpen\"] as ToolStripMenuItem;\n                if (openmenu != null)\n                {\n                    _fileOpenMenuItem = new ToolStripMenuItem(\"Open from OneDrive...\", Resources.OneDriveIcon)\n                    {\n                        ShortcutKeys = Keys.Control | Keys.Alt | Keys.O\n                    };\n                    _fileOpenMenuItem.Click += MenuFileOpenFromOneDriveOnClick;\n                    openmenu.DropDownItems.Add(_fileOpenMenuItem);\n                }\n\n                // Add the menu option for Offline use under File\n                var fileLockIndex = filemenu.DropDownItems.IndexOfKey(\"m_menuFileLock\");\n                _fileOfflineMenuItem = new ToolStripMenuItem(\"OneDriveSync is Online\", Resources.OneDriveIcon)\n                {\n                    Checked = true\n                };\n                _fileOfflineMenuItem.Click += MenuFileOneDriveSyncOfflineOnClick;\n                filemenu.DropDownItems.Insert(fileLockIndex != -1 ? fileLockIndex : filemenu.DropDownItems.Count - 1, _toolsMenuSeparator);\n                filemenu.DropDownItems.Insert(fileLockIndex != -1 ? fileLockIndex : filemenu.DropDownItems.Count - 1, _fileOfflineMenuItem);\n            }\n\n            // Indicate that the plugin started successfully\n            return true;\n        }\n\n        /// <summary>\n        /// Triggered when the Plugin is being terminated\n        /// </summary>\n        public override void Terminate()\n        {\n            // Remove custom items from the menu as per recommendations on http://keepass.info/help/v2_dev/plg_index.html\n            var optionsmenu = Host.MainWindow.ToolsMenu.DropDownItems;\n\n            _toolsMenuConfigMenuItem.Click -= MenuOptionsOnClick;\n            optionsmenu.Remove(_toolsMenuSeparator);\n            optionsmenu.Remove(_toolsMenuConfigMenuItem);\n\n            var openmenu = Host.MainWindow.MainMenu.Items[\"m_menuFile\"] as ToolStripMenuItem;\n            if (openmenu != null)\n            {\n                _fileOpenMenuItem.Click -= MenuFileOpenFromOneDriveOnClick;\n                openmenu.DropDownItems.Remove(_fileOpenMenuItem);\n            }\n\n            _fileOfflineMenuItem.Click -= MenuFileOneDriveSyncOfflineOnClick;\n            openmenu.DropDownItems.Remove(_fileOfflineMenuItem);\n        }\n\n        /// <summary>\n        /// Triggered when a KeePass database is closing after the database has been saved\n        /// </summary>\n        private void OnKeePassDatabaseClosing(object sender, FileClosingEventArgs e)\n        {\n            // Check if there's still a process running that we need to wait for before allowing KeePass to terminate\n            if (Configuration.IsSomethingStillRunning)\n            {\n                Host.MainWindow.SetStatusEx(\"Waiting for OneDriveSync to complete...\");\n\n                // Record the time until we want to wait at most before exiting\n                var waitUntil = DateTime.Now.AddSeconds(30);\n\n                do\n                {\n                    System.Threading.Thread.Sleep(1);\n                    Application.DoEvents();\n                } while (Configuration.IsSomethingStillRunning && DateTime.Now < waitUntil);\n            }\n        }\n\n        /// <summary>\n        /// Triggered when a KeePass database is being saved\n        /// </summary>\n        private async void MainWindowOnFileSaved(object sender, FileSavedEventArgs fileSavedEventArgs)\n        {\n            var databasePath = fileSavedEventArgs.Database.IOConnectionInfo.Path;\n\n            var config = Configuration.GetPasswordDatabaseConfiguration(databasePath);\n            config.KeePassDatabase = fileSavedEventArgs.Database;\n\n            // Check if we should sync this database\n            if (config.DoNotSync) return;\n            if(!_fileOfflineMenuItem.Checked)\n            {\n                Host.MainWindow.SetStatusEx(string.Format(\"OneDriveSync has been set to offline, skipping sync for database {0}\", fileSavedEventArgs.Database.Name));\n                return;\n            }\n\n            // Make sure it's not a remote database on i.e. an FTP or website\n            if (!fileSavedEventArgs.Database.IOConnectionInfo.IsLocalFile())\n            {\n                MessageBox.Show(\"KeePass OneDriveSync does not support synchronizing databases from remote locations and will therefore not be available for this database\", \"KeePass OneDriveSync\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n\n                config.DoNotSync = true;\n                Configuration.Save();\n                return;\n            }\n\n            await KeePassDatabase.SyncDatabase(databasePath, KeePassDatabase.UpdateStatus, true, config);\n            \n            // If the OneDrive Refresh Token is stored in the KeePass database, we must trigger a save of the database here so to ensure that the actual value gets saved into the KDBX\n            if (config.RefreshTokenStorage == OneDriveRefreshTokenStorage.KeePassDatabase)\n            {\n                fileSavedEventArgs.Database.Save(null);\n            }\n        }\n\n        /// <summary>\n        /// Triggered when clicking on the OneDriveSync menu item under Tools\n        /// </summary>\n        private static void MenuOptionsOnClick(object sender, EventArgs e)\n        {\n            var oneDriveConfigForm = new OneDriveConfigForm();\n            oneDriveConfigForm.ShowDialog();\n        }\n\n        /// <summary>\n        /// Triggered when clicking on the Open from OneDrive menu item under File > Open\n        /// </summary>\n        private async static void MenuFileOpenFromOneDriveOnClick(object sender, EventArgs e)\n        {\n            await KeePassDatabase.OpenDatabaseFromCloudService(KeePassDatabase.UpdateStatus);\n        }\n\n        /// <summary>\n        /// Triggered when clicking on the OneDriveSync Offline Mode menu item under File\n        /// </summary>\n        private void MenuFileOneDriveSyncOfflineOnClick(object sender, EventArgs e)\n        {\n            _fileOfflineMenuItem.Checked = !_fileOfflineMenuItem.Checked;\n            _fileOfflineMenuItem.Text = _fileOfflineMenuItem.Checked ? _fileOfflineMenuItem.Text = \"OneDriveSync is Online\" : _fileOfflineMenuItem.Text = \"OneDriveSync is Offline\";\n        }\n\n        /// <summary>\n        /// Triggered when a KeePass database is being opened\n        /// </summary>\n        private async void OnKeePassDatabaseOpened(object sender, FileOpenedEventArgs fileOpenedEventArgs)\n        {\n            var databasePath = fileOpenedEventArgs.Database.IOConnectionInfo.Path;            \n\n            // Add the KeePass database instance to the already available configuration\n            var config = Configuration.GetPasswordDatabaseConfiguration(databasePath);\n            config.KeePassDatabase = fileOpenedEventArgs.Database;\n\n            // Check if we should sync this database\n            if (config.DoNotSync || !fileOpenedEventArgs.Database.IOConnectionInfo.IsLocalFile()) return;\n            if(!_fileOfflineMenuItem.Checked)\n            {\n                Host.MainWindow.SetStatusEx(string.Format(\"OneDriveSync has been set to offline, skipping sync for database {0}\", fileOpenedEventArgs.Database.Name));\n                return;\n            }\n\n            // Check if the database configuration of the opened KeePass database is set to retrieve the OneDrive Refresh Token from the KeePass database itself\n            if (config.RefreshTokenStorage == OneDriveRefreshTokenStorage.KeePassDatabase && string.IsNullOrEmpty(config.RefreshToken))\n            {\n                // Retrieve the OneDrive Refresh Token from the KeePass database that is being opened\n                config.RefreshToken = Utilities.GetRefreshTokenFromKeePassDatabase(fileOpenedEventArgs.Database);\n            }\n\n            await KeePassDatabase.SyncDatabase(databasePath, KeePassDatabase.UpdateStatus, false, config);\n\n            // If the OneDrive Refresh Token is stored in the KeePass database, we must trigger a save of the database here so to ensure that the actual value gets saved into the KDBX\n            if (config.RefreshTokenStorage == OneDriveRefreshTokenStorage.KeePassDatabase)\n            {\n                fileOpenedEventArgs.Database.Save(null);\n            } \n        }\n\n        /// <summary>\n        /// Triggered when a KeePass database has been closed\n        /// </summary>\n        private static void OnKeePassDatabaseClosed(object sender, FileClosedEventArgs fileClosedEventArgs)\n        {\n            // Remove the KeePass database instance from the already available configuration\n            var config = Configuration.GetPasswordDatabaseConfiguration(fileClosedEventArgs.IOConnectionInfo.Path);\n            config.KeePassDatabase = null;\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"KoenZomers.KeePass.OneDriveSync\")]\n[assembly: AssemblyDescription(\"Allows automatic synchronization of one or more KeePass databases to one or more OneDrives\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"Koen Zomers\")]\n[assembly: AssemblyProduct(\"KeePass Plugin\")]\n[assembly: AssemblyCopyright(\"Copyright © 2021\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"9cf31805-d88f-44da-89fc-0643eaa70bfc\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"2.1.2.3\")]\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeAuthCheckFailedResponse.cs",
    "content": "﻿using Newtonsoft.Json;\nusing System;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers.MicrosoftGraph\n{\n    /// <summary>\n    /// Response message from Microsoft Graph when failing verification on if the device session has authenticated\n    /// </summary>\n    public class MicrosoftGraphDeviceCodeAuthCheckFailedResponse\n    {\n        /// <summary>\n        /// Type of error\n        /// </summary>\n        [JsonProperty(\"error\", NullValueHandling = NullValueHandling.Ignore)]\n        public string Error { get; set; }\n\n        /// <summary>\n        /// Detailed description of what went wrong\n        /// </summary>\n        [JsonProperty(\"error_description\", NullValueHandling = NullValueHandling.Ignore)]\n        public string ErrorDescription { get; set; }\n\n        /// <summary>\n        /// Code(s) identifying the type of error\n        /// </summary>\n        [JsonProperty(\"error_codes\", NullValueHandling = NullValueHandling.Ignore)]\n        public long[] ErrorCodes { get; set; }\n\n        /// <summary>\n        /// Date and time when the error occurred\n        /// </summary>\n        [JsonProperty(\"timestamp\", NullValueHandling = NullValueHandling.Ignore)]\n        public DateTimeOffset? Timestamp { get; set; }\n\n        /// <summary>\n        /// Trace ID of the error\n        /// </summary>\n        [JsonProperty(\"trace_id\", NullValueHandling = NullValueHandling.Ignore)]\n        public Guid? TraceId { get; set; }\n\n        /// <summary>\n        /// Correlation ID of the error\n        /// </summary>\n        [JsonProperty(\"correlation_id\", NullValueHandling = NullValueHandling.Ignore)]\n        public Guid? CorrelationId { get; set; }\n\n        /// <summary>\n        /// Url with more information on the error\n        /// </summary>\n        [JsonProperty(\"error_uri\", NullValueHandling = NullValueHandling.Ignore)]\n        public Uri ErrorUri { get; set; }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeAuthCheckSucceededResponse.cs",
    "content": "﻿using Newtonsoft.Json;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers.MicrosoftGraph\n{\n    /// <summary>\n    /// Response message from Microsoft Graph when succeeding verification on if the device session has authenticated\n    /// </summary>\n    public class MicrosoftGraphDeviceCodeAuthCheckSucceededResponse\n    {\n        /// <summary>\n        /// Type of token received. Must be Bearer.\n        /// </summary>\n        [JsonProperty(\"token_type\", NullValueHandling = NullValueHandling.Ignore)]\n        public string TokenType { get; set; }\n\n        /// <summary>\n        /// Scopes that were granted\n        /// </summary>\n        [JsonProperty(\"scope\", NullValueHandling = NullValueHandling.Ignore)]\n        public string Scope { get; set; }\n\n        /// <summary>\n        /// Time in seconds when this token will expire\n        /// </summary>\n        [JsonProperty(\"expires_in\", NullValueHandling = NullValueHandling.Ignore)]\n        public long? ExpiresIn { get; set; }\n\n        /// <summary>\n        /// Time in seconds when this token will expire \n        /// </summary>\n        [JsonProperty(\"ext_expires_in\", NullValueHandling = NullValueHandling.Ignore)]\n        public long? ExtExpiresIn { get; set; }\n\n        /// <summary>\n        /// The access token\n        /// </summary>\n        [JsonProperty(\"access_token\", NullValueHandling = NullValueHandling.Ignore)]\n        public string AccessToken { get; set; }\n\n        /// <summary>\n        /// The refresh token\n        /// </summary>\n        [JsonProperty(\"refresh_token\", NullValueHandling = NullValueHandling.Ignore)]\n        public string RefreshToken { get; set; }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeResponse.cs",
    "content": "﻿using Newtonsoft.Json;\nusing System;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers.MicrosoftGraph\n{\n    /// <summary>\n    /// Response message from Microsoft Graph after requesting a device login\n    /// </summary>\n    public class MicrosoftGraphDeviceCodeResponse\n    {\n        /// <summary>\n        /// A short string shown to the user that's used to identify the session on a secondary device\n        /// </summary>\n        [JsonProperty(\"user_code\", NullValueHandling = NullValueHandling.Ignore)]\n        public string UserCode { get; set; }\n\n        /// <summary>\n        /// A long string used to verify the session between the client and the authorization server. The client uses this parameter to request the access token from the authorization server.\n        /// </summary>\n        [JsonProperty(\"device_code\", NullValueHandling = NullValueHandling.Ignore)]\n        public string DeviceCode { get; set; }\n\n        /// <summary>\n        /// The URI the user should go to with the user_code in order to sign in\n        /// </summary>\n        [JsonProperty(\"verification_uri\", NullValueHandling = NullValueHandling.Ignore)]\n        public Uri VerificationUri { get; set; }\n\n        /// <summary>\n        /// The number of seconds before the device_code and user_code expire\n        /// </summary>\n        [JsonProperty(\"expires_in\", NullValueHandling = NullValueHandling.Ignore)]\n        public int? ExpiresIn { get; set; }\n\n        /// <summary>\n        /// The number of seconds the client should wait between polling requests\n        /// </summary>\n        [JsonProperty(\"interval\", NullValueHandling = NullValueHandling.Ignore)]\n        public int? Interval { get; set; }\n\n        /// <summary>\n        /// A human-readable string with instructions for the user. This can be localized by including a query parameter in the request of the form ?mkt=xx-XX, filling in the appropriate language culture code.\n        /// </summary>\n        [JsonProperty(\"message\", NullValueHandling = NullValueHandling.Ignore)]\n        public string Message { get; set; }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/OneDriveProvider.cs",
    "content": "﻿using KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\nusing KoenZomers.OneDrive.Api;\nusing KoenZomers.OneDrive.Api.Entities;\nusing System;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers\n{\n    internal static class OneDriveProvider\n    {\n        /// <summary>\n        /// Uses a Microsoft OneDrive Cloud Storage Provider (OneDrive Consumer, OneDrive for Business, Microsoft Graph) to sync the KeePass database\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration of the database to sync</param>\n        /// <param name=\"localKeePassDatabasePath\">Path to where the KeePass database to sync resides</param>\n        /// <param name=\"forceSync\">Flag to indicate if the sync should always take place</param>\n        /// <param name=\"updateStatus\">Action to write status messages to to display in the UI</param>\n        /// <returns>True if successful, false if failed</returns>\n        public static async Task<bool> SyncUsingOneDriveCloudProvider(Configuration databaseConfig, string localKeePassDatabasePath, bool forceSync, Action<string> updateStatus)\n        {\n            // Connect to OneDrive\n            OneDriveApi oneDriveApi = null;\n            bool retryGettingApiInstance;\n            do\n            {\n                retryGettingApiInstance = false;\n                try\n                {\n                    oneDriveApi = await Utilities.GetOneDriveApi(databaseConfig);\n                }\n                catch (KoenZomers.OneDrive.Api.Exceptions.TokenRetrievalFailedException)\n                {\n                    // Failed to get a OneDrive API instance because retrieving an oAuth token failed. This could be because the oAuth token expired or has been removed. Show the login dialog again so we can get a new token.\n                    databaseConfig.RefreshToken = null;\n                    retryGettingApiInstance = true;\n                }\n                catch (Exception e)\n                {\n                    // Build the error text to show to the end user\n                    var errorMessage = new System.Text.StringBuilder();\n                    errorMessage.Append(\"Failed to connect to \");\n                    switch (databaseConfig.CloudStorageType.GetValueOrDefault(CloudStorageType.OneDriveConsumer))\n                    {\n                        case CloudStorageType.OneDriveConsumer:\n                            errorMessage.Append(\"OneDrive\");\n                            break;\n                        case CloudStorageType.MicrosoftGraph:\n                        case CloudStorageType.MicrosoftGraphDeviceLogin:\n                            errorMessage.Append(\"Microsoft Graph\");\n                            break;\n                        default:\n                            errorMessage.Append(\"cloud storage provider\");\n                            break;\n                    }\n                    errorMessage.AppendLine(string.Format(\" for database {0}:\", databaseConfig.KeePassDatabase.Name));\n                    errorMessage.AppendLine();\n\n                    // Revert to the most inner exception to get the best details on what went wrong\n                    while (e.InnerException != null) e = e.InnerException;\n\n                    errorMessage.AppendLine(e.Message);\n\n                    // Verify if we're offline\n                    if (e.Message.Contains(\"remote name could not be resolved\"))\n                    {\n                        // Offline, don't display a modal dialog but use the status bar instead\n                        KeePassDatabase.UpdateStatus(\"Can't connect. Working offline.\");\n                        return false;\n                    }\n\n                    MessageBox.Show(errorMessage.ToString(), \"Connection failed\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);\n                }\n            } while (retryGettingApiInstance);\n\n            if (oneDriveApi == null)\n            {\n                switch (databaseConfig.CloudStorageType.GetValueOrDefault(CloudStorageType.OneDriveConsumer))\n                {\n                    case CloudStorageType.OneDriveConsumer: updateStatus(string.Format(\"Failed to connect to OneDrive for database {0}\", databaseConfig.KeePassDatabase.Name)); break;\n                    case CloudStorageType.MicrosoftGraph:\n                    case CloudStorageType.MicrosoftGraphDeviceLogin:\n                        updateStatus(string.Format(\"Failed to connect to Microsoft Graph for database {0}\", databaseConfig.KeePassDatabase.Name));\n                        break;\n                    default: updateStatus(string.Format(\"Failed to connect to cloud service for database {0}\", databaseConfig.KeePassDatabase.Name)); break;\n                }\n\n                return false;\n            }\n\n            // Save the RefreshToken in the configuration so we can use it again next time\n            databaseConfig.RefreshToken = oneDriveApi.AccessToken.RefreshToken;\n\n            // Verify if we already have retrieved the name of this OneDrive\n            if (string.IsNullOrEmpty(databaseConfig.OneDriveName))\n            {\n                // Fetch details about this OneDrive account\n                var oneDriveAccount = await oneDriveApi.GetDrive();\n                databaseConfig.OneDriveName = oneDriveAccount.Owner.User.DisplayName;\n            }\n            Configuration.Save();\n\n            // Check if we have a location on OneDrive to sync with\n            if (string.IsNullOrEmpty(databaseConfig.RemoteDatabasePath) && string.IsNullOrEmpty(databaseConfig.RemoteFolderId) && string.IsNullOrEmpty(databaseConfig.RemoteFileName))\n            {\n                // Ask the user where to store the database on OneDrive\n                var oneDriveFilePickerDialog = new Forms.OneDriveFilePickerDialog(oneDriveApi)\n                {\n                    ExplanationText = \"Select where you want to store the KeePass database. Right click for additional options.\",\n                    AllowEnteringNewFileName = true,\n                    FileName = new System.IO.FileInfo(localKeePassDatabasePath).Name\n                };\n                await oneDriveFilePickerDialog.LoadFolderItems();\n                var result = oneDriveFilePickerDialog.ShowDialog();\n                if (result != DialogResult.OK || string.IsNullOrEmpty(oneDriveFilePickerDialog.FileName))\n                {\n                    return false;\n                }\n\n                databaseConfig.RemoteDatabasePath = (oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference.Path : \"\") + \"/\" + oneDriveFilePickerDialog.CurrentOneDriveItem.Name + \"/\" + oneDriveFilePickerDialog.FileName;\n                databaseConfig.RemoteDriveId = oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.ParentReference.DriveId : oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference.DriveId != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference.DriveId : null;\n                if (oneDriveFilePickerDialog.CurrentOneDriveItem.File != null || (oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem != null && oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.File != null))\n                {\n                    databaseConfig.RemoteItemId = oneDriveFilePickerDialog.CurrentOneDriveItem.File != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.Id : oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.Id;\n                }\n                else\n                {\n                    databaseConfig.RemoteFolderId = oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.ParentReference != null ? string.IsNullOrEmpty(oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.ParentReference.Id) || oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.Folder != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.Id : oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.ParentReference.Id : oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.Id : oneDriveFilePickerDialog.CurrentOneDriveItem.Id;\n                }\n                databaseConfig.RemoteFileName = oneDriveFilePickerDialog.FileName;\n                Configuration.Save();\n            }\n\n            // Retrieve the metadata of the KeePass database on OneDrive\n            OneDriveItem oneDriveItem;\n            if (string.IsNullOrEmpty(databaseConfig.RemoteItemId))\n            {\n                // We don't have the ID of the KeePass file, check if the database is stored on the current user its drive or on a shared drive\n                OneDriveItem folder;\n                if (string.IsNullOrEmpty(databaseConfig.RemoteDriveId))\n                {\n                    // KeePass database is on the current user its drive\n                    if (string.IsNullOrEmpty(databaseConfig.RemoteFolderId))\n                    {\n                        // No direct reference to the folder on the drive available, try locating it by its remote path\n                        oneDriveItem = await oneDriveApi.GetItem(databaseConfig.RemoteDatabasePath);\n                    }\n                    else\n                    {\n                        // Get the folder in which the KeePass file resides\n                        folder = await oneDriveApi.GetItemById(databaseConfig.RemoteFolderId);\n\n                        if (folder == null)\n                        {\n                            updateStatus(string.Format(\"Unable to download database {0} from OneDrive. Remote path cannot be found.\", databaseConfig.KeePassDatabase.Name));\n                            return false;\n                        }\n\n                        // Locate the KeePass file in the folder\n                        oneDriveItem = await oneDriveApi.GetItemInFolder(folder, databaseConfig.RemoteFileName);\n                    }\n                }\n                else\n                {\n                    // KeePass database is on a shared drive or has not been uploaded yet\n                    folder = await oneDriveApi.GetItemFromDriveById(databaseConfig.RemoteFolderId, databaseConfig.RemoteDriveId);\n\n                    // Locate the KeePass file in the folder. Will return NULL if the file has not been uploaded yet.\n                    oneDriveItem = await oneDriveApi.GetItemInFolder(folder, databaseConfig.RemoteFileName);\n                }\n\n                // Check if the KeePass file has been found\n                if (oneDriveItem != null)\n                {\n                    // Store the direct Id to the KeePass file so we can save several API calls on future syncs\n                    databaseConfig.RemoteItemId = oneDriveItem.Id;\n                    Configuration.Save();\n                }\n            }\n            else\n            {\n                // We have the ID of the KeePass file, check if it's on the current user its drive or on a shared drive\n                if (string.IsNullOrEmpty(databaseConfig.RemoteDriveId))\n                {\n                    // KeePass database is on the current user its drive\n                    oneDriveItem = await oneDriveApi.GetItemById(databaseConfig.RemoteItemId);\n                }\n                else\n                {\n                    // KeePass database is on a shared drive\n                    oneDriveItem = await oneDriveApi.GetItemFromDriveById(databaseConfig.RemoteItemId, databaseConfig.RemoteDriveId);\n                }\n            }\n            \n            if (oneDriveItem == null)\n            {\n                // KeePass database not found on OneDrive\n                updateStatus(string.Format(\"Database {0} does not exist yet on OneDrive, uploading it now\", databaseConfig.KeePassDatabase.Name));\n\n                OneDriveItem oneDriveFolder;\n                string fileName;\n                if (string.IsNullOrEmpty(databaseConfig.RemoteFolderId))\n                {\n                    oneDriveFolder = databaseConfig.RemoteDatabasePath.Contains(\"/\") ? await oneDriveApi.GetFolderOrCreate(databaseConfig.RemoteDatabasePath.Remove(databaseConfig.RemoteDatabasePath.LastIndexOf(\"/\", StringComparison.Ordinal))) : await oneDriveApi.GetDriveRoot();\n                    fileName = databaseConfig.RemoteDatabasePath.Contains(\"/\") ? databaseConfig.RemoteDatabasePath.Remove(0, databaseConfig.RemoteDatabasePath.LastIndexOf(\"/\", StringComparison.Ordinal) + 1) : databaseConfig.RemoteDatabasePath;\n                }\n                else\n                {\n                    oneDriveFolder = databaseConfig.RemoteDriveId == null ? await oneDriveApi.GetItemById(databaseConfig.RemoteFolderId) : await oneDriveApi.GetItemFromDriveById(databaseConfig.RemoteFolderId, databaseConfig.RemoteDriveId);\n                    fileName = databaseConfig.RemoteFileName;\n                }\n\n                if (oneDriveFolder == null)\n                {\n                    updateStatus(string.Format(\"Unable to upload database {0} to OneDrive. Remote path is invalid.\", databaseConfig.KeePassDatabase.Name));\n                    return false;\n                }\n\n                // Upload the database to OneDrive                \n                var newUploadResult = await oneDriveApi.UploadFileAs(localKeePassDatabasePath, fileName, oneDriveFolder);\n\n                updateStatus(string.Format(newUploadResult == null ? \"Failed to upload the KeePass database {0}\" : \"Successfully uploaded the new KeePass database {0} to OneDrive\", databaseConfig.KeePassDatabase.Name));\n\n                databaseConfig.LocalFileHash = Utilities.GetDatabaseFileHash(localKeePassDatabasePath);\n                if (newUploadResult != null)\n                {\n                    databaseConfig.RemoteItemId = newUploadResult.Id;\n                    databaseConfig.LastCheckedAt = DateTime.Now;\n                    databaseConfig.LastSyncedAt = DateTime.Now;\n                    databaseConfig.ETag = newUploadResult.ETag;\n                }\n                Configuration.Save();\n                return false;\n            }\n\n            // Use the ETag from the OneDrive item to compare it against the local database config etag to see if the content has changed\n            // Microsoft Graph API reports back a different ETag when uploading than the file actually gets assigned for some unknown reason. This would cause each sync attempt to sync again as the ETags differ. As a workaround we'll use the CTag which does seem reliable to detect a change to the file.\n            if (!forceSync && \n                oneDriveItem.CTag == databaseConfig.ETag)\n            {\n                updateStatus(string.Format(\"Database {0} is in sync\", databaseConfig.KeePassDatabase.Name));\n\n                databaseConfig.LastCheckedAt = DateTime.Now;\n                Configuration.Save();\n\n                return false;\n            }\n\n            // Download the database from OneDrive\n            updateStatus(string.Format(\"Downloading KeePass database {0} from OneDrive\", databaseConfig.KeePassDatabase.Name));\n\n            var temporaryKeePassDatabasePath = System.IO.Path.GetTempFileName();\n            var downloadSuccessful = await oneDriveApi.DownloadItemAndSaveAs(oneDriveItem, temporaryKeePassDatabasePath);\n\n            if (!downloadSuccessful)\n            {\n                updateStatus(string.Format(\"Failed to download the KeePass database {0} from OneDrive\", databaseConfig.KeePassDatabase.Name));\n\n                return false;\n            }\n\n            // Sync database\n            updateStatus(string.Format(\"KeePass database {0} downloaded, going to sync\", databaseConfig.KeePassDatabase.Name));\n\n            // Merge the downloaded database with the currently open KeePass database\n            var syncSuccessful = KeePassDatabase.MergeDatabases(databaseConfig, temporaryKeePassDatabasePath);\n\n            string localDatabaseToUpload;\n            if (!syncSuccessful)\n            {\n                updateStatus(string.Format(\"Failed to synchronize the KeePass database {0}\", databaseConfig.KeePassDatabase.Name));\n\n                var confirm = MessageBox.Show(\"Unable to merge the databases. Did you just change the master password for this KeePass database? If so and you would like to OVERWRITE the KeePass database stored on your OneDrive with your local database, select Yes, otherwise select No.\", \"Confirm overwriting your KeePass database\", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);\n                if (confirm != DialogResult.Yes) return false;\n\n                // Upload the local database\n                localDatabaseToUpload = databaseConfig.KeePassDatabase.IOConnectionInfo.Path;\n\n                updateStatus(string.Format(\"Uploading the local KeePass database {0} to OneDrive\", databaseConfig.KeePassDatabase.Name));\n            }\n            else\n            {\n                // Upload the synced database\n                localDatabaseToUpload = temporaryKeePassDatabasePath;\n\n                updateStatus(string.Format(\"Uploading the merged KeePass database {0} to OneDrive\", databaseConfig.KeePassDatabase.Name));\n            }\n\n            OneDriveItem uploadResult = null;\n\n            // Due to some issues with the OneDrive API throwing random errors for no reason, retry a few times to upload the database before it will be considered failed\n            for (var uploadAttempts = 1; uploadAttempts <= 5; uploadAttempts++)\n            {\n                try\n                {\n                    if (!string.IsNullOrEmpty(databaseConfig.RemoteItemId))\n                    {\n                        // Database is already present on OneDrive, update it\n                        uploadResult = await oneDriveApi.UpdateFile(localDatabaseToUpload, oneDriveItem);\n                    }\n                    else\n                    {\n                        // Database resides on the user its own OneDrive in the root folder\n                        if (oneDriveItem.ParentReference.Path.Equals(\"/drive/root:\", StringComparison.CurrentCultureIgnoreCase))\n                        {\n                            uploadResult = await oneDriveApi.UploadFileAs(localDatabaseToUpload, oneDriveItem.Name, await oneDriveApi.GetDriveRoot());\n                        }\n                        else\n                        {\n                            if (string.IsNullOrEmpty(databaseConfig.RemoteDriveId))\n                            {\n                                // Database resides on the user its own OneDrive in a folder\n                                uploadResult = await oneDriveApi.UploadFileAs(localDatabaseToUpload, oneDriveItem.Name, await oneDriveApi.GetItemById(oneDriveItem.ParentReference.Id));\n                            }\n                            else\n                            {\n                                // Database resides on another OneDrive\n                                uploadResult = await oneDriveApi.UploadFileAs(localDatabaseToUpload, oneDriveItem.Name, await oneDriveApi.GetItemFromDriveById(oneDriveItem.ParentReference.Id, oneDriveItem.ParentReference.DriveId));\n                            }\n                        }\n                    }\n\n                    // Uploading succeeded\n                    break;\n                }\n                catch (ArgumentNullException e)\n                {\n                    // If any other exception than the one we will get if the OneDrive API throws the random error, then ensure we pass on the exception instead of swallowing it\n                    if (e.ParamName != \"oneDriveUploadSession\")\n                    {\n                        throw;\n                    }\n\n                    updateStatus(string.Format(\"Uploading the new KeePass database {1} to OneDrive (attempt {0})\", uploadAttempts + 1, databaseConfig.KeePassDatabase.Name));\n                }\n            }\n\n            if (uploadResult == null)\n            {\n                updateStatus(string.Format(\"Failed to upload the KeePass database {0}\", databaseConfig.KeePassDatabase.Name));\n                return false;\n            }\n\n            // Delete the temporary database used for merging\n            System.IO.File.Delete(temporaryKeePassDatabasePath);\n\n           // The ETag changes with every request of the item so we use the CTag instead which only changes when the file changes\n            databaseConfig.ETag = uploadResult.CTag;\n\n            return true;\n        }\n\n        /// <summary>\n        /// Uses a Microsoft OneDrive Cloud Storage Provider (OneDrive Consumer, OneDrive for Business, Microsoft Graph) to download a KeePass database\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration of the database to sync</param>\n        /// <param name=\"updateStatus\">Action to write status messages to to display in the UI</param>\n        /// <returns>Path to the local KeePass database or NULL if the process has been aborted</returns>\n        public static async Task<string> OpenFromOneDriveCloudProvider(Configuration databaseConfig, Action<string> updateStatus)\n        {\n            // Connect to OneDrive\n            var oneDriveApi = await Utilities.GetOneDriveApi(databaseConfig);\n\n            if (oneDriveApi == null)\n            {\n                switch (databaseConfig.CloudStorageType.Value)\n                {\n                    case CloudStorageType.OneDriveConsumer: updateStatus(\"Failed to connect to OneDrive\"); break;\n                    case CloudStorageType.MicrosoftGraph:\n                    case CloudStorageType.MicrosoftGraphDeviceLogin:\n                        updateStatus(\"Failed to connect to Microsoft Graph\"); break;\n                    default: updateStatus(\"Failed to connect to cloud service\"); break;\n                }\n                return null;\n            }\n\n            // Save the RefreshToken in the configuration so we can use it again next time\n            databaseConfig.RefreshToken = oneDriveApi.AccessToken.RefreshToken;\n\n            // Fetch details about this OneDrive account\n            var oneDriveAccount = await oneDriveApi.GetDrive();\n            databaseConfig.OneDriveName = oneDriveAccount.Owner.User.DisplayName;\n\n            // Ask the user to select the database to open on OneDrive\n            var oneDriveFilePickerDialog = new Forms.OneDriveFilePickerDialog(oneDriveApi)\n            {\n                ExplanationText = \"Select the KeePass database to open. Right click for additional options.\",\n                AllowEnteringNewFileName = false\n            };\n            await oneDriveFilePickerDialog.LoadFolderItems();\n            var result = oneDriveFilePickerDialog.ShowDialog();\n            if (result != DialogResult.OK || string.IsNullOrEmpty(oneDriveFilePickerDialog.FileName))\n            {\n                KeePassDatabase.UpdateStatus(\"Open KeePass database from OneDrive aborted\");\n                return null;\n            }\n\n            databaseConfig.RemoteDatabasePath = (oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference.Path : \"\") + \"/\" + oneDriveFilePickerDialog.CurrentOneDriveItem.Name + \"/\" + oneDriveFilePickerDialog.FileName;\n            databaseConfig.RemoteDriveId = oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.ParentReference.DriveId : oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference.DriveId != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.ParentReference.DriveId : null;\n            if (oneDriveFilePickerDialog.CurrentOneDriveItem.File != null || (oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem != null && oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.File != null))\n            {\n                databaseConfig.RemoteItemId = oneDriveFilePickerDialog.CurrentOneDriveItem.File != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.Id : oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.Id;\n            }\n            else\n            {\n                databaseConfig.RemoteFolderId = oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem != null ? oneDriveFilePickerDialog.CurrentOneDriveItem.RemoteItem.Id : oneDriveFilePickerDialog.CurrentOneDriveItem.Id;\n            }\n            databaseConfig.RemoteFileName = oneDriveFilePickerDialog.FileName;\n\n            // Retrieve the metadata of the KeePass database on OneDrive\n            OneDriveItem oneDriveItem;\n            if (string.IsNullOrEmpty(databaseConfig.RemoteItemId))\n            {\n                // We don't have the ID of the KeePass file, check if the database is stored on the current user its drive or on a shared drive\n                OneDriveItem folder;\n                if (string.IsNullOrEmpty(databaseConfig.RemoteDriveId))\n                {\n                    // KeePass database is on the current user its drive\n                    folder = await oneDriveApi.GetItemById(databaseConfig.RemoteFolderId);\n                }\n                else\n                {\n                    // KeePass database is on a shared drive\n                    folder = await oneDriveApi.GetItemFromDriveById(databaseConfig.RemoteFolderId, databaseConfig.RemoteDriveId);\n                }\n\n                // Locate the KeePass file in the folder\n                oneDriveItem = await oneDriveApi.GetItemInFolder(folder, databaseConfig.RemoteFileName);\n\n                // Check if the KeePass file has been found\n                if (oneDriveItem != null)\n                {\n                    // Store the direct Id to the KeePass file so we can save several API calls on future syncs\n                    databaseConfig.RemoteItemId = oneDriveItem.Id;\n                    Configuration.Save();\n                }\n            }\n            else\n            {\n                // We have the ID of the KeePass file, check if it's on the current user its drive or on a shared drive\n                if (string.IsNullOrEmpty(databaseConfig.RemoteDriveId))\n                {\n                    // KeePass database is on the current user its drive\n                    oneDriveItem = await oneDriveApi.GetItemById(databaseConfig.RemoteItemId);\n                }\n                else\n                {\n                    // KeePass database is on a shared drive\n                    oneDriveItem = await oneDriveApi.GetItemFromDriveById(databaseConfig.RemoteItemId, databaseConfig.RemoteDriveId);\n                }\n            }\n\n            if (oneDriveItem == null)\n            {\n                // KeePass database not found on OneDrive\n                switch (databaseConfig.CloudStorageType.Value)\n                {\n                    case CloudStorageType.OneDriveConsumer: updateStatus(string.Format(\"Unable to find the database {0} on your OneDrive\", databaseConfig.KeePassDatabase.Name)); break;\n                    case CloudStorageType.MicrosoftGraph: updateStatus(string.Format(\"Unable to find the database {0} through Microsoft Graph\", databaseConfig.KeePassDatabase.Name)); break;\n                    default: updateStatus(\"Failed to connect to cloud service\"); break;\n                }\n                return null;\n            }\n\n            // Show the save as dialog to select a location locally where to store the KeePass database\n            var saveFiledialog = new SaveFileDialog\n            {\n                Filter = \"KeePass databases (*.kdbx)|*.kdbx|All Files (*.*)|*.*\",\n                Title = \"Select where to store the KeePass database locally\",\n                CheckFileExists = false,\n                FileName = oneDriveItem.Name\n            };\n\n            var saveFileDialogResult = saveFiledialog.ShowDialog();\n            if (saveFileDialogResult != DialogResult.OK || string.IsNullOrEmpty(saveFiledialog.FileName))\n            {\n                updateStatus(\"Open KeePass database from OneDrive aborted\");\n                return null;\n            }\n\n            // Download the KeePass database to the selected location\n            updateStatus(\"Downloading KeePass database\");\n            await oneDriveApi.DownloadItemAndSaveAs(oneDriveItem, saveFiledialog.FileName);\n\n            // The ETag changes with every request of the item so we use the CTag instead which only changes when the file changes\n            databaseConfig.ETag = oneDriveItem.CTag;\n\n            return saveFiledialog.FileName;\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/SharePointProvider.cs",
    "content": "﻿using KoenZomers.KeePass.OneDriveSync;\nusing Newtonsoft.Json.Linq;\nusing System;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Reflection;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers\n{\n    internal static class SharePointProvider\n    {\n        /// <summary>\n        /// Uses the Microsoft SharePoint platform (SharePoint 2013, 2016 or Online) to sync the KeePass database\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration of the database to sync</param>\n        /// <param name=\"localKeePassDatabasePath\">Path to where the KeePass database to sync resides</param>\n        /// <param name=\"forceSync\">Flag to indicate if the sync should always take place</param>\n        /// <param name=\"updateStatus\">Action to write status messages to to display in the UI</param>\n        /// <returns>True if successful, false if failed</returns>\n        public static async Task<bool> SyncUsingSharePointPlatform(Configuration databaseConfig, string localKeePassDatabasePath, bool forceSync, Action<string> updateStatus)\n        {\n            if(! await EnsureSharePointCredentials(databaseConfig))\n            {\n                return false;\n            }\n\n            using (var httpClient = CreateSharePointHttpClient(databaseConfig))\n            {\n                // Check if we have a Document Library on SharePoint to sync with\n                if (string.IsNullOrEmpty(databaseConfig.RemoteFolderId) && string.IsNullOrEmpty(databaseConfig.RemoteFileName))\n                {\n                    // Ask the user where to store the database on SharePoint\n                    var sharePointDocumentLibraryPickerDialog = new Forms.SharePointDocumentLibraryPickerDialog(httpClient);\n                    await sharePointDocumentLibraryPickerDialog.LoadDocumentLibraryItems();\n                    sharePointDocumentLibraryPickerDialog.FileName = !string.IsNullOrEmpty(databaseConfig.RemoteFileName) ? databaseConfig.RemoteFileName : new System.IO.FileInfo(localKeePassDatabasePath).Name;\n                    var result = sharePointDocumentLibraryPickerDialog.ShowDialog();\n                    if (result != DialogResult.OK || string.IsNullOrEmpty(sharePointDocumentLibraryPickerDialog.SelectedDocumentLibraryServerRelativeUrl))\n                    {\n                        return false;\n                    }\n                    databaseConfig.RemoteFolderId = sharePointDocumentLibraryPickerDialog.SelectedDocumentLibraryServerRelativeUrl;\n                    databaseConfig.RemoteFileName = sharePointDocumentLibraryPickerDialog.FileName;\n                    Configuration.Save();\n                }\n\n                // Ensure we have the SharePoint site name\n                if(string.IsNullOrEmpty(databaseConfig.OneDriveName))\n                {\n                    // We don't have the SharePoint site name yet, retrieve it now by triggering TestConnection\n                    await TestConnection(httpClient, databaseConfig);\n                    Configuration.Save();\n                }\n\n                // Retrieve the KeePass database from SharePoint\n                var serverRelativeSharePointUrl = string.Concat(databaseConfig.RemoteFolderId, \"/\", databaseConfig.RemoteFileName);\n                var eTag = await GetEtagOfFile(httpClient, serverRelativeSharePointUrl);\n\n                if (eTag == null)\n                {\n                    // KeePass database not found on OneDrive\n                    updateStatus(string.Format(\"Database {0} does not exist yet on SharePoint, uploading it now\", databaseConfig.KeePassDatabase.Name));\n\n                    // Upload the database to SharePoint\n                    eTag = await UploadFile(databaseConfig.KeePassDatabase.IOConnectionInfo.Path, databaseConfig.RemoteFolderId, databaseConfig.RemoteFileName, httpClient, true);\n\n                    updateStatus(string.Format(eTag == null ? \"Failed to upload the KeePass database {0}\" : \"Successfully uploaded the new KeePass database {0} to SharePoint\", databaseConfig.KeePassDatabase.Name));\n\n                    databaseConfig.LocalFileHash = Utilities.GetDatabaseFileHash(localKeePassDatabasePath);\n                    if (eTag != null)\n                    {\n                        databaseConfig.LastCheckedAt = DateTime.Now;\n                        databaseConfig.LastSyncedAt = DateTime.Now;\n                        databaseConfig.ETag = eTag;\n                    }\n                    Configuration.Save();\n                    return false;\n                }\n\n                // Use the ETag from the SharePoint item to compare it against the local database config etag to see if the content has changed\n                if (!forceSync && eTag == databaseConfig.ETag)\n                {\n                    updateStatus(string.Format(\"KeePass database {0} is in sync\", databaseConfig.KeePassDatabase.Name));\n\n                    databaseConfig.LastCheckedAt = DateTime.Now;\n                    Configuration.Save();\n\n                    return false;\n                }\n\n                // Download the database from SharePoint\n                updateStatus(string.Format(\"Downloading KeePass database {0} from SharePoint\", databaseConfig.KeePassDatabase.Name));\n\n                var temporaryKeePassDatabasePath = System.IO.Path.GetTempFileName();\n                var downloadSuccessful = DownloadFile(temporaryKeePassDatabasePath, serverRelativeSharePointUrl, httpClient);\n\n                if (! await downloadSuccessful)\n                {\n                    updateStatus(string.Format(\"Failed to download the KeePass database {0} from SharePoint\", databaseConfig.KeePassDatabase.Name));\n\n                    return false;\n                }\n\n                // Sync database\n                updateStatus(string.Format(\"KeePass database {0} downloaded, going to sync\", databaseConfig.KeePassDatabase.Name));\n\n                // Merge the downloaded database with the currently open KeePass database\n                var syncSuccessful = KeePassDatabase.MergeDatabases(databaseConfig, temporaryKeePassDatabasePath);\n\n                string localDatabaseToUpload;\n                if (!syncSuccessful)\n                {\n                    updateStatus(string.Format(\"Failed to synchronize the KeePass database {0}\", databaseConfig.KeePassDatabase.Name));\n\n                    var confirm = MessageBox.Show(string.Format(\"Unable to merge the KeePass database {0}. Did you just change the master password for this KeePass database? If so and you would like to OVERWRITE the KeePass database stored on your SharePoint site with your local database, select Yes, otherwise select No.\", databaseConfig.KeePassDatabase.Name), \"Confirm overwriting your KeePass database\", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);\n                    if (confirm != DialogResult.Yes) return false;\n\n                    // Upload the local database\n                    updateStatus(string.Format(\"Uploading the local KeePass database {0} to SharePoint\", databaseConfig.KeePassDatabase.Name));\n\n                    localDatabaseToUpload = databaseConfig.KeePassDatabase.IOConnectionInfo.Path;\n                }\n                else\n                {\n                    // Upload the synced database\n                    updateStatus(string.Format(\"Uploading the merged KeePass database {0} to SharePoint\", databaseConfig.KeePassDatabase.Name));\n\n                    localDatabaseToUpload = temporaryKeePassDatabasePath;\n                }\n\n                var uploadResult = await UploadFile(localDatabaseToUpload, databaseConfig.RemoteFolderId, databaseConfig.RemoteFileName, httpClient, false);\n\n                // Delete the temporary database used for merging\n                System.IO.File.Delete(temporaryKeePassDatabasePath);\n\n                databaseConfig.ETag = uploadResult;\n                return true;\n            }\n        }\n\n        /// <summary>\n        /// Tries to retrieve the ETag of the file at the provided server relative URL from SharePoint\n        /// </summary>\n        /// <param name=\"httpClient\">HttpClientt to use for the SharePoint communication</param>\n        /// <param name=\"serverRelativeUrl\">Server relative URL of the file to query for</param>\n        /// <returns>ETag of the file or NULL if unable to find the file</returns>\n        public static async Task<string> GetEtagOfFile(HttpClient httpClient, string serverRelativeUrl)\n        {\n            // Retrieve the ETag of the file\n            using (var response = await httpClient.GetAsync(\"web/GetFileByServerRelativeUrl('\" + serverRelativeUrl + \"')?$select=ETag\"))\n            {\n                // Check if the attempt was successful\n                if(!response.IsSuccessStatusCode)\n                {\n                    // Attempt failed\n                    return null;\n                }\n\n                // Attempt was successful, parse the JSON response\n                var responseJson = JObject.Parse(await response.Content.ReadAsStringAsync());\n\n                // Validate if ETag node exists in the result\n                JToken value;\n                if (responseJson.TryGetValue(\"ETag\", out value))\n                {\n                    // ETag node exists, return it\n                    return value.Value<string>();\n                }\n            }\n\n            return null;\n        }\n\n        /// <summary>\n        /// Uploads a file to SharePoint\n        /// </summary>\n        /// <param name=\"localDatabasePath\">Full path to where the file to upload resides locally</param>\n        /// <param name=\"serverRelativeUrl\">Server relative URL where the file should be uploaded. Should not include the filename.</param>\n        /// <param name=\"fileName\">Filename under which to store the file in SharePoint</param>\n        /// <param name=\"httpClient\">HttpClientt to use for the SharePoint communication</param>\n        /// <returns>ETag of the uploaded file if successful, NULL if it failed</returns>\n        public static async Task<string> UploadFile(string localDatabasePath, string serverRelativeUrl, string fileName, HttpClient httpClient, bool asNewFile)\n        {\n            try\n            {\n                // Get a FormDigest to send to SharePoint\n                var formDigest = await GetFormDigest(httpClient);\n\n                // Validate that the FormDigest was retrieved successfully\n                if(string.IsNullOrEmpty(formDigest))\n                {\n                    // No FormDigest available\n                    return null;\n                }\n\n                if(!asNewFile)\n                {\n                    // Send a check out request for the file, in case require checkout is enabled on the SharePoint Document Library\n                    using (var checkOutRequest = new HttpRequestMessage(HttpMethod.Post, \"web/GetFileByServerRelativeUrl('\" + serverRelativeUrl + \"/\" + fileName + \"')/CheckOut()\"))\n                    {\n                        checkOutRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n                        await httpClient.SendAsync(checkOutRequest);\n                    }\n                }\n\n                // Construct a new HTTP message\n                using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, asNewFile ? \"web/GetFolderByServerRelativeUrl('\" + serverRelativeUrl + \"')/Files/Add(url='\" + fileName + \"',overwrite=true)?$select=ETag\" :\n                                                                                              \"web/GetFileByServerRelativeUrl('\" + serverRelativeUrl + \"/\" + fileName + \"')/$value\"))\n                {\n                    // Add the FormDiges to the request header\n                    httpRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n                    \n                    if (!asNewFile)\n                    {\n                        // Add the header to indicate an update to an existing file should be done\n                        httpRequest.Headers.Add(\"X-HTTP-Method\", \"PUT\");\n                    }\n\n                    // Open the local file to upload\n                    using (var fileContent = new StreamContent(System.IO.File.OpenRead(localDatabasePath)))\n                    {\n                        // Set the BODY content to the file byes\n                        httpRequest.Content = fileContent;\n\n                        // Send the bytes of the local file to the upload location on SharePoint\n                        var response = await httpClient.SendAsync(httpRequest);\n\n                        // Verify if the file was uploaded successfully\n                        if (!response.IsSuccessStatusCode)\n                        {\n                            // Upload failed\n                            return null;\n                        }\n\n                        // Send a check in request of the file, in case require checkout is enabled on the SharePoint Document Library\n                        using (var checkInRequest = new HttpRequestMessage(HttpMethod.Post, \"web/GetFileByServerRelativeUrl('\" + serverRelativeUrl + \"/\" + fileName + \"')/CheckIn(comment='\" + (asNewFile ? \"Added\" : \"Updated\") + \" by \" + httpClient.DefaultRequestHeaders.UserAgent + \"',checkintype=0)\"))\n                        {\n                            checkInRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n                            await httpClient.SendAsync(checkInRequest);\n                        }\n\n                        if (asNewFile)\n                        {\n                            // Parse the result of the upload new file request to get the ETag\n                            var responseJson = JObject.Parse(await response.Content.ReadAsStringAsync());\n\n                            // Validate if a ETag node exists in the result\n                            JToken value;\n                            if (responseJson.TryGetValue(\"ETag\", out value))\n                            {\n                                // ETag node exists, return it\n                                return value.Value<string>();\n                            }\n                        }\n                        else\n                        {\n                            // Updating a file does not support retrieval of the new ETag, so send out another request to get it\n                            var eTag = await GetEtagOfFile(httpClient, serverRelativeUrl + \"/\" + fileName);\n                            return eTag;\n                        }\n                    }\n                }\n\n                return null;\n            }\n            catch(Exception)\n            {\n                return null;\n            }\n        }\n\n        /// <summary>\n        /// Downloads a file from SharePoint\n        /// </summary>\n        /// <param name=\"localDatabasePath\">Full path to where to download the file to</param>\n        /// <param name=\"serverRelativeUrl\">Server relative URL where the file should be downloaded from. Should include the filename.</param>\n        /// <param name=\"httpClient\">HttpClient to use for the SharePoint communication</param>\n        /// <returns>File instance representing the uploaded file if successful, NULL if it failed</returns>\n        public static async Task<bool> DownloadFile(string localDatabasePath, string serverRelativeUrl, HttpClient httpClient)\n        {\n            try\n            {\n                // Request the file contents\n                using (var response = await httpClient.GetStreamAsync(\"web/GetFileByServerRelativeUrl('\" + serverRelativeUrl + \"')/$value\"))\n                {\n                    // Open the local file\n                    using (var fileStream = System.IO.File.Create(localDatabasePath))\n                    {\n                        // Copy the downloaded bytes to the local file\n                        await response.CopyToAsync(fileStream);\n                    }\n                }\n\n                return true;\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Deletes a file at the provided location in SharePoint\n        /// </summary>\n        /// <param name=\"serverRelativeFilePath\">Server relative URL to the file to delete</param>\n        /// <param name=\"httpClient\">HttpClient to use for the SharePoint communication</param>\n        /// <returns>True if successful, false if failed</returns>\n        public static async Task<bool> DeleteFile(string serverRelativeFilePath, HttpClient httpClient)\n        {\n            try\n            {\n                // Get a FormDigest to send to SharePoint\n                var formDigest = await GetFormDigest(httpClient);\n\n                // Validate that the FormDigest was retrieved successfully\n                if (string.IsNullOrEmpty(formDigest))\n                {\n                    // No FormDigest available\n                    return false;\n                }\n\n                // Construct a new HTTP message\n                using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, \"web/GetFileByServerRelativeUrl('\" + serverRelativeFilePath + \"')\"))\n                {\n                    // Add the FormDiges to the request header\n                    httpRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n\n                    // Disable concurrency control\n                    httpRequest.Headers.Add(\"If-Match\", \"*\");\n\n                    // Instruct to perform a DELETE operation   \n                    httpRequest.Headers.Add(\"X-HTTP-Method\", \"DELETE\");\n\n                    // Send the request to SharePoint\n                    var response = await httpClient.SendAsync(httpRequest);\n\n                    // Verify if the request was processed successfully\n                    if (!response.IsSuccessStatusCode)\n                    {\n                        // Request failed\n                        return false;\n                    }\n\n                    // Request was successful\n                    return true;\n                }\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Deletes a folder at the provided location in SharePoint\n        /// </summary>\n        /// <param name=\"serverRelativeFolderPath\">Server relative URL to the folder to delete</param>\n        /// <param name=\"httpClient\">HttpClient to use for the SharePoint communication</param>\n        /// <returns>True if successful, false if failed</returns>\n        public static async Task<bool> DeleteFolder(string serverRelativeFolderPath, HttpClient httpClient)\n        {\n            try\n            {\n                // Get a FormDigest to send to SharePoint\n                var formDigest = await GetFormDigest(httpClient);\n\n                // Validate that the FormDigest was retrieved successfully\n                if (string.IsNullOrEmpty(formDigest))\n                {\n                    // No FormDigest available\n                    return false;\n                }\n\n                // Construct a new HTTP message\n                using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, \"web/GetFolderByServerRelativeUrl('\" + serverRelativeFolderPath + \"')\"))\n                {\n                    // Add the FormDiges to the request header\n                    httpRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n\n                    // Disable concurrency control\n                    httpRequest.Headers.Add(\"If-Match\", \"*\");\n\n                    // Instruct to perform a DELETE operation   \n                    httpRequest.Headers.Add(\"X-HTTP-Method\", \"DELETE\");\n\n                    // Send the request to SharePoint\n                    var response = await httpClient.SendAsync(httpRequest);\n\n                    // Verify if the request was processed successfully\n                    if (!response.IsSuccessStatusCode)\n                    {\n                        // Request failed\n                        return false;\n                    }\n\n                    // Request was successful\n                    return true;\n                }\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Renames a folder at the provided location in SharePoint\n        /// </summary>\n        /// <param name=\"newFolderName\">The new name to assign to the folder</param>\n        /// <param name=\"serverRelativeFolderPath\">Server relative URL to the folder to rename</param>\n        /// <param name=\"httpClient\">HttpClient to use for the SharePoint communication</param>\n        /// <returns>True if successful, false if failed</returns>\n        public static async Task<bool> RenameFolder(string newFolderName, string serverRelativeFolderPath, HttpClient httpClient)\n        {\n            try\n            {\n                // Get a FormDigest to send to SharePoint\n                var formDigest = await GetFormDigest(httpClient);\n\n                // Validate that the FormDigest was retrieved successfully\n                if (string.IsNullOrEmpty(formDigest))\n                {\n                    // No FormDigest available\n                    return false;\n                }\n               \n                // Define the server relative url of the parent folder in which the folder resides\n                var parentPath = serverRelativeFolderPath.Remove(serverRelativeFolderPath.LastIndexOf('/'));\n\n                // Construct a new HTTP message\n                using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, \"web/GetFolderByServerRelativeUrl('\" + serverRelativeFolderPath + \"')/moveto(newurl='\" + parentPath + \"/\" + newFolderName + \"')\"))\n                {\n                    // Add the FormDiges to the request header\n                    httpRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n\n                    // Disable concurrency control\n                    httpRequest.Headers.Add(\"If-Match\", \"*\");\n\n                    // Instruct to perform a MERGE operation   \n                    httpRequest.Headers.Add(\"X-HTTP-Method\", \"MERGE\");\n\n                    // Provide the POST body content\n                    //httpRequest.Content = new StringContent(\"{ '__metadata': { 'type': 'SP.Folder' }, 'Name': '\" + newFolderName + \"' }\", System.Text.Encoding.UTF8, \"application/json\");                    \n\n                    // Send the request to SharePoint\n                    var response = await httpClient.SendAsync(httpRequest);\n\n                    // Verify if the request was processed successfully\n                    if (!response.IsSuccessStatusCode)\n                    {\n                        // Request failed\n                        return false;\n                    }\n\n                    // Request was successful\n                    return true;\n                }\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Renames a file at the provided location in SharePoint\n        /// </summary>\n        /// <param name=\"newFileName\">The new name to assign to the file</param>\n        /// <param name=\"serverRelativeFilePath\">Server relative URL to the file to rename</param>\n        /// <param name=\"httpClient\">HttpClient to use for the SharePoint communication</param>\n        /// <returns>True if successful, false if failed</returns>\n        public static async Task<bool> RenameFile(string newFileName, string serverRelativeFilePath, HttpClient httpClient)\n        {\n            try\n            {\n                // Get a FormDigest to send to SharePoint\n                var formDigest = await GetFormDigest(httpClient);\n\n                // Validate that the FormDigest was retrieved successfully\n                if (string.IsNullOrEmpty(formDigest))\n                {\n                    // No FormDigest available\n                    return false;\n                }\n\n                // Define the server relative url of the folder in which the file resides\n                var parentPath = serverRelativeFilePath.Remove(serverRelativeFilePath.LastIndexOf('/'));\n\n                // Construct a new HTTP message\n                using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, \"web/GetFileByServerRelativeUrl('\" + serverRelativeFilePath + \"')/moveto(newurl='\" + parentPath + \"/\" + newFileName + \"',flags=0)\"))\n                {\n                    // Add the FormDiges to the request header\n                    httpRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n\n                    // Disable concurrency control\n                    httpRequest.Headers.Add(\"If-Match\", \"*\");\n\n                    // Instruct to perform a MERGE operation   \n                    httpRequest.Headers.Add(\"X-HTTP-Method\", \"MERGE\");\n\n                    // Send the request to SharePoint\n                    var response = await httpClient.SendAsync(httpRequest);\n\n                    // Verify if the request was processed successfully\n                    if (!response.IsSuccessStatusCode)\n                    {\n                        // Request failed\n                        return false;\n                    }\n\n                    // Request was successful\n                    return true;\n                }\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Creates a new folder at the provided location in SharePoint\n        /// </summary>\n        /// <param name=\"folderName\">Name of the new folder to create</param>\n        /// <param name=\"serverRelativeUrl\">Server relative URL to the location where to create the new folder</param>\n        /// <param name=\"httpClient\">HttpClient to use for the SharePoint communication</param>\n        /// <returns>Server relative URL of the new folder if successful or NULL if failed to create the new folder</returns>\n        public static async Task<string> CreateFolder(string folderName, string serverRelativeUrl, HttpClient httpClient)\n        {\n            try\n            {\n                // Get a FormDigest to send to SharePoint\n                var formDigest = await GetFormDigest(httpClient);\n\n                // Validate that the FormDigest was retrieved successfully\n                if (string.IsNullOrEmpty(formDigest))\n                {\n                    // No FormDigest available\n                    return null;\n                }\n\n                // Construct a new HTTP message\n                using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, \"web/GetFolderByServerRelativeUrl('\" + serverRelativeUrl + \"')/Folders/Add('\" + folderName + \"')?$select=ServerRelativeUrl\"))\n                {\n                    // Add the FormDiges to the request header\n                    httpRequest.Headers.Add(\"X-RequestDigest\", formDigest);\n\n                    // Send the request to SharePoint\n                    var response = await httpClient.SendAsync(httpRequest);\n\n                    // Verify if the request was processed successfully\n                    if (!response.IsSuccessStatusCode)\n                    {\n                        // Request failed\n                        return null;\n                    }\n\n                    // Request was successful. Parse the result of the request.\n                    var responseJson = JObject.Parse(await response.Content.ReadAsStringAsync());\n\n                    // Validate if a ServerRelativeUrl node exists in the result\n                    JToken value;\n                    if (responseJson.TryGetValue(\"ServerRelativeUrl\", out value))\n                    {\n                        // ServerRelativeUrl node exists, return it\n                        return value.Value<string>();\n                    }\n                }\n            }\n            catch (Exception)\n            {\n                return null;\n            }\n            return null;\n        }\n\n        /// <summary>\n        /// Requests a FormDigest from SharePoint which is needed when requesting changes to SharePoint\n        /// </summary>\n        /// <param name=\"httpClient\">HttpClient to use for the SharePoint communication</param>\n        /// <returns>FormDirect if successful or NULL if unable to retrieve the FormDigest</returns>\n        public static async Task<string> GetFormDigest(HttpClient httpClient)\n        {\n            try\n            {\n                // Request a RequestDigest to allow uploading to SharePoint\n                using (var response = await httpClient.PostAsync(\"contextInfo\", new StringContent(\"Hello\")))\n                {\n                    // Verify if the RequestDigest was retrieved successfully\n                    if (!response.IsSuccessStatusCode)\n                    {\n                        // Request failed\n                        return null;\n                    }\n\n                    // Request was successful. Parse the result of the request.\n                    var responseJson = JObject.Parse(await response.Content.ReadAsStringAsync());\n\n                    // Validate if a FormDigestValue node exists in the result\n                    JToken value;\n                    if (responseJson.TryGetValue(\"FormDigestValue\", out value))\n                    {\n                        // FormDigestValue node exists, return it\n                        return value.Value<string>();\n                    }\n                }\n            }\n            catch (Exception)\n            {\n                return null;\n            }\n            return null;\n        }\n\n        /// <summary>\n        /// Creates a SharePoint ClientContext based on a Configuration file specific for a SharePoint synchronization\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration set to be specific for a SharePoint synchronization</param>\n        /// <returns>SharePoint HttpClient or NULL if unable to establish one based on the provided configuration</returns>\n        public static HttpClient CreateSharePointHttpClient(Configuration databaseConfig)\n        {\n            // Collect the SharePoint variables required to connect\n            var sharePointUri = new Uri(databaseConfig.RemoteDatabasePath);\n            var sharePointClientId = databaseConfig.RefreshToken.Remove(databaseConfig.RefreshToken.IndexOf(';'));\n            var sharePointClientSecret = databaseConfig.RefreshToken.Remove(0, databaseConfig.RefreshToken.IndexOf(';') + 1);\n\n            return CreateSharePointHttpClient(sharePointUri, sharePointClientId, sharePointClientSecret);\n        }\n\n        /// <summary>\n        /// Creates a SharePoint ClientContext based on the provided SharePoint Uri, ClientId and ClientSecret\n        /// </summary>\n        /// <param name=\"sharePointUri\">Uri of the SharePoint site to connect to</param>\n        /// <param name=\"sharePointClientId\">ClientId to use for the Low Trust to connect to SharePoint</param>\n        /// <param name=\"sharePointClientSecret\">ClientSecret to use for the Low Trust to connect to SharePoint</param>\n        /// <returns>SharePoint HttpClient or NULL if unable to establish one based on the provided configuration</returns>\n        public static HttpClient CreateSharePointHttpClient(Uri sharePointUri, string sharePointClientId, string sharePointClientSecret)\n        {\n            // Get the realm for the SharePoint site\n            var realm = TokenHelper.GetRealmFromTargetUrl(sharePointUri);\n\n            // Get the access token for the URL\n            var accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, sharePointUri.Authority, realm, sharePointClientId, sharePointClientSecret).AccessToken;\n\n            // Connect to SharePoint\n            var httpClientHandler = new HttpClientHandler()\n            {\n                Proxy = Utilities.GetProxySettings(),\n                PreAuthenticate = true,\n                UseDefaultCredentials = false,\n                Credentials = Utilities.GetProxyCredentials()\n            };\n\n            // Set the base URI to use for all calls\n            var httpClient = new HttpClient(httpClientHandler)\n            {\n                BaseAddress = new Uri(sharePointUri.OriginalString + \"/_api/\")\n            };\n\n            // Configure the HTTP headers for each request\n            httpClient.DefaultRequestHeaders.Accept.Clear();\n            httpClient.DefaultRequestHeaders.Add(\"Accept\", \"application/json; odata=nometadata\");\n            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n\n            var assemblyVersion = Assembly.GetCallingAssembly().GetName().Version;\n            httpClient.DefaultRequestHeaders.Add(\"User-Agent\", string.Format(\"KoenZomers KeePass OneDriveSync v{0}.{1}.{2}.{3}\", assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build, assemblyVersion.Revision));\n\n            return httpClient;\n        }\n\n        /// <summary>\n        /// Form to request the SharePoint details to connect to\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration which needs to map to a SharePoint environment</param>\n        /// <returns>True if successful, false if failed to receive a SharePoint configuration</returns>\n        private static bool RequestSharePointDetails(Configuration databaseConfig)\n        {\n            var sharePointCredentialsDialog = new Forms.SharePointCredentialsForm();\n            var result = sharePointCredentialsDialog.ShowDialog();\n            if (result != DialogResult.OK)\n            {\n                return false;\n            }\n\n            // Copy the entered data into the database configuration\n            databaseConfig.RefreshToken = string.Format(\"{0};{1}\", sharePointCredentialsDialog.SharePointClientId, sharePointCredentialsDialog.SharePointClientSecret);\n            databaseConfig.RemoteDatabasePath = sharePointCredentialsDialog.SharePointUrl;\n            Configuration.Save();\n\n            return true;\n        }\n\n        /// <summary>\n        /// Test the connection with the provided HttpClient\n        /// </summary>\n        /// <param name=\"httpClient\">The HttpClient to use to test the connection</param>\n        /// <param name=\"databaseConfig\">If config is provided, the drive name will be updated with the actual title (optional)</param>\n        /// <returns>True if connection successful, False if the test failed</returns>\n        public static async Task<bool> TestConnection(HttpClient httpClient, Configuration databaseConfig = null)\n        {\n            try\n            {\n                // Perform a simple get operation to test the access to SharePoint\n                using (var response = await httpClient.GetAsync(\"web?$select=Title\"))\n                {\n\n                    // Verify if the request was successful\n                    if (!response.IsSuccessStatusCode)\n                    {\n                        // Request failed\n                        return false;\n                    }\n\n                    // Request was successful. Check if a database config was provided which we can update with the actual site title.\n                    if (databaseConfig == null)\n                    {\n                        // No database config was provided. No need to parse the result.\n                        return true;\n                    }\n\n                    // Database config was provided. Parse the result of the request.\n                    var responseJson = JObject.Parse(await response.Content.ReadAsStringAsync());\n\n                    // Validate if a Title node exists in the result\n                    JToken value;\n                    if (responseJson.TryGetValue(\"Title\", out value))\n                    {\n                        // Title node exists, update the database config with the site title\n                        databaseConfig.OneDriveName = value.Value<string>();\n                    }\n                }\n\n                return true;                \n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// Ensures that the provided database config contains information to connect to SharePoint. If not, it will prompt for the end user to provide the details.\n        /// </summary>\n        /// <param name=\"databaseConfig\">Databaseconfig to check for the presence of SharePoint authentication information</param>\n        /// <returns>True if succeeded to get SharePoint authentication information, false if failed</returns>\n        public static async Task<bool> EnsureSharePointCredentials(Configuration databaseConfig)\n        {\n            if (string.IsNullOrEmpty(databaseConfig.RefreshToken) || databaseConfig.RefreshToken.IndexOf(';') == -1 || string.IsNullOrEmpty(databaseConfig.RemoteDatabasePath))\n            {\n                // Configuration does not have a SharePoint config in it yet, ask for connection details\n                bool retryGettingApiInstance;\n                do\n                {\n                    retryGettingApiInstance = false;\n                    try\n                    {\n                        var requestSharePointDetailsSuccessful = RequestSharePointDetails(databaseConfig);\n\n                        if (!requestSharePointDetailsSuccessful)\n                        {\n                            return false;\n                        }\n\n                        using (var httpClient = CreateSharePointHttpClient(databaseConfig))\n                        {\n                            if (! await TestConnection(httpClient, databaseConfig))\n                            {\n                                MessageBox.Show(\"Connection failed. Please ensure you are able to connect to the SharePoint farm\", \"Connecting to SharePoint\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\n                                retryGettingApiInstance = true;\n                            }\n                        }\n                    }\n                    catch (Exception e)\n                    {\n                        // Build the error text to show to the end user\n                        var errorMessage = new System.Text.StringBuilder();\n                        errorMessage.Append(\"Failed to connect to SharePoint:\");\n                        errorMessage.AppendLine();\n                        errorMessage.AppendLine(e.Message);\n\n                        // If there's an inner exception, show its message as well as it typically gives more detail why it went wrong\n                        if (e.InnerException != null)\n                        {\n                            errorMessage.AppendLine(e.InnerException.Message);\n\n                            // Verify if we're offline\n                            if (e.InnerException.Message.Contains(\"remote name could not be resolved\"))\n                            {\n                                // Offline, don't display a modal dialog but use the status bar instead\n                                KeePassDatabase.UpdateStatus(\"Can't connect. Working offline.\");\n                                return false;\n                            }\n                        }\n\n                        MessageBox.Show(errorMessage.ToString(), \"Connection failed\", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);\n                        retryGettingApiInstance = true;\n                    }\n                } while (retryGettingApiInstance);\n            }\n\n            return true;\n        }\n\n        /// <summary>\n        /// Download a KeePass database from SharePoint\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration of the database to sync</param>\n        /// <param name=\"updateStatus\">Action to write status messages to to display in the UI</param>\n        /// <returns>Path to the local KeePass database or NULL if the process has been aborted</returns>\n        public static async Task<string> OpenFromSharePoint(Configuration databaseConfig, Action<string> updateStatus)\n        {\n            if(! await EnsureSharePointCredentials(databaseConfig))\n            {\n                return null;\n            }\n\n            using (var httpClient = CreateSharePointHttpClient(databaseConfig))\n            {\n                // Ask the user where to store the database on SharePoint\n                var sharePointDocumentLibraryPickerDialog = new Forms.SharePointDocumentLibraryPickerDialog(httpClient)\n                {\n                    ExplanationText = \"Select the KeePass database to open. Right click for additional options.\",\n                    AllowEnteringNewFileName = false\n                };\n                await sharePointDocumentLibraryPickerDialog.LoadDocumentLibraryItems();\n\n                var result = sharePointDocumentLibraryPickerDialog.ShowDialog();\n                if (result != DialogResult.OK || string.IsNullOrEmpty(sharePointDocumentLibraryPickerDialog.SelectedDocumentLibraryServerRelativeUrl))\n                {\n                    updateStatus(\"Open KeePass database from SharePoint aborted\");\n                    return null;\n                }\n                databaseConfig.RemoteFolderId = sharePointDocumentLibraryPickerDialog.SelectedDocumentLibraryServerRelativeUrl;\n                databaseConfig.RemoteFileName = sharePointDocumentLibraryPickerDialog.FileName;\n\n                // Show the save as dialog to select a location locally where to store the KeePass database\n                var saveFiledialog = new SaveFileDialog\n                {\n                    Filter = \"KeePass databases (*.kdbx)|*.kdbx|All Files (*.*)|*.*\",\n                    Title = \"Select where to store the KeePass database locally\",\n                    CheckFileExists = false,\n                    FileName = sharePointDocumentLibraryPickerDialog.FileName\n                };\n\n                var saveFileDialogResult = saveFiledialog.ShowDialog();\n                if (saveFileDialogResult != DialogResult.OK || string.IsNullOrEmpty(saveFiledialog.FileName))\n                {\n                    updateStatus(\"Open KeePass database from SharePoint aborted\");\n                    return null;\n                }\n\n                // Download the KeePass database to the selected location\n                updateStatus(\"Downloading KeePass database\");\n\n                // Retrieve the KeePass database from SharePoint\n                var serverRelativeSharePointUrl = string.Concat(databaseConfig.RemoteFolderId, \"/\", databaseConfig.RemoteFileName);\n                var downloadSuccessful = await DownloadFile(saveFiledialog.FileName, serverRelativeSharePointUrl, httpClient);\n\n                // Get the ETag of the database so we can determine if it's in sync\n                databaseConfig.ETag = await GetEtagOfFile(httpClient, serverRelativeSharePointUrl);\n\n                return downloadSuccessful ? saveFiledialog.FileName : null;\n            }\n        }\n    }\n} "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace KoenZomersKeePassOneDriveSync {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"KoenZomersKeePassOneDriveSync.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap MicrosoftLogo {\n            get {\n                object obj = ResourceManager.GetObject(\"MicrosoftLogo\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap MSGraph {\n            get {\n                object obj = ResourceManager.GetObject(\"MSGraph\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap OneDrive {\n            get {\n                object obj = ResourceManager.GetObject(\"OneDrive\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap OneDriveBothClouds {\n            get {\n                object obj = ResourceManager.GetObject(\"OneDriveBothClouds\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap OneDriveConsumer {\n            get {\n                object obj = ResourceManager.GetObject(\"OneDriveConsumer\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap OneDriveForBusiness {\n            get {\n                object obj = ResourceManager.GetObject(\"OneDriveForBusiness\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap OneDriveIcon {\n            get {\n                object obj = ResourceManager.GetObject(\"OneDriveIcon\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap SharePoint {\n            get {\n                object obj = ResourceManager.GetObject(\"SharePoint\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"MicrosoftLogo\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\mslogo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"MSGraph\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\MSGraph.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"OneDrive\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\OneDrive.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"OneDriveBothClouds\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\OneDriveBothClouds.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"OneDriveConsumer\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Images\\OneDriveConsumer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"OneDriveForBusiness\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\OneDriveForBusiness.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"OneDriveIcon\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\OneDriveIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"SharePoint\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\SharePoint.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/TokenHelper.cs",
    "content": "using Microsoft.IdentityModel;\nusing Microsoft.IdentityModel.SecurityTokenService;\nusing Microsoft.IdentityModel.S2S.Protocols.OAuth2;\nusing Microsoft.IdentityModel.S2S.Tokens;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Globalization;\nusing System.IdentityModel.Selectors;\nusing System.IdentityModel.Tokens;\nusing System.IO;\nusing System.Linq;\nusing System.Net;\nusing System.Security.Cryptography.X509Certificates;\nusing System.Security.Principal;\nusing System.Text;\nusing System.Web;\nusing System.Web.Configuration;\nusing System.Web.Script.Serialization;\nusing AudienceRestriction = Microsoft.IdentityModel.Tokens.AudienceRestriction;\nusing SecurityTokenHandlerConfiguration = Microsoft.IdentityModel.Tokens.SecurityTokenHandlerConfiguration;\nusing X509SigningCredentials = Microsoft.IdentityModel.SecurityTokenService.X509SigningCredentials;\nusing System.Net.Http;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public static class TokenHelper\n    {\n        #region public fields\n\n        /// <summary>\n        /// SharePoint principal.\n        /// </summary>\n        public const string SharePointPrincipal = \"00000003-0000-0ff1-ce00-000000000000\";\n\n        /// <summary>\n        /// Lifetime of HighTrust access token, 12 hours.\n        /// </summary>\n        public static readonly TimeSpan HighTrustAccessTokenLifetime = TimeSpan.FromHours(12.0);\n\n        #endregion public fields\n\n        #region public methods\n\n        /// <summary>\n        /// Retrieves the context token string from the specified request by looking for well-known parameter names in the \n        /// POSTed form parameters and the querystring. Returns null if no context token is found.\n        /// </summary>\n        /// <param name=\"request\">HttpRequest in which to look for a context token</param>\n        /// <returns>The context token string</returns>\n        public static string GetContextTokenFromRequest(HttpRequest request)\n        {\n            return GetContextTokenFromRequest(new HttpRequestWrapper(request));\n        }\n\n        /// <summary>\n        /// Retrieves the context token string from the specified request by looking for well-known parameter names in the \n        /// POSTed form parameters and the querystring. Returns null if no context token is found.\n        /// </summary>\n        /// <param name=\"request\">HttpRequest in which to look for a context token</param>\n        /// <returns>The context token string</returns>\n        public static string GetContextTokenFromRequest(HttpRequestBase request)\n        {\n            string[] paramNames = { \"AppContext\", \"AppContextToken\", \"AccessToken\", \"SPAppToken\" };\n            foreach (string paramName in paramNames)\n            {\n                if (!string.IsNullOrEmpty(request.Form[paramName]))\n                {\n                    return request.Form[paramName];\n                }\n                if (!string.IsNullOrEmpty(request.QueryString[paramName]))\n                {\n                    return request.QueryString[paramName];\n                }\n            }\n            return null;\n        }\n\n        /// <summary>\n        /// Retrieves an access token from ACS to call the source of the specified context token at the specified \n        /// targetHost. The targetHost must be registered for the principal that sent the context token.\n        /// </summary>\n        /// <param name=\"contextToken\">Context token issued by the intended access token audience</param>\n        /// <param name=\"targetHost\">Url authority of the target principal</param>\n        /// <returns>An access token with an audience matching the context token's source</returns>\n        public static OAuth2AccessTokenResponse GetAccessToken(SharePointContextToken contextToken, string targetHost)\n        {\n            string targetPrincipalName = contextToken.TargetPrincipalName;\n\n            // Extract the refreshToken from the context token\n            string refreshToken = contextToken.RefreshToken;\n\n            if (String.IsNullOrEmpty(refreshToken))\n            {\n                return null;\n            }\n\n            string targetRealm = Realm ?? contextToken.Realm;\n\n            return GetAccessToken(refreshToken,\n                                  targetPrincipalName,\n                                  targetHost,\n                                  targetRealm);\n        }\n\n        /// <summary>\n        /// Uses the specified authorization code to retrieve an access token from ACS to call the specified principal \n        /// at the specified targetHost. The targetHost must be registered for target principal.  If specified realm is \n        /// null, the \"Realm\" setting in web.config will be used instead.\n        /// </summary>\n        /// <param name=\"authorizationCode\">Authorization code to exchange for access token</param>\n        /// <param name=\"targetPrincipalName\">Name of the target principal to retrieve an access token for</param>\n        /// <param name=\"targetHost\">Url authority of the target principal</param>\n        /// <param name=\"targetRealm\">Realm to use for the access token's nameid and audience</param>\n        /// <param name=\"redirectUri\">Redirect URI registered for this add-in</param>\n        /// <returns>An access token with an audience of the target principal</returns>\n        public static OAuth2AccessTokenResponse GetAccessToken(\n            string authorizationCode,\n            string targetPrincipalName,\n            string targetHost,\n            string targetRealm,\n            Uri redirectUri)\n        {\n            if (targetRealm == null)\n            {\n                targetRealm = Realm;\n            }\n\n            string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, targetRealm);\n            string clientId = GetFormattedPrincipal(ClientId, null, targetRealm);\n\n            // Create request for token. The RedirectUri is null here.  This will fail if redirect uri is registered\n            OAuth2AccessTokenRequest oauth2Request =\n                OAuth2MessageFactory.CreateAccessTokenRequestWithAuthorizationCode(\n                    clientId,\n                    ClientSecret,\n                    authorizationCode,\n                    redirectUri,\n                    resource);\n\n            // Get token\n            OAuth2S2SClient client = new OAuth2S2SClient();\n            OAuth2AccessTokenResponse oauth2Response;\n            try\n            {\n                oauth2Response =\n                    client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;\n            }\n            catch (RequestFailedException)\n            {\n                if (!string.IsNullOrEmpty(SecondaryClientSecret))\n                {\n                    oauth2Request =\n                    OAuth2MessageFactory.CreateAccessTokenRequestWithAuthorizationCode(\n                        clientId,\n                        SecondaryClientSecret,\n                        authorizationCode,\n                        redirectUri,\n                        resource);\n\n                    oauth2Response =\n                        client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;\n                }\n                else\n                {\n                    throw;\n                }\n            }\n            catch (WebException wex)\n            {\n                using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))\n                {\n                    string responseText = sr.ReadToEnd();\n                    throw new WebException(wex.Message + \" - \" + responseText, wex);\n                }\n            }\n\n            return oauth2Response;\n        }\n\n        /// <summary>\n        /// Uses the specified refresh token to retrieve an access token from ACS to call the specified principal \n        /// at the specified targetHost. The targetHost must be registered for target principal.  If specified realm is \n        /// null, the \"Realm\" setting in web.config will be used instead.\n        /// </summary>\n        /// <param name=\"refreshToken\">Refresh token to exchange for access token</param>\n        /// <param name=\"targetPrincipalName\">Name of the target principal to retrieve an access token for</param>\n        /// <param name=\"targetHost\">Url authority of the target principal</param>\n        /// <param name=\"targetRealm\">Realm to use for the access token's nameid and audience</param>\n        /// <returns>An access token with an audience of the target principal</returns>\n        public static OAuth2AccessTokenResponse GetAccessToken(\n            string refreshToken,\n            string targetPrincipalName,\n            string targetHost,\n            string targetRealm)\n        {\n            if (targetRealm == null)\n            {\n                targetRealm = Realm;\n            }\n\n            string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, targetRealm);\n            string clientId = GetFormattedPrincipal(ClientId, null, targetRealm);\n\n            OAuth2AccessTokenRequest oauth2Request = OAuth2MessageFactory.CreateAccessTokenRequestWithRefreshToken(clientId, ClientSecret, refreshToken, resource);\n\n            // Get token\n            OAuth2S2SClient client = new OAuth2S2SClient();\n            OAuth2AccessTokenResponse oauth2Response;\n            try\n            {\n                oauth2Response =\n                    client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;\n            }\n            catch (RequestFailedException)\n            {\n                if (!string.IsNullOrEmpty(SecondaryClientSecret))\n                {\n                    oauth2Request = OAuth2MessageFactory.CreateAccessTokenRequestWithRefreshToken(clientId, SecondaryClientSecret, refreshToken, resource);\n                    oauth2Response =\n                        client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;\n                }\n                else\n                {\n                    throw;\n                }\n            }\n            catch (WebException wex)\n            {\n                using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))\n                {\n                    string responseText = sr.ReadToEnd();\n                    throw new WebException(wex.Message + \" - \" + responseText, wex);\n                }\n            }\n\n            return oauth2Response;\n        }\n\n        /// <summary>\n        /// Retrieves an app-only access token from ACS to call the specified principal \n        /// at the specified targetHost. The targetHost must be registered for target principal.  If specified realm is \n        /// null, the \"Realm\" setting in web.config will be used instead.\n        /// </summary>\n        /// <param name=\"targetPrincipalName\">Name of the target principal to retrieve an access token for</param>\n        /// <param name=\"targetHost\">Url authority of the target principal</param>\n        /// <param name=\"targetRealm\">Realm to use for the access token's nameid and audience</param>\n        /// <returns>An access token with an audience of the target principal</returns>\n        public static OAuth2AccessTokenResponse GetAppOnlyAccessToken(\n            string targetPrincipalName,\n            string targetHost,\n            string targetRealm,\n            string clientId = null,\n            string clientSecret = null)\n        {\n            if (targetRealm == null)\n            {\n                targetRealm = Realm;\n            }\n\n            if(clientId == null)\n            {\n                clientId = ClientId;\n            }\n\n            if(clientSecret == null)\n            {\n                clientSecret = ClientSecret;\n            }\n\n            string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, targetRealm);\n            string formattedClientId = GetFormattedPrincipal(clientId, HostedAppHostName, targetRealm);\n\n            OAuth2AccessTokenRequest oauth2Request = OAuth2MessageFactory.CreateAccessTokenRequestWithClientCredentials(formattedClientId, clientSecret, resource);\n            oauth2Request.Resource = resource;\n\n            // Get token\n            OAuth2S2SClient client = new OAuth2S2SClient();\n\n            OAuth2AccessTokenResponse oauth2Response;\n            try\n            {\n                oauth2Response =\n                    client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;\n            }\n            catch (RequestFailedException)\n            {\n                if (!string.IsNullOrEmpty(SecondaryClientSecret))\n                {\n                    oauth2Request = OAuth2MessageFactory.CreateAccessTokenRequestWithClientCredentials(clientId, SecondaryClientSecret, resource);\n                    oauth2Request.Resource = resource;\n\n                    oauth2Response =\n                        client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;\n                }\n                else\n                {\n                    throw;\n                }\n            }\n            catch (WebException wex)\n            {\n                using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))\n                {\n                    string responseText = sr.ReadToEnd();\n                    throw new WebException(wex.Message + \" - \" + responseText, wex);\n                }\n            }\n\n            return oauth2Response;\n        }\n \n        /// <summary>\n        /// Returns the SharePoint url to which the add-in should redirect the browser to request consent and get back\n        /// an authorization code.\n        /// </summary>\n        /// <param name=\"contextUrl\">Absolute Url of the SharePoint site</param>\n        /// <param name=\"scope\">Space-delimited permissions to request from the SharePoint site in \"shorthand\" format \n        /// (e.g. \"Web.Read Site.Write\")</param>\n        /// <returns>Url of the SharePoint site's OAuth authorization page</returns>\n        public static string GetAuthorizationUrl(string contextUrl, string scope)\n        {\n            return string.Format(\n                \"{0}{1}?IsDlg=1&client_id={2}&scope={3}&response_type=code\",\n                EnsureTrailingSlash(contextUrl),\n                AuthorizationPage,\n                ClientId,\n                scope);\n        }\n\n        /// <summary>\n        /// Returns the SharePoint url to which the add-in should redirect the browser to request consent and get back\n        /// an authorization code.\n        /// </summary>\n        /// <param name=\"contextUrl\">Absolute Url of the SharePoint site</param>\n        /// <param name=\"scope\">Space-delimited permissions to request from the SharePoint site in \"shorthand\" format\n        /// (e.g. \"Web.Read Site.Write\")</param>\n        /// <param name=\"redirectUri\">Uri to which SharePoint should redirect the browser to after consent is \n        /// granted</param>\n        /// <returns>Url of the SharePoint site's OAuth authorization page</returns>\n        public static string GetAuthorizationUrl(string contextUrl, string scope, string redirectUri)\n        {\n            return string.Format(\n                \"{0}{1}?IsDlg=1&client_id={2}&scope={3}&response_type=code&redirect_uri={4}\",\n                EnsureTrailingSlash(contextUrl),\n                AuthorizationPage,\n                ClientId,\n                scope,\n                redirectUri);\n        }\n\n        /// <summary>\n        /// Returns the SharePoint url to which the add-in should redirect the browser to request a new context token.\n        /// </summary>\n        /// <param name=\"contextUrl\">Absolute Url of the SharePoint site</param>\n        /// <param name=\"redirectUri\">Uri to which SharePoint should redirect the browser to with a context token</param>\n        /// <returns>Url of the SharePoint site's context token redirect page</returns>\n        public static string GetAppContextTokenRequestUrl(string contextUrl, string redirectUri)\n        {\n            return string.Format(\n                \"{0}{1}?client_id={2}&redirect_uri={3}\",\n                EnsureTrailingSlash(contextUrl),\n                RedirectPage,\n                ClientId,\n                redirectUri);\n        }\n\n        /// <summary>\n        /// Retrieves an S2S access token signed by the application's private certificate on behalf of the specified \n        /// WindowsIdentity and intended for the SharePoint at the targetApplicationUri. If no Realm is specified in \n        /// web.config, an auth challenge will be issued to the targetApplicationUri to discover it.\n        /// </summary>\n        /// <param name=\"targetApplicationUri\">Url of the target SharePoint site</param>\n        /// <param name=\"identity\">Windows identity of the user on whose behalf to create the access token</param>\n        /// <returns>An access token with an audience of the target principal</returns>\n        public static string GetS2SAccessTokenWithWindowsIdentity(\n            Uri targetApplicationUri,\n            WindowsIdentity identity)\n        {\n            string realm = string.IsNullOrEmpty(Realm) ? GetRealmFromTargetUrl(targetApplicationUri) : Realm;\n\n            JsonWebTokenClaim[] claims = identity != null ? GetClaimsWithWindowsIdentity(identity) : null;\n\n            return GetS2SAccessTokenWithClaims(targetApplicationUri.Authority, realm, claims);\n        }\n\n        /// <summary>\n        /// Get authentication realm from SharePoint\n        /// </summary>\n        /// <param name=\"targetApplicationUri\">Url of the target SharePoint site</param>\n        /// <returns>String representation of the realm GUID</returns>\n        public static string GetRealmFromTargetUrl(Uri targetApplicationUri)\n        {\n            WebRequest request = WebRequest.Create(targetApplicationUri.ToString().TrimEnd('/') + \"/_vti_bin/client.svc\");\n            request.Headers.Add(\"Authorization: Bearer \");\n\n            try\n            {\n                // We're expecting an exception here as the server should return a 401 telling us how we can authenticate\n                using (request.GetResponse())\n                {\n                }\n            }\n            catch (WebException e)\n            {\n                if (e.Response == null)\n                {\n                    return null;\n                }\n\n                string bearerResponseHeader = e.Response.Headers[\"WWW-Authenticate\"];\n                if (string.IsNullOrEmpty(bearerResponseHeader))\n                {\n                    return null;\n                }\n\n                const string bearer = \"Bearer realm=\\\"\";\n                int bearerIndex = bearerResponseHeader.IndexOf(bearer, StringComparison.Ordinal);\n                if (bearerIndex < 0)\n                {\n                    return null;\n                }\n\n                int realmIndex = bearerIndex + bearer.Length;\n\n                if (bearerResponseHeader.Length >= realmIndex + 36)\n                {\n                    string targetRealm = bearerResponseHeader.Substring(realmIndex, 36);\n\n                    Guid realmGuid;\n\n                    if (Guid.TryParse(targetRealm, out realmGuid))\n                    {\n                        return targetRealm;\n                    }\n                }\n            }\n            return null;\n        }\n\n        /// <summary>\n        /// Determines if this is a high trust add-in.\n        /// </summary>\n        /// <returns>True if this is a high trust add-in.</returns>\n        public static bool IsHighTrustApp()\n        {\n            return SigningCredentials != null;\n        }\n\n        /// <summary>\n        /// Ensures that the specified URL ends with '/' if it is not null or empty.\n        /// </summary>\n        /// <param name=\"url\">The url.</param>\n        /// <returns>The url ending with '/' if it is not null or empty.</returns>\n        public static string EnsureTrailingSlash(string url)\n        {\n            if (!string.IsNullOrEmpty(url) && url[url.Length - 1] != '/')\n            {\n                return url + \"/\";\n            }\n\n            return url;\n        }\n\n        #endregion\n\n        #region private fields\n\n        //\n        // Configuration Constants\n        //        \n\n        private const string AuthorizationPage = \"_layouts/15/OAuthAuthorize.aspx\";\n        private const string RedirectPage = \"_layouts/15/AppRedirect.aspx\";\n        private const string AcsPrincipalName = \"00000001-0000-0000-c000-000000000000\";\n        private const string AcsMetadataEndPointRelativeUrl = \"metadata/json/1\";\n        private const string S2SProtocol = \"OAuth2\";\n        private const string DelegationIssuance = \"DelegationIssuance1.0\";\n        private const string NameIdentifierClaimType = JsonWebTokenConstants.ReservedClaims.NameIdentifier;\n        private const string TrustedForImpersonationClaimType = \"trustedfordelegation\";\n        private const string ActorTokenClaimType = JsonWebTokenConstants.ReservedClaims.ActorToken;\n\n        //\n        // Environment Constants\n        //\n\n        private static string GlobalEndPointPrefix = \"accounts\";\n        private static string AcsHostUrl = \"accesscontrol.windows.net\";\n\n        //\n        // Hosted add-in configuration\n        //\n        private static readonly string ClientId = string.IsNullOrEmpty(WebConfigurationManager.AppSettings.Get(\"ClientId\")) ? WebConfigurationManager.AppSettings.Get(\"HostedAppName\") : WebConfigurationManager.AppSettings.Get(\"ClientId\");\n        private static readonly string IssuerId = string.IsNullOrEmpty(WebConfigurationManager.AppSettings.Get(\"IssuerId\")) ? ClientId : WebConfigurationManager.AppSettings.Get(\"IssuerId\");\n        private static readonly string HostedAppHostNameOverride = WebConfigurationManager.AppSettings.Get(\"HostedAppHostNameOverride\");\n        private static readonly string HostedAppHostName = WebConfigurationManager.AppSettings.Get(\"HostedAppHostName\");\n        private static readonly string ClientSecret = string.IsNullOrEmpty(WebConfigurationManager.AppSettings.Get(\"ClientSecret\")) ? WebConfigurationManager.AppSettings.Get(\"HostedAppSigningKey\") : WebConfigurationManager.AppSettings.Get(\"ClientSecret\");\n        private static readonly string SecondaryClientSecret = WebConfigurationManager.AppSettings.Get(\"SecondaryClientSecret\");\n        private static readonly string Realm = WebConfigurationManager.AppSettings.Get(\"Realm\");\n        private static readonly string ServiceNamespace = WebConfigurationManager.AppSettings.Get(\"Realm\");\n\n        private static readonly string ClientSigningCertificatePath = WebConfigurationManager.AppSettings.Get(\"ClientSigningCertificatePath\");\n        private static readonly string ClientSigningCertificatePassword = WebConfigurationManager.AppSettings.Get(\"ClientSigningCertificatePassword\");\n        private static readonly X509Certificate2 ClientCertificate = (string.IsNullOrEmpty(ClientSigningCertificatePath) || string.IsNullOrEmpty(ClientSigningCertificatePassword)) ? null : new X509Certificate2(ClientSigningCertificatePath, ClientSigningCertificatePassword);\n        private static readonly X509SigningCredentials SigningCredentials = (ClientCertificate == null) ? null : new X509SigningCredentials(ClientCertificate, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);\n\n        #endregion\n\n        #region private methods\n\n        private static string GetAcsMetadataEndpointUrl()\n        {\n            return Path.Combine(GetAcsGlobalEndpointUrl(), AcsMetadataEndPointRelativeUrl);\n        }\n\n        private static string GetFormattedPrincipal(string principalName, string hostName, string realm)\n        {\n            if (!String.IsNullOrEmpty(hostName))\n            {\n                return String.Format(CultureInfo.InvariantCulture, \"{0}/{1}@{2}\", principalName, hostName, realm);\n            }\n\n            return String.Format(CultureInfo.InvariantCulture, \"{0}@{1}\", principalName, realm);\n        }\n\n        private static string GetAcsPrincipalName(string realm)\n        {\n            return GetFormattedPrincipal(AcsPrincipalName, new Uri(GetAcsGlobalEndpointUrl()).Host, realm);\n        }\n\n        private static string GetAcsGlobalEndpointUrl()\n        {\n            return String.Format(CultureInfo.InvariantCulture, \"https://{0}.{1}/\", GlobalEndPointPrefix, AcsHostUrl);\n        }\n\n        private static JsonWebSecurityTokenHandler CreateJsonWebSecurityTokenHandler()\n        {\n            JsonWebSecurityTokenHandler handler = new JsonWebSecurityTokenHandler();\n            handler.Configuration = new SecurityTokenHandlerConfiguration();\n            handler.Configuration.AudienceRestriction = new AudienceRestriction(AudienceUriMode.Never);\n            handler.Configuration.CertificateValidator = X509CertificateValidator.None;\n\n            List<byte[]> securityKeys = new List<byte[]>();\n            securityKeys.Add(Convert.FromBase64String(ClientSecret));\n            if (!string.IsNullOrEmpty(SecondaryClientSecret))\n            {\n                securityKeys.Add(Convert.FromBase64String(SecondaryClientSecret));\n            }\n\n            List<SecurityToken> securityTokens = new List<SecurityToken>();\n            securityTokens.Add(new MultipleSymmetricKeySecurityToken(securityKeys));\n\n            handler.Configuration.IssuerTokenResolver =\n                SecurityTokenResolver.CreateDefaultSecurityTokenResolver(\n                new ReadOnlyCollection<SecurityToken>(securityTokens),\n                false);\n            SymmetricKeyIssuerNameRegistry issuerNameRegistry = new SymmetricKeyIssuerNameRegistry();\n            foreach (byte[] securitykey in securityKeys)\n            {\n                issuerNameRegistry.AddTrustedIssuer(securitykey, GetAcsPrincipalName(ServiceNamespace));\n            }\n            handler.Configuration.IssuerNameRegistry = issuerNameRegistry;\n            return handler;\n        }\n\n        private static string GetS2SAccessTokenWithClaims(\n            string targetApplicationHostName,\n            string targetRealm,\n            IEnumerable<JsonWebTokenClaim> claims)\n        {\n            return IssueToken(\n                ClientId,\n                IssuerId,\n                targetRealm,\n                SharePointPrincipal,\n                targetRealm,\n                targetApplicationHostName,\n                true,\n                claims,\n                claims == null);\n        }\n\n        private static JsonWebTokenClaim[] GetClaimsWithWindowsIdentity(WindowsIdentity identity)\n        {\n            JsonWebTokenClaim[] claims = new JsonWebTokenClaim[]\n            {\n                new JsonWebTokenClaim(NameIdentifierClaimType, identity.User.Value.ToLower()),\n                new JsonWebTokenClaim(\"nii\", \"urn:office:idp:activedirectory\")\n            };\n            return claims;\n        }\n\n        private static string IssueToken(\n            string sourceApplication,\n            string issuerApplication,\n            string sourceRealm,\n            string targetApplication,\n            string targetRealm,\n            string targetApplicationHostName,\n            bool trustedForDelegation,\n            IEnumerable<JsonWebTokenClaim> claims,\n            bool appOnly = false)\n        {\n            if (null == SigningCredentials)\n            {\n                throw new InvalidOperationException(\"SigningCredentials was not initialized\");\n            }\n\n            #region Actor token\n\n            string issuer = string.IsNullOrEmpty(sourceRealm) ? issuerApplication : string.Format(\"{0}@{1}\", issuerApplication, sourceRealm);\n            string nameid = string.IsNullOrEmpty(sourceRealm) ? sourceApplication : string.Format(\"{0}@{1}\", sourceApplication, sourceRealm);\n            string audience = string.Format(\"{0}/{1}@{2}\", targetApplication, targetApplicationHostName, targetRealm);\n\n            List<JsonWebTokenClaim> actorClaims = new List<JsonWebTokenClaim>();\n            actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, nameid));\n            if (trustedForDelegation && !appOnly)\n            {\n                actorClaims.Add(new JsonWebTokenClaim(TrustedForImpersonationClaimType, \"true\"));\n            }\n\n            // Create token\n            JsonWebSecurityToken actorToken = new JsonWebSecurityToken(\n                issuer: issuer,\n                audience: audience,\n                validFrom: DateTime.UtcNow,\n                validTo: DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),\n                signingCredentials: SigningCredentials,\n                claims: actorClaims);\n\n            string actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken);\n\n            if (appOnly)\n            {\n                // App-only token is the same as actor token for delegated case\n                return actorTokenString;\n            }\n\n            #endregion Actor token\n\n            #region Outer token\n\n            List<JsonWebTokenClaim> outerClaims = null == claims ? new List<JsonWebTokenClaim>() : new List<JsonWebTokenClaim>(claims);\n            outerClaims.Add(new JsonWebTokenClaim(ActorTokenClaimType, actorTokenString));\n\n            JsonWebSecurityToken jsonToken = new JsonWebSecurityToken(\n                nameid, // outer token issuer should match actor token nameid\n                audience,\n                DateTime.UtcNow,\n                DateTime.UtcNow.Add(HighTrustAccessTokenLifetime),\n                outerClaims);\n\n            string accessToken = new JsonWebSecurityTokenHandler().WriteTokenAsString(jsonToken);\n\n            #endregion Outer token\n\n            return accessToken;\n        }\n\n        #endregion\n\n        #region AcsMetadataParser\n\n        // This class is used to get MetaData document from the global STS endpoint. It contains\n        // methods to parse the MetaData document and get endpoints and STS certificate.\n        public static class AcsMetadataParser\n        {\n            public static X509Certificate2 GetAcsSigningCert(string realm)\n            {\n                JsonMetadataDocument document = GetMetadataDocument(realm);\n\n                if (null != document.keys && document.keys.Count > 0)\n                {\n                    JsonKey signingKey = document.keys[0];\n\n                    if (null != signingKey && null != signingKey.keyValue)\n                    {\n                        return new X509Certificate2(Encoding.UTF8.GetBytes(signingKey.keyValue.value));\n                    }\n                }\n\n                throw new Exception(\"Metadata document does not contain ACS signing certificate.\");\n            }\n\n            public static string GetDelegationServiceUrl(string realm)\n            {\n                JsonMetadataDocument document = GetMetadataDocument(realm);\n\n                JsonEndpoint delegationEndpoint = document.endpoints.SingleOrDefault(e => e.protocol == DelegationIssuance);\n\n                if (null != delegationEndpoint)\n                {\n                    return delegationEndpoint.location;\n                }\n                throw new Exception(\"Metadata document does not contain Delegation Service endpoint Url\");\n            }\n\n            private static JsonMetadataDocument GetMetadataDocument(string realm)\n            {\n                string acsMetadataEndpointUrlWithRealm = String.Format(CultureInfo.InvariantCulture, \"{0}?realm={1}\",\n                                                                       GetAcsMetadataEndpointUrl(),\n                                                                       realm);\n                byte[] acsMetadata;\n                using (WebClient webClient = new WebClient())\n                {\n\n                    acsMetadata = webClient.DownloadData(acsMetadataEndpointUrlWithRealm);\n                }\n                string jsonResponseString = Encoding.UTF8.GetString(acsMetadata);\n\n                JavaScriptSerializer serializer = new JavaScriptSerializer();\n                JsonMetadataDocument document = serializer.Deserialize<JsonMetadataDocument>(jsonResponseString);\n\n                if (null == document)\n                {\n                    throw new Exception(\"No metadata document found at the global endpoint \" + acsMetadataEndpointUrlWithRealm);\n                }\n\n                return document;\n            }\n\n            public static string GetStsUrl(string realm)\n            {\n                JsonMetadataDocument document = GetMetadataDocument(realm);\n\n                JsonEndpoint s2sEndpoint = document.endpoints.SingleOrDefault(e => e.protocol == S2SProtocol);\n\n                if (null != s2sEndpoint)\n                {\n                    return s2sEndpoint.location;\n                }\n\n                throw new Exception(\"Metadata document does not contain STS endpoint url\");\n            }\n\n            private class JsonMetadataDocument\n            {\n                public string serviceName { get; set; }\n                public List<JsonEndpoint> endpoints { get; set; }\n                public List<JsonKey> keys { get; set; }\n            }\n\n            private class JsonEndpoint\n            {\n                public string location { get; set; }\n                public string protocol { get; set; }\n                public string usage { get; set; }\n            }\n\n            private class JsonKeyValue\n            {\n                public string type { get; set; }\n                public string value { get; set; }\n            }\n\n            private class JsonKey\n            {\n                public string usage { get; set; }\n                public JsonKeyValue keyValue { get; set; }\n            }\n        }\n\n        #endregion\n    }\n\n    /// <summary>\n    /// A JsonWebSecurityToken generated by SharePoint to authenticate to a 3rd party application and allow callbacks using a refresh token\n    /// </summary>\n    public class SharePointContextToken : JsonWebSecurityToken\n    {\n        public static SharePointContextToken Create(JsonWebSecurityToken contextToken)\n        {\n            return new SharePointContextToken(contextToken.Issuer, contextToken.Audience, contextToken.ValidFrom, contextToken.ValidTo, contextToken.Claims);\n        }\n\n        public SharePointContextToken(string issuer, string audience, DateTime validFrom, DateTime validTo, IEnumerable<JsonWebTokenClaim> claims)\n            : base(issuer, audience, validFrom, validTo, claims)\n        {\n        }\n\n        public SharePointContextToken(string issuer, string audience, DateTime validFrom, DateTime validTo, IEnumerable<JsonWebTokenClaim> claims, SecurityToken issuerToken, JsonWebSecurityToken actorToken)\n            : base(issuer, audience, validFrom, validTo, claims, issuerToken, actorToken)\n        {\n        }\n\n        public SharePointContextToken(string issuer, string audience, DateTime validFrom, DateTime validTo, IEnumerable<JsonWebTokenClaim> claims, SigningCredentials signingCredentials)\n            : base(issuer, audience, validFrom, validTo, claims, signingCredentials)\n        {\n        }\n\n        public string NameId\n        {\n            get\n            {\n                return GetClaimValue(this, \"nameid\");\n            }\n        }\n\n        /// <summary>\n        /// The principal name portion of the context token's \"appctxsender\" claim\n        /// </summary>\n        public string TargetPrincipalName\n        {\n            get\n            {\n                string appctxsender = GetClaimValue(this, \"appctxsender\");\n\n                if (appctxsender == null)\n                {\n                    return null;\n                }\n\n                return appctxsender.Split('@')[0];\n            }\n        }\n\n        /// <summary>\n        /// The context token's \"refreshtoken\" claim\n        /// </summary>\n        public string RefreshToken\n        {\n            get\n            {\n                return GetClaimValue(this, \"refreshtoken\");\n            }\n        }\n\n        /// <summary>\n        /// The realm portion of the context token's \"audience\" claim\n        /// </summary>\n        public string Realm\n        {\n            get\n            {\n                string aud = Audience;\n                if (aud == null)\n                {\n                    return null;\n                }\n\n                string tokenRealm = aud.Substring(aud.IndexOf('@') + 1);\n\n                return tokenRealm;\n            }\n        }\n\n        private static string GetClaimValue(JsonWebSecurityToken token, string claimType)\n        {\n            if (token == null)\n            {\n                throw new ArgumentNullException(\"token\");\n            }\n\n            foreach (JsonWebTokenClaim claim in token.Claims)\n            {\n                if (StringComparer.Ordinal.Equals(claim.ClaimType, claimType))\n                {\n                    return claim.Value;\n                }\n            }\n\n            return null;\n        }\n\n    }\n\n    /// <summary>\n    /// Represents a security token which contains multiple security keys that are generated using symmetric algorithms.\n    /// </summary>\n    public class MultipleSymmetricKeySecurityToken : SecurityToken\n    {\n        /// <summary>\n        /// Initializes a new instance of the MultipleSymmetricKeySecurityToken class.\n        /// </summary>\n        /// <param name=\"keys\">An enumeration of Byte arrays that contain the symmetric keys.</param>\n        public MultipleSymmetricKeySecurityToken(IEnumerable<byte[]> keys)\n            : this(UniqueId.CreateUniqueId(), keys)\n        {\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the MultipleSymmetricKeySecurityToken class.\n        /// </summary>\n        /// <param name=\"tokenId\">The unique identifier of the security token.</param>\n        /// <param name=\"keys\">An enumeration of Byte arrays that contain the symmetric keys.</param>\n        public MultipleSymmetricKeySecurityToken(string tokenId, IEnumerable<byte[]> keys)\n        {\n            if (keys == null)\n            {\n                throw new ArgumentNullException(\"keys\");\n            }\n\n            if (String.IsNullOrEmpty(tokenId))\n            {\n                throw new ArgumentException(\"Value cannot be a null or empty string.\", \"tokenId\");\n            }\n\n            foreach (byte[] key in keys)\n            {\n                if (key.Length <= 0)\n                {\n                    throw new ArgumentException(\"The key length must be greater then zero.\", \"keys\");\n                }\n            }\n\n            id = tokenId;\n            effectiveTime = DateTime.UtcNow;\n            securityKeys = CreateSymmetricSecurityKeys(keys);\n        }\n\n        /// <summary>\n        /// Gets the unique identifier of the security token.\n        /// </summary>\n        public override string Id\n        {\n            get\n            {\n                return id;\n            }\n        }\n\n        /// <summary>\n        /// Gets the cryptographic keys associated with the security token.\n        /// </summary>\n        public override ReadOnlyCollection<SecurityKey> SecurityKeys\n        {\n            get\n            {\n                return securityKeys.AsReadOnly();\n            }\n        }\n\n        /// <summary>\n        /// Gets the first instant in time at which this security token is valid.\n        /// </summary>\n        public override DateTime ValidFrom\n        {\n            get\n            {\n                return effectiveTime;\n            }\n        }\n\n        /// <summary>\n        /// Gets the last instant in time at which this security token is valid.\n        /// </summary>\n        public override DateTime ValidTo\n        {\n            get\n            {\n                // Never expire\n                return DateTime.MaxValue;\n            }\n        }\n\n        /// <summary>\n        /// Returns a value that indicates whether the key identifier for this instance can be resolved to the specified key identifier.\n        /// </summary>\n        /// <param name=\"keyIdentifierClause\">A SecurityKeyIdentifierClause to compare to this instance</param>\n        /// <returns>true if keyIdentifierClause is a SecurityKeyIdentifierClause and it has the same unique identifier as the Id property; otherwise, false.</returns>\n        public override bool MatchesKeyIdentifierClause(SecurityKeyIdentifierClause keyIdentifierClause)\n        {\n            if (keyIdentifierClause == null)\n            {\n                throw new ArgumentNullException(\"keyIdentifierClause\");\n            }\n\n            // Since this is a symmetric token and we do not have IDs to distinguish tokens, we just check for the\n            // presence of a SymmetricIssuerKeyIdentifier. The actual mapping to the issuer takes place later\n            // when the key is matched to the issuer.\n            if (keyIdentifierClause is SymmetricIssuerKeyIdentifierClause)\n            {\n                return true;\n            }\n            return base.MatchesKeyIdentifierClause(keyIdentifierClause);\n        }\n\n        #region private members\n\n        private List<SecurityKey> CreateSymmetricSecurityKeys(IEnumerable<byte[]> keys)\n        {\n            List<SecurityKey> symmetricKeys = new List<SecurityKey>();\n            foreach (byte[] key in keys)\n            {\n                symmetricKeys.Add(new InMemorySymmetricSecurityKey(key));\n            }\n            return symmetricKeys;\n        }\n\n        private string id;\n        private DateTime effectiveTime;\n        private List<SecurityKey> securityKeys;\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Utilities.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Net;\nusing System.Security.Cryptography;\nusing System.Text;\nusing System.Threading.Tasks;\nusing CredentialManagement;\nusing KeePassLib;\nusing KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\nusing KoenZomers.OneDrive.Api;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    /// <summary>\n    /// Utilities for the KeePass plugin\n    /// </summary>\n    public static class Utilities\n    {\n        #region File Hashes\n\n        /// <summary>\n        /// Calculates the SHA1 file hash of the provided KeePass database\n        /// </summary>\n        /// <param name=\"localKeePassDatabasePath\">Full path to where the KeePass database resides locally</param>\n        /// <returns>SHA1 file hash</returns>\n        public static string GetDatabaseFileHash(string localKeePassDatabasePath)\n        {\n            using (var fileStream = new FileStream(localKeePassDatabasePath, FileMode.Open))\n            {\n                using (var cryptoProvider = new SHA1CryptoServiceProvider())\n                {\n                    var hash = BitConverter.ToString(cryptoProvider.ComputeHash(fileStream)).Replace(\"-\", string.Empty);\n                    return hash;\n                }\n            }\n        }\n\n        #endregion\n\n        #region OneDrive\n\n        /// <summary>\n        /// Returns an active OneDriveApi instance. If a RefreshToken is available, it will set up an instance based on that, otherwise it will show the login dialog\n        /// </summary>\n        /// <param name=\"databaseConfig\">Configuration of the KeePass database</param>\n        /// <returns>Active OneDrive instance or NULL if unable to get an authenticated instance</returns>\n        public static async Task<OneDriveApi> GetOneDriveApi(Configuration databaseConfig)\n        {\n            OneDriveApi cloudStorage;\n\n            switch (databaseConfig.CloudStorageType.GetValueOrDefault(CloudStorageType.OneDriveConsumer))\n            {\n                case CloudStorageType.OneDriveConsumer:\n                    cloudStorage = new OneDriveConsumerApi(KoenZomersKeePassOneDriveSyncExt.OneDriveConsumerClientId, KoenZomersKeePassOneDriveSyncExt.OneDriveConsumerClientSecret);\n                    break;\n\n                case CloudStorageType.MicrosoftGraph:\n                case CloudStorageType.MicrosoftGraphDeviceLogin:\n                    cloudStorage = new OneDriveGraphApi(KoenZomersKeePassOneDriveSyncExt.GraphApiApplicationId);\n                    break;\n\n                default:\n                    throw new ArgumentOutOfRangeException(string.Format(\"Cloud storage type {0} is not supported\", databaseConfig.CloudStorageType));\n            }\n\n            // Ensure we have a refresh token\n            if (string.IsNullOrEmpty(databaseConfig.RefreshToken))\n            {\n                // No refresh token available, perform the login process\n                if (databaseConfig.CloudStorageType.GetValueOrDefault(CloudStorageType.OneDriveConsumer) == CloudStorageType.MicrosoftGraphDeviceLogin)\n                {\n                    // Using Microsoft Graph Device ID Code Flow\n                    var oneDriveGraphDeviceLoginForm = new OneDriveGraphDeviceLoginForm(cloudStorage);\n                    var deviceLoginResult = oneDriveGraphDeviceLoginForm.ShowDialog();\n\n                    if (deviceLoginResult != System.Windows.Forms.DialogResult.OK)\n                    {\n                        return null;\n                    }\n\n                    // Save the configuration so we keep the Refresh Token\n                    databaseConfig.RefreshToken = oneDriveGraphDeviceLoginForm.RefreshToken;\n                    Configuration.Save();\n                }\n                else\n                {\n                    // Using any of the other authentication options\n                    var oneDriveAuthenticateForm = new OneDriveAuthenticateForm(cloudStorage);\n                    var result = oneDriveAuthenticateForm.ShowDialog();\n\n                    if (result != System.Windows.Forms.DialogResult.OK)\n                    {\n                        return null;\n                    }\n\n                    // Check if we already know where to store the Refresh Token for this database\n                    if (!databaseConfig.RefreshTokenStorage.HasValue)\n                    {\n                        // We don't know yet where the Refresh Token for this database should be stored, ask the user to choose\n                        var oneDriveRefreshTokenStorageForm = new OneDriveRefreshTokenStorageDialog(databaseConfig);\n                        oneDriveRefreshTokenStorageForm.ShowDialog();\n                    }\n\n                    // Save the configuration so we keep the Refresh Token\n                    var oneDriveApi = oneDriveAuthenticateForm.OneDriveApi;\n                    databaseConfig.RefreshToken = oneDriveApi.AccessToken.RefreshToken;\n\n                    Configuration.Save();\n\n                    return oneDriveApi;\n                }\n            }\n\n            try\n            {\n                ApplyProxySettings(cloudStorage);\n                await cloudStorage.AuthenticateUsingRefreshToken(databaseConfig.RefreshToken);\n                return cloudStorage;\n            }\n            catch (KoenZomers.OneDrive.Api.Exceptions.TokenRetrievalFailedException)\n            {\n                // Something went wrong with retrieving the access token\n                throw;\n            }\n            catch (Exception e)\n            {\n                // If specifically the HttpRequestException occurred, it likely contains more information on what went wrong, so pass it up to the callstack\n                if (e.GetType().ToString() == \"System.Net.Http.HttpRequestException\")\n                {\n                    throw;\n                }\n                // Occurs if no connection can be made with the OneDrive service. It will be handled properly in the calling code.\n                return null;\n            }\n        }\n\n        #endregion\n\n        #region Proxy Support\n\n        /// <summary>\n        /// Gets correct web proxy settings based on KeePass proxy configuration\n        /// </summary>\n        /// <returns>IWebProxy conforming instance with the proper proxy configuraton</returns>\n        public static IWebProxy GetProxySettings()\n        {\n            IWebProxy webProxy = null;\n\n            // Create the WebProxy object based on KeePass configuration\n            switch (KeePass.Program.Config.Integration.ProxyType)\n            {\n                case ProxyServerType.None:\n                    webProxy = null;\n                    break;\n\n                case ProxyServerType.Manual:\n                    webProxy = new WebProxy(string.Concat(KeePass.Program.Config.Integration.ProxyAddress, \":\", KeePass.Program.Config.Integration.ProxyPort));\n                    break;\n\n                case ProxyServerType.System:\n                    webProxy = WebRequest.DefaultWebProxy;\n                    break;\n            }\n\n            return webProxy;\n        }\n\n        /// <summary>\n        /// Gets correct web proxy credentials based on KeePass proxy configuration\n        /// </summary>\n        /// <returns>NetworkCredential instance with the proper proxy credentials</returns>\n        public static NetworkCredential GetProxyCredentials()\n        {\n            var networkCredential = KeePass.Program.Config.Integration.ProxyAuthType == ProxyAuthType.Manual ? new NetworkCredential(KeePass.Program.Config.Integration.ProxyUserName, KeePass.Program.Config.Integration.ProxyPassword) : null;\n            return networkCredential;\n        }\n\n        /// <summary>\n        /// Applies the correct web proxy settings to the provided OneDriveApi instance based on KeePass proxy configuration\n        /// </summary>\n        /// <param name=\"oneDriveApi\">OneDriveApi instance to apply the proper proxy settings to</param>\n        public static void ApplyProxySettings(OneDriveApi oneDriveApi)\n        {\n            // Set the WebProxy to use\n            oneDriveApi.ProxyConfiguration = GetProxySettings();\n\n            // Configure the credentials to use for the proxy\n            oneDriveApi.ProxyCredential = GetProxyCredentials();\n        }\n\n        #endregion\n\n        #region Windows Credential Manager\n\n        /// <summary>\n        /// Saves the provided OneDrive Refresh Token in the Windows Credential Manager\n        /// </summary>\n        /// <param name=\"databaseFilePath\">Full local path to the KeePass database for which to save the OneDrive Refresh Token</param>\n        /// <param name=\"refreshToken\">The OneDrive Refresh Token to store securely in the Windows Credential Manager</param>\n        public static void SaveRefreshTokenInWindowsCredentialManager(string databaseFilePath, string refreshToken)\n        {\n            // Some refresh tokens can be longer than the maximum permitted 512 characters for a password field. If this is the case, put the first 512 characters of the refresh token in the password field and the rest in the comments field. Also the comments field has a limit. So far I have not run into this limit yet.\n            string passwordPart1;\n            string passwordPart2;\n\n            if (refreshToken != null && refreshToken.Length > 512)\n            {\n                passwordPart1 = refreshToken.Remove(512);\n                passwordPart2 = refreshToken.Remove(0, 512);\n            }\n            else\n            {\n                passwordPart1 = refreshToken;\n                passwordPart2 = string.Empty;\n            }\n\n            using (var saved = new Credential(databaseFilePath, passwordPart1, string.Concat(\"KoenZomers.KeePass.OneDriveSync:\", databaseFilePath), CredentialType.Generic) {PersistanceType = PersistanceType.LocalComputer})\n            {\n                saved.Description = passwordPart2;\n                saved.Save();\n            }\n        }\n\n        /// <summary>\n        /// Retrieves a OneDrive Refresh Token from the Windows Credential Manager\n        /// </summary>\n        /// <param name=\"databaseFilePath\">Full local path to the KeePass database for which to retrieve the OneDrive Refresh Token</param>\n        /// <returns>OneDrive Refresh Token if available or NULL if no Refresh Token found for the provided database</returns>\n        public static string GetRefreshTokenFromWindowsCredentialManager(string databaseFilePath)\n        {\n            using (var credential = new Credential {Target = string.Concat(\"KoenZomers.KeePass.OneDriveSync:\", databaseFilePath), Type = CredentialType.Generic})\n            {\n                credential.Load();\n\n                // Concatenate the contents of the password and comments fields to retrieve the refresh token\n                return credential.Exists() ? credential.Password + (!string.IsNullOrEmpty(credential.Description) ? credential.Description : string.Empty) + (!string.IsNullOrEmpty(credential.Target) ? credential.Target : string.Empty) : null;\n            }\n        }\n\n        /// <summary>\n        /// Deletes a OneDrive Refresh Token from the Windows Credential Manager\n        /// </summary>\n        /// <param name=\"databaseFilePath\">Full local path to the KeePass database for which to delete the OneDrive Refresh Token</param>\n        public static void DeleteRefreshTokenFromWindowsCredentialManager(string databaseFilePath)\n        {\n            using (var credential = new Credential {Target = string.Concat(\"KoenZomers.KeePass.OneDriveSync:\", databaseFilePath), Type = CredentialType.Generic})\n            {\n                // Verify if we have stored a token for this database\n                if (credential.Exists())\n                {\n                    // Delete the Windows Credential Manager entry\n                    credential.Delete();\n                }\n            }\n        }\n\n        #endregion\n\n        #region KeePass Database Storage\n\n        /// <summary>\n        /// Saves the provided OneDrive Refresh Token in the provided KeePass database\n        /// </summary>\n        /// <param name=\"keePassDatabase\">KeePass database instance to store the Refresh Token in</param>\n        /// <param name=\"refreshToken\">The OneDrive Refresh Token to store securely in the KeePass database</param>\n        public static void SaveRefreshTokenInKeePassDatabase(PwDatabase keePassDatabase, string refreshToken)\n        {\n            keePassDatabase.CustomData.Set(\"KoenZomers.KeePass.OneDriveSync.RefreshToken\", refreshToken);\n        }\n\n        /// <summary>\n        /// Retrieves a OneDrive Refresh Token from the provided KeePass database\n        /// </summary>\n        /// <param name=\"keePassDatabase\">KeePass database instance to get the Refresh Token from</param>\n        /// <returns>OneDrive Refresh Token if available or NULL if no Refresh Token found for the provided database</returns>\n        public static string GetRefreshTokenFromKeePassDatabase(PwDatabase keePassDatabase)\n        {\n            var refreshToken = keePassDatabase.CustomData.Get(\"KoenZomers.KeePass.OneDriveSync.RefreshToken\");\n            return refreshToken;\n        }\n\n        #endregion\n\n        #region DPAPI\n\n        /// <summary>\n        /// Encrypts a Refresh Token using the DPAPI Protect method with current user scope\n        /// </summary>\n        /// <param name=\"refreshToken\">The Refresh Token to encrypt</param>\n        /// <returns>The Base64-encoded encrypted refresh token or NULL if encryption fails</returns>\n        public static string Protect(string refreshToken)\n        {\n            // Token should be plain ASCII text, get raw byte data for encoding\n            var rawToken = Encoding.ASCII.GetBytes(refreshToken);\n\n            try\n            {\n                // Encrypt using DPAPI with user scope, can only be decrypted by currently logged-in user\n                var rawEncryptedToken = ProtectedData.Protect(rawToken, null, DataProtectionScope.CurrentUser);\n\n                // Base64-encode encrypted token for JSON string compatibility\n                var encryptedToken = Convert.ToBase64String(rawEncryptedToken);\n\n                return encryptedToken;\n            }\n            catch (Exception)\n            {\n                // If encryption fails, lose the token\n                return null;\n            }\n        }\n\n        /// <summary>\n        /// Decrypt a Refresh Token using the DPAPI Protect method with current user scope\n        /// </summary>\n        /// <param name=\"encryptedRefreshToken\">The encrypted Refresh Token to decrypt, Base64-encoded</param>\n        /// <returns>The decrypted refresh token or NULL if decryption fails</returns>\n        public static string Unprotect(string encryptedRefreshToken)\n        {\n            // Decode Base64-encoded encrypted data\n            var rawEncryptedToken = Convert.FromBase64String(encryptedRefreshToken);\n\n            try\n            {\n                // Decrypt using DPAPI with user scope, only possible if the currently logged-in user is the same as the one who encrypted it\n                var rawToken = ProtectedData.Unprotect(rawEncryptedToken, null, DataProtectionScope.CurrentUser);\n\n                // Get string data from byte array\n                var token = Encoding.ASCII.GetString(rawToken);\n\n                return token;\n            }\n            catch (Exception)\n            {\n                // If decryption fails, lose the token\n                return null;\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-12.0.0.0\" newVersion=\"12.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"KoenZomers.OneDrive.Api\" version=\"2.3.0.3\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.Identity.Model.Extensions\" version=\"2.0.1459.0\" targetFramework=\"net452\" />\n  <package id=\"Microsoft.IdentityModel\" version=\"6.1.7600.16394\" targetFramework=\"net452\" />\n  <package id=\"Newtonsoft.Json\" version=\"8.0.1\" targetFramework=\"net452\" />\n</packages>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.0.31903.59\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"KoenZomers.KeePass.OneDriveSync\", \"KoenZomers.KeePass.OneDriveSync\\KoenZomers.KeePass.OneDriveSync.csproj\", \"{ED981431-32EA-4FC8-BF5B-D5A29B3AD52E}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Libraries\", \"Libraries\", \"{078F6134-F1AF-4F2A-907F-C8AC4C976834}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tKoenZomers.KeePass.OneDriveSync\\CredentialManagement.dll = KoenZomers.KeePass.OneDriveSync\\CredentialManagement.dll\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{C51FE94D-1D06-497B-97AA-5B80030F6E7A}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tcreate-plgx.cmd = create-plgx.cmd\n\t\tNuGet.config = NuGet.config\n\t\tversion.txt = version.txt\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Screenshots\", \"Screenshots\", \"{1985E673-364B-4E4F-9DF4-7F110239AEB0}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tScreenshots\\AuthenticateToOneDrive.png = Screenshots\\AuthenticateToOneDrive.png\n\t\tScreenshots\\ChooseCloudStorage.png = Screenshots\\ChooseCloudStorage.png\n\t\tScreenshots\\ConfigurationDetails.png = Screenshots\\ConfigurationDetails.png\n\t\tScreenshots\\ConfigurationsContextMenu.png = Screenshots\\ConfigurationsContextMenu.png\n\t\tScreenshots\\ConfigurationsOverview.png = Screenshots\\ConfigurationsOverview.png\n\t\tScreenshots\\CredentialManagerControlPanel.png = Screenshots\\CredentialManagerControlPanel.png\n\t\tScreenshots\\KeePassCheckForUpdates.png = Screenshots\\KeePassCheckForUpdates.png\n\t\tScreenshots\\KeePassOneDriveSyncConfigurationOptions.png = Screenshots\\KeePassOneDriveSyncConfigurationOptions.png\n\t\tScreenshots\\KeePassOneDriveSyncOptions.png = Screenshots\\KeePassOneDriveSyncOptions.png\n\t\tScreenshots\\KeePassPluginUpToDate.png = Screenshots\\KeePassPluginUpToDate.png\n\t\tScreenshots\\KeePassProxyOptions.png = Screenshots\\KeePassProxyOptions.png\n\t\tScreenshots\\KeePasstoolsPlugins.png = Screenshots\\KeePasstoolsPlugins.png\n\t\tScreenshots\\KeePassVerifyPluginPresent.png = Screenshots\\KeePassVerifyPluginPresent.png\n\t\tScreenshots\\OfflineMode.png = Screenshots\\OfflineMode.png\n\t\tScreenshots\\OneDriveConsentToPriviledges.png = Screenshots\\OneDriveConsentToPriviledges.png\n\t\tScreenshots\\OneDriveDatabaseUploaded.png = Screenshots\\OneDriveDatabaseUploaded.png\n\t\tScreenshots\\OneDriveSelectLocation.png = Screenshots\\OneDriveSelectLocation.png\n\t\tScreenshots\\OneDriveTwoFactorAuthentication.png = Screenshots\\OneDriveTwoFactorAuthentication.png\n\t\tScreenshots\\StartSyncing.png = Screenshots\\StartSyncing.png\n\t\tScreenshots\\WhereToStoreOneDriveToken.png = Screenshots\\WhereToStoreOneDriveToken.png\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Documentation\", \"Documentation\", \"{C681B3E0-217B-497C-A067-12FE1CC6DE69}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tREADME.md = README.md\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{ED981431-32EA-4FC8-BF5B-D5A29B3AD52E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{ED981431-32EA-4FC8-BF5B-D5A29B3AD52E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{ED981431-32EA-4FC8-BF5B-D5A29B3AD52E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{ED981431-32EA-4FC8-BF5B-D5A29B3AD52E}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {508E11B0-378C-44C7-B479-337C56E78BBB}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Eclipse Public License - v 1.0\n\nTHE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC\nLICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM\nCONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\na) in the case of the initial Contributor, the initial code and documentation\n   distributed under this Agreement, and\nb) in the case of each subsequent Contributor:\n    i) changes to the Program, and\n   ii) additions to the Program;\n\n   where such changes and/or additions to the Program originate from and are\n   distributed by that particular Contributor. A Contribution 'originates'\n   from a Contributor if it was added to the Program by such Contributor\n   itself or anyone acting on such Contributor's behalf. Contributions do not\n   include additions to the Program which: (i) are separate modules of\n   software distributed in conjunction with the Program under their own\n   license agreement, and (ii) are not derivative works of the Program.\n\n\"Contributor\" means any person or entity that distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which are\nnecessarily infringed by the use or sale of its Contribution alone or when\ncombined with the Program.\n\n\"Program\" means the Contributions distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement,\nincluding all Contributors.\n\n2. GRANT OF RIGHTS\n  a) Subject to the terms of this Agreement, each Contributor hereby grants\n     Recipient a non-exclusive, worldwide, royalty-free copyright license to\n     reproduce, prepare derivative works of, publicly display, publicly\n     perform, distribute and sublicense the Contribution of such Contributor,\n     if any, and such derivative works, in source code and object code form.\n  b) Subject to the terms of this Agreement, each Contributor hereby grants\n     Recipient a non-exclusive, worldwide, royalty-free patent license under\n     Licensed Patents to make, use, sell, offer to sell, import and otherwise\n     transfer the Contribution of such Contributor, if any, in source code and\n     object code form. This patent license shall apply to the combination of\n     the Contribution and the Program if, at the time the Contribution is\n     added by the Contributor, such addition of the Contribution causes such\n     combination to be covered by the Licensed Patents. The patent license\n     shall not apply to any other combinations which include the Contribution.\n     No hardware per se is licensed hereunder.\n  c) Recipient understands that although each Contributor grants the licenses\n     to its Contributions set forth herein, no assurances are provided by any\n     Contributor that the Program does not infringe the patent or other\n     intellectual property rights of any other entity. Each Contributor\n     disclaims any liability to Recipient for claims brought by any other\n     entity based on infringement of intellectual property rights or\n     otherwise. As a condition to exercising the rights and licenses granted\n     hereunder, each Recipient hereby assumes sole responsibility to secure\n     any other intellectual property rights needed, if any. For example, if a\n     third party patent license is required to allow Recipient to distribute\n     the Program, it is Recipient's responsibility to acquire that license\n     before distributing the Program.\n  d) Each Contributor represents that to its knowledge it has sufficient\n     copyright rights in its Contribution, if any, to grant the copyright\n     license set forth in this Agreement.\n\n3. REQUIREMENTS\n\nA Contributor may choose to distribute the Program in object code form under\nits own license agreement, provided that:\n\n  a) it complies with the terms and conditions of this Agreement; and\n  b) its license agreement:\n      i) effectively disclaims on behalf of all Contributors all warranties\n         and conditions, express and implied, including warranties or\n         conditions of title and non-infringement, and implied warranties or\n         conditions of merchantability and fitness for a particular purpose;\n     ii) effectively excludes on behalf of all Contributors all liability for\n         damages, including direct, indirect, special, incidental and\n         consequential damages, such as lost profits;\n    iii) states that any provisions which differ from this Agreement are\n         offered by that Contributor alone and not by any other party; and\n     iv) states that source code for the Program is available from such\n         Contributor, and informs licensees how to obtain it in a reasonable\n         manner on or through a medium customarily used for software exchange.\n\nWhen the Program is made available in source code form:\n\n  a) it must be made available under this Agreement; and\n  b) a copy of this Agreement must be included with each copy of the Program.\n     Contributors may not remove or alter any copyright notices contained\n     within the Program.\n\nEach Contributor must identify itself as the originator of its Contribution,\nif\nany, in a manner that reasonably allows subsequent Recipients to identify the\noriginator of the Contribution.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities with\nrespect to end users, business partners and the like. While this license is\nintended to facilitate the commercial use of the Program, the Contributor who\nincludes the Program in a commercial product offering should do so in a manner\nwhich does not create potential liability for other Contributors. Therefore,\nif a Contributor includes the Program in a commercial product offering, such\nContributor (\"Commercial Contributor\") hereby agrees to defend and indemnify\nevery other Contributor (\"Indemnified Contributor\") against any losses,\ndamages and costs (collectively \"Losses\") arising from claims, lawsuits and\nother legal actions brought by a third party against the Indemnified\nContributor to the extent caused by the acts or omissions of such Commercial\nContributor in connection with its distribution of the Program in a commercial\nproduct offering. The obligations in this section do not apply to any claims\nor Losses relating to any actual or alleged intellectual property\ninfringement. In order to qualify, an Indemnified Contributor must:\na) promptly notify the Commercial Contributor in writing of such claim, and\nb) allow the Commercial Contributor to control, and cooperate with the\nCommercial Contributor in, the defense and any related settlement\nnegotiations. The Indemnified Contributor may participate in any such claim at\nits own expense.\n\nFor example, a Contributor might include the Program in a commercial product\noffering, Product X. That Contributor is then a Commercial Contributor. If\nthat Commercial Contributor then makes performance claims, or offers\nwarranties related to Product X, those performance claims and warranties are\nsuch Commercial Contributor's responsibility alone. Under this section, the\nCommercial Contributor would have to defend claims against the other\nContributors related to those performance claims and warranties, and if a\ncourt requires any other Contributor to pay any damages as a result, the\nCommercial Contributor must pay those damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN\n\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR\nIMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each\nRecipient is solely responsible for determining the appropriateness of using\nand distributing the Program and assumes all risks associated with its\nexercise of rights under this Agreement , including but not limited to the\nrisks and costs of program errors, compliance with applicable laws, damage to\nor loss of data, programs or equipment, and unavailability or interruption of\noperations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY\nCONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION\nLOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY\nOF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of the\nremainder of the terms of this Agreement, and without further action by the\nparties hereto, such provision shall be reformed to the minimum extent\nnecessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Program itself\n(excluding combinations of the Program with other software or hardware)\ninfringes such Recipient's patent(s), then such Recipient's rights granted\nunder Section 2(b) shall terminate as of the date such litigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it fails to\ncomply with any of the material terms or conditions of this Agreement and does\nnot cure such failure in a reasonable period of time after becoming aware of\nsuch noncompliance. If all Recipient's rights under this Agreement terminate,\nRecipient agrees to cease use and distribution of the Program as soon as\nreasonably practicable. However, Recipient's obligations under this Agreement\nand any licenses granted by Recipient relating to the Program shall continue\nand survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement, but in\norder to avoid inconsistency the Agreement is copyrighted and may only be\nmodified in the following manner. The Agreement Steward reserves the right to\npublish new versions (including revisions) of this Agreement from time to\ntime. No one other than the Agreement Steward has the right to modify this\nAgreement. The Eclipse Foundation is the initial Agreement Steward. The\nEclipse Foundation may assign the responsibility to serve as the Agreement\nSteward to a suitable separate entity. Each new version of the Agreement will\nbe given a distinguishing version number. The Program (including\nContributions) may always be distributed subject to the version of the\nAgreement under which it was received. In addition, after a new version of the\nAgreement is published, Contributor may elect to distribute the Program\n(including its Contributions) under the new version. Except as expressly\nstated in Sections 2(a) and 2(b) above, Recipient receives no rights or\nlicenses to the intellectual property of any Contributor under this Agreement,\nwhether expressly, by implication, estoppel or otherwise. All rights in the\nProgram not expressly granted under this Agreement are reserved.\n\nThis Agreement is governed by the laws of the State of New York and the\nintellectual property laws of the United States of America. No party to this\nAgreement will bring a legal action under this Agreement more than one year\nafter the cause of action arose. Each party waives its rights to a jury trial in\nany resulting litigation.\n"
  },
  {
    "path": "NuGet.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <config>\n    <add key=\"repositoryPath\" value=\"./KoenZomers.KeePass.OneDriveSync/Packages/\" />\n  </config>\n</configuration>"
  },
  {
    "path": "README.md",
    "content": "# KeePass OneDrive Sync\n\n> Notice: Through the years I have enjoyed building and maintaining this code. I have been surprised to see how many people started using this plugin and how often around the globe I met people that asked me if I was the person behind the plugin. Time however is scarse and as much as I would like to, I'm having too many projects to work on in my spare time, so I need to get rid of some, this unfortunately being one. I will therefore no longer maintain this code. Feel free to fork off of it and make your own version out of it. I'll be happy to link to it.\n\n![](https://github.com/KoenZomers/KeePassOneDriveSync/workflows/.NET%20Core/badge.svg) ![](https://img.shields.io/github/downloads/koenzomers/KeePassOneDriveSync/total.svg) ![](https://img.shields.io/github/issues/koenzomers/KeePassOneDriveSync.svg) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)\n\nA free plugin for KeePass (installable and portable) that allows syncing of multiple password databases from multiple OneDrives to a local version. It allows you to synchronize an unlimited amount of KeePass databases with an unlimited amount of OneDrives. So i.e. you can synchronize your personal KeePass database with your personal OneDrive and your work related KeePass with a OneDrive for Business on Office 365 that is shared among your colleagues, if you wish. This way it's also easy to be able to access your same KeePass database from all of your devices. Note that this plugin is only supported on Windows based platforms, but [has been reported to work on \\*nix as well using Mono](https://github.com/KoenZomers/KeePassOneDriveSync/wiki/System-Requirements#nix-through-mono). It can also operate in conjunction with other KeePass plugins serving other operating systems such as KeePass2Android on Android devices.\n\n## Download ##\nDownload the PLGX and place it inside your KeePass\\Plugins folder. Typically this will be `C:\\Program Files (x86)\\KeePass Password Safe 2\\Plugins` or if you're using KeePass Portable, put it in a subfolder called Plugins from where your keepass.exe is located. When upgrading from a previous version of this plugin, simply ensure KeePass is closed, overwrite the existing PLGX and start KeePass again.\n\n[You can find the latest stable version here](../../releases/latest)\n\n## Documentation ##\n- [System requirements](https://github.com/KoenZomers/KeePassOneDriveSync/wiki/System-Requirements)\n- [Installation instructions](https://github.com/KoenZomers/KeePassOneDriveSync/wiki/Installation-instructions)\n- [Configuration options](https://github.com/KoenZomers/KeePassOneDriveSync/wiki/Configuration-options)\n- [Checking for updates](https://github.com/KoenZomers/KeePassOneDriveSync/wiki/Update-check)\n- [Troubleshooting](https://github.com/KoenZomers/KeePassOneDriveSync/wiki/Troubleshooting)\n- [Frequently Asked Questions](https://github.com/KoenZomers/KeePassOneDriveSync/wiki/FAQ)\n\n## Latest Version\n\nVersion 2.1.2.2 - November 24, 2021\n\n- Fixed the issue where the plugin cannot check for an update [#151](https://github.com/KoenZomers/KeePassOneDriveSync/issues/151)\n\nVersion 2.1.2.1 - May 22, 2020\n\n- Bugfix causing opening of the KeePassOneDriveSync about dialog to crash KeePass. Thanks to Drew O'Hara for letting me know!\n\nVersion 2.1.2.0 - May 22, 2020\n\n- Fixed a bug where uploading a KeePass database to a document library on SharePoint having \"Require documents to be checked out before they can be edited?\" set to Yes would never make the KeePass database show up in SharePoint [issue 131](https://github.com/KoenZomers/KeePassOneDriveSync/issues/131)\n- Updated the SharePoint connector so that it now makes use of versioning in the SharePoint document library allowing you to see in SharePoint when it was updated and allowing you to revert to previous versions of the KeePass database just like already was the case when storing the KeePass database on OneDrive for Business\n- Removed OneDrive option in the cloud storage providers as there really should not be a reason anymore to use it instead of the Microsoft Graph options on the first tab\n- Removed the wording Microsoft Graph on the first tab of the cloud storage providers as I noticed it is confusing for many people. Named them OneDrive & OneDrive for Business instead. Technically, they're still using the Microsoft Graph to connect to OneDrive, so it's just a visual change.\n- Fixed a small issue when refreshing the SharePoint location picker or enabling/disabling showing of hidden libraries not entirely working well\n- Changed that in the OneDrive and SharePoint file pickers, if an item in the folder has the same name as shown in the filename textbox, that it will get selected by default to make it clearer that it already exists in that folder\n- Added tooltips for files and folders in the SharePoint file picker to show additional information on these items when hovering over them such as creation date/time, last modified date/time, file size and file version number\n- Updated links pointing to the GitHub documentation to the new GitHub Wiki location\n\n[Full version history](https://github.com/KoenZomers/KeePassOneDriveSync/releases)\n\n## Special Thanks\n\nSpecial thanks to Oleksandr Senyuk for making [KeeSkyDrive](http://sourceforge.net/projects/keeskydrive/) as it has inspired me to create this plugin.\n"
  },
  {
    "path": "create-plgx.cmd",
    "content": "ECHO Creating KeePass plugin package\nset PLUGIN_NAME=KeeOneDriveSync\nset SourceFolder=KoenZomers.KeePass.OneDriveSync\nrd /s /q %~dp0%SourceFolder%\\obj %~dp0%SourceFolder%\\bin\ndel %~dp0%PLUGIN_NAME%.plgx\n\"C:\\Program Files\\KeePass Password Safe 2\\KeePass.exe\" --plgx-create %~dp0%SourceFolder% --plgx-prereq-net:4.0\nren %~dp0%SourceFolder%.plgx %PLUGIN_NAME%.plgx\nECHO KeePass Plugin package has been created"
  },
  {
    "path": "version.txt",
    "content": ":\nKoenZomers.KeePass.OneDriveSync:2.1.2.2\n:"
  }
]