airdcpp-webui 2.13.1-beta.9 → 2.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.html +1 -1
- package/dist/js/223.3c648d224ecdf7df15cb.chunk.js +2 -0
- package/dist/js/223.3c648d224ecdf7df15cb.chunk.js.gz +0 -0
- package/dist/js/223.3c648d224ecdf7df15cb.chunk.js.map +1 -0
- package/dist/js/{filelists.913207a5f957082c811d.chunk.js → filelists.005c956eabdbb3869c6f.chunk.js} +2 -2
- package/dist/js/filelists.005c956eabdbb3869c6f.chunk.js.gz +0 -0
- package/dist/js/filelists.005c956eabdbb3869c6f.chunk.js.map +1 -0
- package/dist/js/hubs.29f2e7fde513aa2aa81a.chunk.js +2 -0
- package/dist/js/hubs.29f2e7fde513aa2aa81a.chunk.js.gz +0 -0
- package/dist/js/hubs.29f2e7fde513aa2aa81a.chunk.js.map +1 -0
- package/dist/js/{main.1408811d6831f662f421.entry.js → main.e2f715744e80ce3a09aa.entry.js} +3 -3
- package/dist/js/main.e2f715744e80ce3a09aa.entry.js.gz +0 -0
- package/dist/js/{main.1408811d6831f662f421.entry.js.map → main.e2f715744e80ce3a09aa.entry.js.map} +1 -1
- package/dist/js/{queue.4095b1ea967e164737e6.chunk.js → queue.493c6d72a2e6d66362a3.chunk.js} +2 -2
- package/dist/js/queue.493c6d72a2e6d66362a3.chunk.js.gz +0 -0
- package/dist/js/queue.493c6d72a2e6d66362a3.chunk.js.map +1 -0
- package/dist/js/settings.ae1be9e0a1c99eed7597.chunk.js +2 -0
- package/dist/js/settings.ae1be9e0a1c99eed7597.chunk.js.gz +0 -0
- package/dist/js/settings.ae1be9e0a1c99eed7597.chunk.js.map +1 -0
- package/dist/sw.js +1 -1
- package/dist/sw.js.gz +0 -0
- package/package.json +1 -1
- package/dist/js/223.e1724bcbb15b37be3e66.chunk.js +0 -2
- package/dist/js/223.e1724bcbb15b37be3e66.chunk.js.gz +0 -0
- package/dist/js/223.e1724bcbb15b37be3e66.chunk.js.map +0 -1
- package/dist/js/filelists.913207a5f957082c811d.chunk.js.gz +0 -0
- package/dist/js/filelists.913207a5f957082c811d.chunk.js.map +0 -1
- package/dist/js/hubs.b1afb9f790924d60d294.chunk.js +0 -2
- package/dist/js/hubs.b1afb9f790924d60d294.chunk.js.gz +0 -0
- package/dist/js/hubs.b1afb9f790924d60d294.chunk.js.map +0 -1
- package/dist/js/main.1408811d6831f662f421.entry.js.gz +0 -0
- package/dist/js/queue.4095b1ea967e164737e6.chunk.js.gz +0 -0
- package/dist/js/queue.4095b1ea967e164737e6.chunk.js.map +0 -1
- package/dist/js/settings.1287a0ef1d611a34ea1c.chunk.js +0 -2
- package/dist/js/settings.1287a0ef1d611a34ea1c.chunk.js.gz +0 -0
- package/dist/js/settings.1287a0ef1d611a34ea1c.chunk.js.map +0 -1
- /package/dist/js/{main.1408811d6831f662f421.entry.js.LICENSE.txt → main.e2f715744e80ce3a09aa.entry.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"js/settings.ae1be9e0a1c99eed7597.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./node_modules/compare-versions/lib/esm/utils.js","webpack://airdcpp-webui/./node_modules/compare-versions/lib/esm/compareVersions.js","webpack://airdcpp-webui/./node_modules/fomantic-ui-css/components/item.min.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/System/style.css","webpack://airdcpp-webui/./src/routes/Settings/routes/View/style.css","webpack://airdcpp-webui/./src/routes/Settings/style.css","webpack://airdcpp-webui/./node_modules/fomantic-ui-css/components/item.min.css?538d","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/style.css?1643","webpack://airdcpp-webui/./src/routes/Settings/routes/System/style.css?7e6a","webpack://airdcpp-webui/./src/actions/ui/extension/ExtensionInstallActions.ts","webpack://airdcpp-webui/./src/actions/ui/search/SearchTypeActions.ts","webpack://airdcpp-webui/./src/actions/ui/share/ShareActions.ts","webpack://airdcpp-webui/./src/actions/ui/share/ShareExcludeActions.ts","webpack://airdcpp-webui/./src/actions/ui/share/ShareProfileActions.ts","webpack://airdcpp-webui/./src/actions/ui/share/ShareRootActions.ts","webpack://airdcpp-webui/./src/actions/ui/system/SystemActions.ts","webpack://airdcpp-webui/./src/actions/ui/system/WebUserActions.ts","webpack://airdcpp-webui/./src/components/InstallPrompt.tsx","webpack://airdcpp-webui/./src/components/semantic/Grid.tsx","webpack://airdcpp-webui/./src/constants/ExtensionConstants.ts","webpack://airdcpp-webui/./src/constants/FavoriteDirectoryConstants.ts","webpack://airdcpp-webui/./src/constants/ShareProfileConstants.ts","webpack://airdcpp-webui/./src/constants/ShareRootConstants.ts","webpack://airdcpp-webui/./src/constants/WebUserConstants.ts","webpack://airdcpp-webui/./src/decorators/ShareProfileDecorator.tsx","webpack://airdcpp-webui/./src/decorators/StatisticsDecorator.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/LocalSettingForm.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/RemoteSettingForm.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/MenuItems.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingsSideMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingsTopMenuLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SaveButton.tsx","webpack://airdcpp-webui/./src/routes/Settings/components/SettingSection.tsx","webpack://airdcpp-webui/./src/routes/Settings/effects/useSettingSaveContext.ts","webpack://airdcpp-webui/./src/routes/Settings/style.css?ebc5","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/View/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/About/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/index.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/System/index.ts","webpack://airdcpp-webui/./src/routes/Settings/components/Settings.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/ApplicationPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/HubStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/ShareStatisticsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/About/components/TransferStatisticsPage.tsx","webpack://airdcpp-webui/./src/constants/ConnectivityConstants.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/style.css?efda","webpack://airdcpp-webui/./src/actions/ui/connectivity/ConnectivityActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/DetectPanel.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/DetectionPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/EncryptionPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/IPv4Page.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/IPv6Page.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/PortsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/ProtocolPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Connectivity/components/ProxiesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/DownloadOptionsPage.tsx","webpack://airdcpp-webui/./src/actions/ui/favorite-directory/FavoriteDirectoryActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/FavoriteDirectoryDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/FavoriteDirectoryTable.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/LocationsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/PrioritiesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchMatchingPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchTypeDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SearchTypesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Downloads/components/SkippingOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/EngineStatusMessage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionEnginesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/NpmPackageLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsBrowsePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/LocalExtension.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsManagePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/ExtensionsOptionsPage.tsx","webpack://airdcpp-webui/./src/actions/ui/extension/ExtensionManageActions.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/ExtensionActionButtons.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/Extension.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Extensions/components/extension/ExtensionIcon.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/AwayPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/IgnorePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/style.css?1785","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/MiscPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Profile/components/UserPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/ExcludePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/HashDatabaseLayout.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/HashingPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/RefreshOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/ShareProfileCloneDropdown.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/ShareProfilesPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/Sharing/components/SharingOptionsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/AutoValuePanel.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/DownloadLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/LimiterPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/SpeedPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/UploadLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/SpeedLimits/components/UserLimitPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/AdvancedServerSettingsPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LogSection.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LogSectionGroup.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/LoggingPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/ServerSettingsPage.tsx","webpack://airdcpp-webui/./src/constants/AccessConstants.ts","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/users/WebUserDialog.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/users/PermissionSelector.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/System/components/WebUsersPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/AppearancePage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/EventPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/HistoryPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/MiscellaneousPage.tsx","webpack://airdcpp-webui/./src/routes/Settings/routes/View/style.css?0d4b","webpack://airdcpp-webui/./src/routes/Settings/routes/View/components/NotificationPage.tsx","webpack://airdcpp-webui/./src/services/HttpService.ts","webpack://airdcpp-webui/./src/utils/ShareProfileUtils.ts"],"sourcesContent":["export const semver = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\nexport const validateAndParse = (version) => {\n if (typeof version !== 'string') {\n throw new TypeError('Invalid argument expected string');\n }\n const match = version.match(semver);\n if (!match) {\n throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n }\n match.shift();\n return match;\n};\nconst isWildcard = (s) => s === '*' || s === 'x' || s === 'X';\nconst tryParse = (v) => {\n const n = parseInt(v, 10);\n return isNaN(n) ? v : n;\n};\nconst forceType = (a, b) => typeof a !== typeof b ? [String(a), String(b)] : [a, b];\nconst compareStrings = (a, b) => {\n if (isWildcard(a) || isWildcard(b))\n return 0;\n const [ap, bp] = forceType(tryParse(a), tryParse(b));\n if (ap > bp)\n return 1;\n if (ap < bp)\n return -1;\n return 0;\n};\nexport const compareSegments = (a, b) => {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const r = compareStrings(a[i] || '0', b[i] || '0');\n if (r !== 0)\n return r;\n }\n return 0;\n};\n//# sourceMappingURL=utils.js.map","import { compareSegments, validateAndParse } from './utils.js';\n/**\n * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.\n * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`.\n * @param v1 - First version to compare\n * @param v2 - Second version to compare\n * @returns Numeric value compatible with the [Array.sort(fn) interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters).\n */\nexport const compareVersions = (v1, v2) => {\n // validate input and split into segments\n const n1 = validateAndParse(v1);\n const n2 = validateAndParse(v2);\n // pop off the patch\n const p1 = n1.pop();\n const p2 = n2.pop();\n // validate numbers\n const r = compareSegments(n1, n2);\n if (r !== 0)\n return r;\n // validate pre-release\n if (p1 && p2) {\n return compareSegments(p1.split('.'), p2.split('.'));\n }\n else if (p1 || p2) {\n return p1 ? -1 : 1;\n }\n return 0;\n};\n//# sourceMappingURL=compareVersions.js.map","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/*!\n * # Fomantic-UI 2.9.3 - Item\n * https://github.com/fomantic/Fomantic-UI/\n *\n *\n * Released under the MIT license\n * https://opensource.org/licenses/MIT\n *\n */.ui.items>.item{display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;box-shadow:none;transition:box-shadow .1s ease;z-index:\"\"}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item::after{display:block;content:\" \";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:\"\";align-self:start}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;flex:1 1 auto;background:0 0;color:rgba(0,0,0,.87);margin:0;padding:0;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content::after{display:block;content:\" \";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;align-self:start;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,system-ui,-apple-system,\"Segoe UI\",Roboto,Oxygen,Ubuntu,Cantarell,\"Helvetica Neue\",Arial,\"Noto Sans\",\"Liberation Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\"left floated\"]{float:left}.ui.items>.item [class*=\"right floated\"]{float:right}.ui.items>.item .content img{align-self:center;width:\"\"}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:\"\";height:\"\";border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:none;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\"right floated\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:\"\";transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:\"\"}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0;top:0;left:0;color:rgba(0,0,0,.4);box-shadow:none;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\"right floated\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra::after{display:block;content:\" \";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767.98px){.ui.items:not(.unstackable)>.item{flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\"top aligned\"].content{align-self:flex-start}.ui.items>.item>.image+[class*=\"middle aligned\"].content{align-self:center}.ui.items>.item>.image+[class*=\"bottom aligned\"].content{align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\"very relaxed\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\"very relaxed\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}.ui.mini.items>.item{font-size:.78571429em}.ui.tiny.items>.item{font-size:.85714286em}.ui.small.items>.item{font-size:.92857143em}.ui.large.items>.item{font-size:1.14285714em}.ui.big.items>.item{font-size:1.28571429em}.ui.huge.items>.item{font-size:1.42857143em}.ui.massive.items>.item{font-size:1.71428571em}@media only screen and (max-width:767.98px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}.ui.inverted.items>.item{background:0 0}.ui.inverted.items>.item>.content{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.items>.item .extra{background:0 0}.ui.inverted.items>.item>.content>.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>.description{color:rgba(255,255,255,.9)}.ui.inverted.items>.item .meta{color:rgba(255,255,255,.8)}.ui.inverted.items>.item>.content a:not(.ui){color:#57a4ef}.ui.inverted.items>.item>.content a:not(.ui):hover{color:#4183c4}.ui.inverted.items>.item>.content>a.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>a.header:hover{color:#fff}.ui.inverted.items>.item .meta>a:not(.ui){color:rgba(255,255,255,.7)}.ui.inverted.items>.item .meta>a:not(.ui):hover{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content .favorite.icon:hover{color:#ffc63d}.ui.inverted.items>.item>.content .active.favorite.icon{color:#ffec56}.ui.inverted.items>.item>.content .like.icon:hover{color:#ff5a63}.ui.inverted.items>.item>.content .active.like.icon{color:#ff5a63}.ui.inverted.items>.item .extra{color:rgba(255,255,255,.7)}.ui.inverted.items a.item:hover .content .header,.ui.inverted.link.items>.item:hover .content .header{color:#fff}.ui.inverted.divided.items>.item{border-top:1px solid rgba(255,255,255,.1)}.ui.inverted.divided.items>.item:first-child{border-top:none}.ui.disabled.items,.ui.items>.disabled.item{opacity:.45;pointer-events:none}`, \"\",{\"version\":3,\"sources\":[\"webpack://./node_modules/fomantic-ui-css/components/item.min.css\"],\"names\":[],\"mappings\":\"AAAA;;;;;;;;EAQE,CAAC,gBAAgB,YAAY,CAAC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,cAAc,CAAC,SAAS,CAAC,WAAW,CAAC,eAAe,CAAC,eAAe,CAAC,8BAA8B,CAAC,UAAU,CAAC,kBAAkB,cAAc,CAAC,UAAU,cAAc,CAAC,sBAAsB,sBAAsB,CAAC,qBAAqB,yBAAyB,CAAC,uBAAuB,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,iBAAiB,CAAC,4BAA4B,YAAY,CAAC,2BAA2B,eAAe,CAAC,uBAAuB,iBAAiB,CAAC,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,gBAAgB,CAAC,2BAA2B,aAAa,CAAC,UAAU,CAAC,WAAW,CAAC,qBAAqB,CAAC,WAAW,CAAC,sCAAsC,eAAe,CAAC,yBAAyB,aAAa,CAAC,aAAa,CAAC,cAAc,CAAC,qBAAqB,CAAC,QAAQ,CAAC,SAAS,CAAC,eAAe,CAAC,aAAa,CAAC,WAAW,CAAC,eAAe,CAAC,gCAAgC,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,iBAAiB,CAAC,gCAAgC,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,iCAAiC,oBAAoB,CAAC,oBAAoB,CAAC,4NAA4N,CAAC,eAAe,CAAC,qBAAqB,CAAC,0CAA0C,sBAAsB,CAAC,wCAAwC,UAAU,CAAC,yCAAyC,WAAW,CAAC,6BAA6B,iBAAiB,CAAC,QAAQ,CAAC,uDAAuD,QAAQ,CAAC,SAAS,CAAC,oBAAoB,CAAC,sCAAsC,eAAe,CAAC,cAAc,CAAC,aAAa,CAAC,oBAAoB,CAAC,qBAAqB,CAAC,2BAA2B,eAAe,CAAC,sCAAsC,eAAe,CAAC,sBAAsB,kBAAkB,CAAC,aAAa,CAAC,eAAe,CAAC,oBAAoB,CAAC,wBAAwB,iBAAiB,CAAC,kCAAkC,cAAc,CAAC,+CAA+C,cAAc,CAAC,gBAAgB,CAAC,oCAAoC,QAAQ,CAAC,yBAAyB,CAAC,0CAA0C,QAAQ,CAAC,kCAAkC,qBAAqB,CAAC,wCAAwC,aAAa,CAAC,iCAAiC,oBAAoB,CAAC,uCAAuC,qBAAqB,CAAC,wCAAwC,cAAc,CAAC,WAAW,CAAC,yBAAyB,CAAC,8CAA8C,SAAS,CAAC,aAAa,CAAC,+CAA+C,aAAa,CAAC,oCAAoC,cAAc,CAAC,WAAW,CAAC,yBAAyB,CAAC,0CAA0C,SAAS,CAAC,aAAa,CAAC,2CAA2C,aAAa,CAAC,uBAAuB,aAAa,CAAC,iBAAiB,CAAC,cAAc,CAAC,gBAAgB,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,eAAe,CAAC,yBAAyB,CAAC,eAAe,CAAC,yBAAyB,4BAA4B,CAAC,gDAAgD,4BAA4B,CAAC,8BAA8B,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,iBAAiB,CAAC,gCAAgC,WAAW,CAAC,kEAAkE,gBAAgB,YAAY,CAAC,gCAAgC,WAAW,CAAC,gCAAgC,aAAa,CAAC,iBAAiB,CAAC,CAAC,4CAA4C,kCAAkC,qBAAqB,CAAC,YAAY,CAAC,yCAAyC,aAAa,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,sFAAsF,wBAAwB,CAAC,oBAAoB,CAAC,0BAA0B,CAAC,kDAAkD,aAAa,CAAC,iBAAiB,CAAC,CAAC,sDAAsD,qBAAqB,CAAC,yDAAyD,iBAAiB,CAAC,yDAAyD,mBAAmB,CAAC,wBAAwB,cAAc,CAAC,uCAAuC,YAAY,CAAC,wBAAwB,uCAAuC,CAAC,QAAQ,CAAC,aAAa,CAAC,oCAAoC,eAAe,CAAC,sBAAsB,CAAC,uBAAuB,CAAC,mCAAmC,yBAAyB,CAAC,0BAA0B,CAAC,gCAAgC,QAAQ,CAAC,eAAe,CAAC,+CAA+C,QAAQ,CAAC,aAAa,CAAC,kDAAkD,cAAc,CAAC,oFAAoF,aAAa,CAAC,gBAAgB,aAAa,CAAC,qBAAqB,qBAAqB,CAAC,qBAAqB,qBAAqB,CAAC,sBAAsB,qBAAqB,CAAC,sBAAsB,sBAAsB,CAAC,oBAAoB,sBAAsB,CAAC,qBAAqB,sBAAsB,CAAC,wBAAwB,sBAAsB,CAAC,4CAA4C,0EAA0E,qBAAqB,CAAC,CAAC,yBAAyB,cAAc,CAAC,kCAAkC,cAAc,CAAC,0BAA0B,CAAC,gCAAgC,cAAc,CAAC,0CAA0C,0BAA0B,CAAC,+CAA+C,0BAA0B,CAAC,+BAA+B,0BAA0B,CAAC,6CAA6C,aAAa,CAAC,mDAAmD,aAAa,CAAC,2CAA2C,0BAA0B,CAAC,iDAAiD,UAAU,CAAC,0CAA0C,0BAA0B,CAAC,gDAAgD,0BAA0B,CAAC,uDAAuD,aAAa,CAAC,wDAAwD,aAAa,CAAC,mDAAmD,aAAa,CAAC,oDAAoD,aAAa,CAAC,gCAAgC,0BAA0B,CAAC,sGAAsG,UAAU,CAAC,iCAAiC,yCAAyC,CAAC,6CAA6C,eAAe,CAAC,4CAA4C,WAAW,CAAC,mBAAmB\",\"sourcesContent\":[\"/*!\\n * # Fomantic-UI 2.9.3 - Item\\n * https://github.com/fomantic/Fomantic-UI/\\n *\\n *\\n * Released under the MIT license\\n * https://opensource.org/licenses/MIT\\n *\\n */.ui.items>.item{display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;box-shadow:none;transition:box-shadow .1s ease;z-index:\\\"\\\"}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item::after{display:block;content:\\\" \\\";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:\\\"\\\";align-self:start}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;flex:1 1 auto;background:0 0;color:rgba(0,0,0,.87);margin:0;padding:0;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content::after{display:block;content:\\\" \\\";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;align-self:start;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,system-ui,-apple-system,\\\"Segoe UI\\\",Roboto,Oxygen,Ubuntu,Cantarell,\\\"Helvetica Neue\\\",Arial,\\\"Noto Sans\\\",\\\"Liberation Sans\\\",sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\",\\\"Noto Color Emoji\\\";font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*=\\\"left floated\\\"]{float:left}.ui.items>.item [class*=\\\"right floated\\\"]{float:right}.ui.items>.item .content img{align-self:center;width:\\\"\\\"}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:\\\"\\\";height:\\\"\\\";border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:none;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*=\\\"right floated\\\"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:\\\"\\\";transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:\\\"\\\"}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0;top:0;left:0;color:rgba(0,0,0,.4);box-shadow:none;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*=\\\"right floated\\\"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra::after{display:block;content:\\\" \\\";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767.98px){.ui.items:not(.unstackable)>.item{flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*=\\\"top aligned\\\"].content{align-self:flex-start}.ui.items>.item>.image+[class*=\\\"middle aligned\\\"].content{align-self:center}.ui.items>.item>.image+[class*=\\\"bottom aligned\\\"].content{align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*=\\\"very relaxed\\\"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*=\\\"very relaxed\\\"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}.ui.mini.items>.item{font-size:.78571429em}.ui.tiny.items>.item{font-size:.85714286em}.ui.small.items>.item{font-size:.92857143em}.ui.large.items>.item{font-size:1.14285714em}.ui.big.items>.item{font-size:1.28571429em}.ui.huge.items>.item{font-size:1.42857143em}.ui.massive.items>.item{font-size:1.71428571em}@media only screen and (max-width:767.98px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}.ui.inverted.items>.item{background:0 0}.ui.inverted.items>.item>.content{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.items>.item .extra{background:0 0}.ui.inverted.items>.item>.content>.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>.description{color:rgba(255,255,255,.9)}.ui.inverted.items>.item .meta{color:rgba(255,255,255,.8)}.ui.inverted.items>.item>.content a:not(.ui){color:#57a4ef}.ui.inverted.items>.item>.content a:not(.ui):hover{color:#4183c4}.ui.inverted.items>.item>.content>a.header{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content>a.header:hover{color:#fff}.ui.inverted.items>.item .meta>a:not(.ui){color:rgba(255,255,255,.7)}.ui.inverted.items>.item .meta>a:not(.ui):hover{color:rgba(255,255,255,.9)}.ui.inverted.items>.item>.content .favorite.icon:hover{color:#ffc63d}.ui.inverted.items>.item>.content .active.favorite.icon{color:#ffec56}.ui.inverted.items>.item>.content .like.icon:hover{color:#ff5a63}.ui.inverted.items>.item>.content .active.like.icon{color:#ff5a63}.ui.inverted.items>.item .extra{color:rgba(255,255,255,.7)}.ui.inverted.items a.item:hover .content .header,.ui.inverted.link.items>.item:hover .content .header{color:#fff}.ui.inverted.divided.items>.item{border-top:1px solid rgba(255,255,255,.1)}.ui.inverted.divided.items>.item:first-child{border-top:none}.ui.disabled.items,.ui.items>.disabled.item{opacity:.45;pointer-events:none}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.settings-layout .detect-panel {\n margin-top: 30px;\n}\n\n.settings-layout .detect-panel .header.column > div {\n overflow: hidden;\n line-height: inherit !important;\n}\n\n.settings-layout .detect-panel .header.column {\n max-width: 200px;\n}\n\n.settings-layout .detect-panel .detect-button {\n margin-top: 20px;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Connectivity/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;EAChB,+BAA+B;AACjC;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .detect-panel {\\n margin-top: 30px;\\n}\\n\\n.settings-layout .detect-panel .header.column > div {\\n overflow: hidden;\\n line-height: inherit !important;\\n}\\n\\n.settings-layout .detect-panel .header.column {\\n max-width: 200px;\\n}\\n\\n.settings-layout .detect-panel .detect-button {\\n margin-top: 20px;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.settings-layout .profile.miscellaneous .field-nmdc_encoding li {\n margin-bottom: 5px;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Profile/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,kBAAkB;AACpB\",\"sourcesContent\":[\".settings-layout .profile.miscellaneous .field-nmdc_encoding li {\\n margin-bottom: 5px;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.settings-layout .hash-database.grid {\n padding: 10px 0px 15px 0px;\n}\n\n.settings-layout .hash-database.grid .row {\n padding: 5px 0px;\n}\n\n.settings-layout .sharing.excludes .add.button {\n margin-top: 20px;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/Sharing/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,0BAA0B;AAC5B;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .hash-database.grid {\\n padding: 10px 0px 15px 0px;\\n}\\n\\n.settings-layout .hash-database.grid .row {\\n padding: 5px 0px;\\n}\\n\\n.settings-layout .sharing.excludes .add.button {\\n margin-top: 20px;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.web-user.modal .ui.checkbox {\n width: 100%;\n margin-top: 5px;\n}\n\n.web-user.modal .ui.checkbox.admin {\n margin-bottom: 10px;\n font-weight: bold;\n}\n\n.settings-layout .system.logging .log-section.active {\n background-color: whitesmoke;\n}\n\n.settings-layout .system.logging .sections {\n margin-top: 25px !important;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/System/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,WAAW;EACX,eAAe;AACjB;;AAEA;EACE,mBAAmB;EACnB,iBAAiB;AACnB;;AAEA;EACE,4BAA4B;AAC9B;;AAEA;EACE,2BAA2B;AAC7B\",\"sourcesContent\":[\".web-user.modal .ui.checkbox {\\n width: 100%;\\n margin-top: 5px;\\n}\\n\\n.web-user.modal .ui.checkbox.admin {\\n margin-bottom: 10px;\\n font-weight: bold;\\n}\\n\\n.settings-layout .system.logging .log-section.active {\\n background-color: whitesmoke;\\n}\\n\\n.settings-layout .system.logging .sections {\\n margin-top: 25px !important;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.settings-layout .view.notifications .field-notify_events_info {\n margin-top: 25px;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/routes/View/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB\",\"sourcesContent\":[\".settings-layout .view.notifications .field-notify_events_info {\\n margin-top: 25px;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.settings-layout {\n padding-bottom: 30px;\n max-height: 100% !important;\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout .menu-column .menu {\n max-width: 100%;\n}\n\n.settings-layout .layout.header {\n margin-bottom: 20px;\n}\n\n.settings-layout .setting-form {\n margin-top: 30px;\n}\n\n.settings-layout .setting-form:first-child {\n margin-top: 0px;\n}\n\n.settings-layout h3 {\n margin-bottom: 20px;\n}\n\n.settings-layout h4 {\n margin-top: 15px;\n}\n\n.settings-layout > div,\n.settings-layout .mobile .section-content {\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n margin-bottom: 5px;\n}\n\n.settings-layout .main.grid {\n overflow-y: auto;\n padding: 0px;\n}\n\n.settings-layout .mobile .section-content {\n padding-bottom: 5px;\n /* For possible scrollbar */\n padding-right: 5px;\n}\n\n.settings-layout .mobile .section-content.about {\n margin-top: 10px;\n}\n\n.settings-layout .mobile .section-content.about .options {\n flex-shrink: 0;\n}\n\n.settings-layout .full .section-content {\n height: 100%;\n padding-bottom: 2px;\n}\n\n.settings-layout .top-menu {\n display: flex;\n align-items: center;\n margin-bottom: 10px;\n flex-shrink: 0;\n}\n\n.settings-layout .top-menu > .ui.dropdown,\n.settings-layout .top-menu > .ui.dropdown > .caption {\n display: flex;\n}\n\n.settings-layout .top-menu > i {\n margin: 0px 5px;\n}\n\n.settings-layout .full .top-menu i {\n display: none;\n}\n\n.settings-layout .mobile .save.button {\n margin-bottom: 10px;\n flex-shrink: 0;\n}\n\n.settings-layout .options {\n min-height: 80px;\n}\n\n.settings-layout .options > .ui.grid {\n margin: 0px;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Settings/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,oBAAoB;EACpB,2BAA2B;EAC3B,aAAa;EACb,sBAAsB;AACxB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;;EAEE,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,YAAY;AACd;;AAEA;EACE,mBAAmB;EACnB,2BAA2B;EAC3B,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,cAAc;AAChB;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,cAAc;AAChB;;AAEA;;EAEE,aAAa;AACf;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,mBAAmB;EACnB,cAAc;AAChB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,WAAW;AACb\",\"sourcesContent\":[\".settings-layout {\\n padding-bottom: 30px;\\n max-height: 100% !important;\\n display: flex;\\n flex-direction: column;\\n}\\n\\n.settings-layout .menu-column .menu {\\n max-width: 100%;\\n}\\n\\n.settings-layout .layout.header {\\n margin-bottom: 20px;\\n}\\n\\n.settings-layout .setting-form {\\n margin-top: 30px;\\n}\\n\\n.settings-layout .setting-form:first-child {\\n margin-top: 0px;\\n}\\n\\n.settings-layout h3 {\\n margin-bottom: 20px;\\n}\\n\\n.settings-layout h4 {\\n margin-top: 15px;\\n}\\n\\n.settings-layout > div,\\n.settings-layout .mobile .section-content {\\n display: flex;\\n flex-direction: column;\\n overflow-y: auto;\\n margin-bottom: 5px;\\n}\\n\\n.settings-layout .main.grid {\\n overflow-y: auto;\\n padding: 0px;\\n}\\n\\n.settings-layout .mobile .section-content {\\n padding-bottom: 5px;\\n /* For possible scrollbar */\\n padding-right: 5px;\\n}\\n\\n.settings-layout .mobile .section-content.about {\\n margin-top: 10px;\\n}\\n\\n.settings-layout .mobile .section-content.about .options {\\n flex-shrink: 0;\\n}\\n\\n.settings-layout .full .section-content {\\n height: 100%;\\n padding-bottom: 2px;\\n}\\n\\n.settings-layout .top-menu {\\n display: flex;\\n align-items: center;\\n margin-bottom: 10px;\\n flex-shrink: 0;\\n}\\n\\n.settings-layout .top-menu > .ui.dropdown,\\n.settings-layout .top-menu > .ui.dropdown > .caption {\\n display: flex;\\n}\\n\\n.settings-layout .top-menu > i {\\n margin: 0px 5px;\\n}\\n\\n.settings-layout .full .top-menu i {\\n display: none;\\n}\\n\\n.settings-layout .mobile .save.button {\\n margin-bottom: 10px;\\n flex-shrink: 0;\\n}\\n\\n.settings-layout .options {\\n min-height: 80px;\\n}\\n\\n.settings-layout .options > .ui.grid {\\n margin: 0px;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\n import API from \"!../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../css-loader/dist/cjs.js!./item.min.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../css-loader/dist/cjs.js!./item.min.css\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import { APISocket } from 'services/SocketService';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst downloadExtension = (\r\n socket: APISocket,\r\n url: string,\r\n installId?: string,\r\n shasum?: string,\r\n) => {\r\n return socket.post(ExtensionConstants.DOWNLOAD_URL, {\r\n install_id: installId ? installId : url,\r\n url,\r\n shasum,\r\n });\r\n};\r\n\r\nconst handleNpmAction: UI.ActionHandler<UI.NpmPackage> = async ({\r\n itemData: npmPackage,\r\n socket,\r\n}) => {\r\n const data = await fetchCorsSafeData(\r\n ExtensionConstants.NPM_PACKAGE_URL + npmPackage.name + '/latest',\r\n true,\r\n );\r\n\r\n const { tarball, shasum } = data.dist;\r\n\r\n return downloadExtension(socket, tarball, npmPackage.name, shasum);\r\n};\r\n\r\nconst handleInstallUrl: UI.ActionHandler<undefined> = ({ socket }, url: string) => {\r\n return downloadExtension(socket, url);\r\n};\r\n\r\nexport const ExtensionInstallURLAction = {\r\n id: 'installUrl',\r\n displayName: 'Install from URL',\r\n icon: IconConstants.CREATE,\r\n access: API.AccessEnum.ADMIN,\r\n input: {\r\n approveCaption: 'Install',\r\n content: 'Enter download URL',\r\n inputProps: {\r\n placeholder: 'Enter URL',\r\n type: 'url',\r\n required: true,\r\n },\r\n },\r\n handler: handleInstallUrl,\r\n};\r\n\r\nexport const ExtensionInstallNpmAction = {\r\n id: 'installNpm',\r\n displayName: 'Install',\r\n icon: IconConstants.CREATE,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleNpmAction,\r\n};\r\n\r\nexport const ExtensionUpdateNpmAction = {\r\n id: 'updateNpm',\r\n displayName: 'Update',\r\n icon: IconConstants.REFRESH_COLORED,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleNpmAction,\r\n};\r\n\r\nexport const ExtensionInstallActionModule = {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n};\r\n","import IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport SearchConstants from 'constants/SearchConstants';\r\n\r\ntype Filter = UI.ActionFilter<API.SearchType>;\r\nconst notDefaultType: Filter = ({ itemData: type }) => !type.default_type;\r\n\r\nconst handleCreate: UI.ActionHandler<API.SearchType> = ({ navigate }) => {\r\n navigate(`types`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.SearchType> = ({ itemData: type, navigate }) => {\r\n navigate(`types/${type.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.SearchType> = ({ itemData: type, socket }) => {\r\n return socket.delete(`${SearchConstants.SEARCH_TYPES_URL}/${type.id}`);\r\n};\r\n\r\nexport const SearchTypeCreateAction = {\r\n id: 'create',\r\n displayName: 'Add type',\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n};\r\n\r\nexport const SearchTypeEditAction = {\r\n id: 'edit',\r\n displayName: 'Edit type',\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n};\r\n\r\nexport const SearchTypeRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove type',\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the search type {{item.name}}?',\r\n approveCaption: 'Remove type',\r\n rejectCaption: `Don't remove`,\r\n },\r\n filter: notDefaultType,\r\n handler: handleRemove,\r\n};\r\n\r\nconst SearchTypeEditActions: UI.ActionListType<API.SearchType> = {\r\n edit: SearchTypeEditAction,\r\n remove: SearchTypeRemoveAction,\r\n};\r\n\r\nexport const SearchTypeActionModule = {\r\n moduleId: UI.Modules.SETTINGS,\r\n};\r\n\r\nexport const SearchTypeEditActionMenu = {\r\n moduleData: SearchTypeActionModule,\r\n actions: SearchTypeEditActions,\r\n};\r\n","import ShareConstants from 'constants/ShareConstants';\nimport IconConstants from 'constants/IconConstants';\n\nimport * as API from 'types/api';\nimport * as UI from 'types/ui';\n\nconst handleRefresh: UI.ActionHandler<void> = ({ socket }) => {\n return socket.post(ShareConstants.REFRESH_URL);\n};\n\nexport const ShareRefreshAction = {\n id: 'refreshAll',\n displayName: 'Refresh all',\n access: API.AccessEnum.SETTINGS_EDIT,\n icon: IconConstants.REFRESH_COLORED,\n handler: handleRefresh,\n};\n\nconst ShareActions: UI.ActionListType<undefined> = {\n refresh: ShareRefreshAction,\n};\n\nexport const ShareActionModule = {\n moduleId: UI.Modules.SHARE,\n};\n\nexport const ShareActionMenu = {\n moduleData: ShareActionModule,\n actions: ShareActions,\n};\n","import ShareConstants from 'constants/ShareConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst handleAdd: UI.ActionHandler<void> = ({ navigate }) => {\r\n navigate(`browse`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<string> = ({ itemData: path, socket }) => {\r\n return socket.post(ShareConstants.EXCLUDES_REMOVE_URL, { path });\r\n};\r\n\r\nexport const ShareExcludeAddAction = {\r\n id: 'add',\r\n displayName: 'Add path',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.CREATE,\r\n handler: handleAdd,\r\n};\r\n\r\nexport const ShareExcludeRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove path',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the excluded path {{item}}?',\r\n approveCaption: 'Remove path',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst ShareExcludeEditActions: UI.ActionListType<string> = {\r\n remove: ShareExcludeRemoveAction,\r\n};\r\n\r\nexport const ShareExcludeActionModule = {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'shareExclude',\r\n};\r\n\r\nexport const ShareExcludeEditMenu = {\r\n moduleData: ShareExcludeActionModule,\r\n actions: ShareExcludeEditActions,\r\n};\r\n","import FilelistSessionActions from 'actions/reflux/FilelistSessionActions';\r\nimport FilelistSessionStore from 'stores/reflux/FilelistSessionStore';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { MENU_DIVIDER } from 'constants/ActionConstants';\r\nimport ShareRootConstants from 'constants/ShareRootConstants';\r\n\r\ntype Filter = UI.ActionFilter<API.ShareProfile>;\r\nconst notDefault: Filter = ({ itemData: profile }) => !profile.default;\r\n\r\nconst handleCreate: UI.ActionHandler<void> = ({ socket }, name: string) => {\r\n return socket.post<API.ShareProfile>(ShareProfileConstants.PROFILES_URL, {\r\n name: name,\r\n });\r\n};\r\n\r\ntype Handler = UI.ActionHandler<API.ShareProfile>;\r\nconst handleClone: Handler = async (data, name: string) => {\r\n // Create new profile\r\n const newProfile: API.ShareProfile = await handleCreate(\r\n data as unknown as UI.ActionHandlerData<void, void>,\r\n name,\r\n );\r\n\r\n const { itemData: sourceProfile, socket } = data;\r\n\r\n // Fetch roots\r\n const roots = await socket.get<API.ShareRootEntry[]>(\r\n `${ShareRootConstants.MODULE_URL}`,\r\n );\r\n\r\n // Add new profile in all roots that include the source profile\r\n for (const root of roots) {\r\n const rootProfileIds = root.profiles.map((rootProfile) => rootProfile.id);\r\n if (!rootProfileIds.includes(sourceProfile.id)) {\r\n continue;\r\n }\r\n\r\n await socket.patch(`${ShareRootConstants.MODULE_URL}/${root.id}`, {\r\n profiles: [...rootProfileIds, newProfile.id],\r\n });\r\n }\r\n};\r\n\r\nconst handleDefault: Handler = ({ itemData: profile, socket }) => {\r\n return socket.post(`${ShareProfileConstants.PROFILES_URL}/${profile.id}/default`);\r\n};\r\n\r\nconst handleEdit: Handler = ({ itemData: profile, socket }, name: string) => {\r\n return socket.patch(`${ShareProfileConstants.PROFILES_URL}/${profile.id}`, {\r\n name: name,\r\n });\r\n};\r\n\r\nconst handleRemove: Handler = ({ itemData: profile, socket }) => {\r\n return socket.delete(ShareProfileConstants.PROFILES_URL + '/' + profile.id);\r\n};\r\n\r\nconst handleBrowse: Handler = ({ itemData: profile, location, navigate }) => {\r\n return FilelistSessionActions.ownList(profile.id, {\r\n location,\r\n navigate,\r\n sessionStore: FilelistSessionStore,\r\n });\r\n};\r\n\r\nexport const ShareProfileCreateAction = {\r\n id: 'create',\r\n displayName: 'Add profile',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.CREATE,\r\n input: {\r\n approveCaption: 'Create',\r\n content: 'Enter name for the profile',\r\n inputProps: {\r\n placeholder: 'Enter name',\r\n required: true,\r\n },\r\n },\r\n handler: handleCreate,\r\n};\r\n\r\nexport const ShareProfileCloneAction = {\r\n id: 'clone',\r\n displayName: 'Clone profile',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.COPY,\r\n input: {\r\n approveCaption: 'Create',\r\n content: 'Enter name for the profile (cloned from {{item.name}})',\r\n inputProps: {\r\n placeholder: 'Enter name',\r\n required: true,\r\n },\r\n },\r\n handler: handleClone,\r\n};\r\n\r\nexport const ShareProfileBrowseAction = {\r\n id: 'browse',\r\n displayName: 'Browse files',\r\n access: API.AccessEnum.FILELISTS_VIEW,\r\n icon: IconConstants.FILELIST,\r\n handler: handleBrowse,\r\n};\r\n\r\nexport const ShareProfileEditAction = {\r\n id: 'edit',\r\n displayName: 'Rename profile',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.EDIT,\r\n input: (profile: API.ShareProfile) => ({\r\n approveCaption: 'Rename',\r\n content: 'Enter new name for the profile {{item.name}}',\r\n inputProps: {\r\n placeholder: 'Enter name',\r\n defaultValue: profile.name,\r\n required: true,\r\n },\r\n }),\r\n handler: handleEdit,\r\n};\r\n\r\nexport const ShareProfileSetDefaultAction = {\r\n id: 'default',\r\n displayName: 'Set as default',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n filter: notDefault,\r\n icon: IconConstants.DEFAULT,\r\n handler: handleDefault,\r\n};\r\n\r\nexport const ShareProfileRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove profile',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n filter: notDefault,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the profile {{item.name}}?',\r\n approveCaption: 'Remove profile',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst ShareProfileEditActions: UI.ActionListType<API.ShareProfile> = {\r\n browse: ShareProfileBrowseAction,\r\n divider: MENU_DIVIDER,\r\n edit: ShareProfileEditAction,\r\n default: ShareProfileSetDefaultAction,\r\n remove: ShareProfileRemoveAction,\r\n};\r\n\r\nexport const ShareProfileActionModule = {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'profile',\r\n};\r\n\r\nexport const ShareProfileEditMenu = {\r\n moduleData: ShareProfileActionModule,\r\n actions: ShareProfileEditActions,\r\n};\r\n","import ShareRootConstants from 'constants/ShareRootConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst handleCreate: UI.ActionHandler<void> = ({ navigate }) => {\r\n navigate(`directories`);\r\n};\r\n\r\ntype Handler = UI.ActionHandler<API.ShareRootEntry>;\r\nconst handleEdit: Handler = ({ itemData: root, navigate }) => {\r\n navigate(`directories/${root.id}`);\r\n};\r\n\r\nconst handleRemove: Handler = ({ itemData: root, socket }) => {\r\n return socket.delete(ShareRootConstants.ROOTS_URL + '/' + root.id);\r\n};\r\n\r\nexport const ShareRootCreateAction = {\r\n id: 'create',\r\n displayName: 'Add directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n};\r\n\r\nexport const ShareRootEditAction = {\r\n id: 'edit',\r\n displayName: 'Edit directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n};\r\n\r\nexport const ShareRootRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content:\r\n // eslint-disable-next-line max-len\r\n 'Are you sure that you want to remove the directory {{item.virtual_name}} from share? It will be removed from all share profiles.',\r\n approveCaption: 'Remove directory',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst ShareRootEditActions: UI.ActionListType<API.ShareRootEntry> = {\r\n edit: ShareRootEditAction,\r\n remove: ShareRootRemoveAction,\r\n};\r\n\r\nexport const ShareRootActionModule = {\r\n moduleId: UI.Modules.SHARE,\r\n subId: 'root',\r\n};\r\n\r\nexport const ShareRootEditActionMenu = {\r\n moduleData: ShareRootActionModule,\r\n actions: ShareRootEditActions,\r\n};\r\n","import SystemConstants from 'constants/SystemConstants';\n\nimport IconConstants from 'constants/IconConstants';\n\nimport * as API from 'types/api';\nimport * as UI from 'types/ui';\n\nconst handleRestartWeb: UI.ActionHandler<void> = ({ socket }) => {\n return socket.post(SystemConstants.MODULE_URL + '/restart_web');\n};\n\nconst handleShutdown: UI.ActionHandler<void> = ({ socket }) => {\n return socket.post(SystemConstants.MODULE_URL + '/shutdown');\n};\n\nexport const SystemRestartWebAction = {\n id: 'restartWeb',\n displayName: 'Restart web server',\n access: API.AccessEnum.ADMIN,\n icon: IconConstants.REFRESH_COLORED,\n confirmation: {\n content: `When changing the binding options, it's recommended to restart the web server only \n when you are able to access the server for troubleshooting. If \\\n the web server won't come back online, you should start the application \n manually to see if there are any error messages. The configuration file is located in your \\\n user directory by default (inside .airdc++ directory) in case you need to edit it manually.`,\n approveCaption: 'Continue and restart',\n rejectCaption: `Don't restart`,\n },\n handler: handleRestartWeb,\n};\n\nexport const SystemShutdownAction = {\n id: 'shutdown',\n displayName: 'Shut down application',\n access: API.AccessEnum.ADMIN,\n icon: IconConstants.POWER,\n confirmation: {\n content: 'Are you sure that you wish to shut down the application?',\n approveCaption: 'Continue and shut down',\n rejectCaption: 'Cancel',\n },\n handler: handleShutdown,\n};\n\nexport const SystemActionModule = {\n moduleId: UI.Modules.COMMON,\n subId: 'system',\n};\n","import WebUserConstants from 'constants/WebUserConstants';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport LoginStore from 'stores/reflux/LoginStore';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\ntype Filter = UI.ActionFilter<API.WebUser>;\r\nconst isOther: Filter = ({ itemData: user }) => user.id !== LoginStore.user.id;\r\n\r\nconst handleCreate: UI.ActionHandler<void> = ({ navigate }) => {\r\n navigate(`users`);\r\n};\r\n\r\ntype Handler = UI.ActionHandler<API.WebUser>;\r\nconst handleEdit: Handler = ({ itemData: user, navigate }) => {\r\n navigate(`users/${user.id}`);\r\n};\r\n\r\nconst handleRemove: Handler = ({ itemData: user, socket }) => {\r\n return socket.delete(`${WebUserConstants.USERS_URL}/${user.id}`);\r\n};\r\n\r\nexport const WebUserCreateAction = {\r\n id: 'create',\r\n displayName: 'Add user',\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n};\r\n\r\nexport const WebUserEditAction = {\r\n id: 'edit',\r\n displayName: 'Edit user',\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n};\r\n\r\nexport const WebUserRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove user',\r\n filter: isOther,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the user {{item.username}}?',\r\n approveCaption: 'Remove user',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst WebUserEditActions: UI.ActionListType<API.WebUser> = {\r\n edit: WebUserEditAction,\r\n remove: WebUserRemoveAction,\r\n};\r\n\r\nexport const WebUserActionModule = {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'webUser',\r\n};\r\n\r\nexport const WebUserEditActionMenu = {\r\n moduleData: WebUserActionModule,\r\n actions: WebUserEditActions,\r\n};\r\n","import { useContext } from 'react';\r\nimport * as React from 'react';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport Button from 'components/semantic/Button';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport { useStore } from 'effects/StoreListenerEffect';\r\nimport LocalSettingStore from 'stores/reflux/LocalSettingStore';\r\nimport { InstallPromptContext } from 'context/InstallPromptContext';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translate, toI18nKey } from 'utils/TranslationUtils';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\ninterface InstallPromptProps {\r\n alwaysShow?: boolean;\r\n}\r\n\r\nconst InstallPrompt: React.FC<InstallPromptProps> = ({ alwaysShow }) => {\r\n const localSettings = useStore<UI.FormValueMap>(LocalSettingStore);\r\n const prompt = useContext(InstallPromptContext);\r\n const { t } = useTranslation();\r\n if (!prompt) {\r\n return null;\r\n }\r\n\r\n if (!alwaysShow && !!localSettings[LocalSettings.NO_INSTALL_PROMPT]) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Message\r\n title={translate('Install as local application', t, UI.Modules.COMMON)}\r\n description={\r\n <div className=\"install-prompt\">\r\n <p>\r\n {t(\r\n toI18nKey('pwaInstallDesc', UI.Modules.COMMON),\r\n 'This web application can be installed locally, providing a better user experience',\r\n )}\r\n </p>\r\n <Button\r\n className=\"primary\"\r\n caption={translate('Install', t, UI.Modules.COMMON)}\r\n onClick={() => prompt()}\r\n icon={IconConstants.CREATE}\r\n />\r\n {!alwaysShow && (\r\n <Button\r\n caption={translate(`Don't install`, t, UI.Modules.COMMON)}\r\n onClick={() =>\r\n LocalSettingStore.setValue(LocalSettings.NO_INSTALL_PROMPT, true)\r\n }\r\n />\r\n )}\r\n </div>\r\n }\r\n />\r\n );\r\n};\r\n\r\nexport default InstallPrompt;\r\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { toI18nKey } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nexport interface RowProps {\r\n title: React.ReactNode;\r\n text?: React.ReactNode;\r\n titleWidth?: string;\r\n className?: string;\r\n noText?: boolean;\r\n}\r\n\r\nconst formatText = (text: React.ReactNode) => {\r\n if (!!text) {\r\n return text;\r\n }\r\n\r\n return <Trans i18nKey={toI18nKey('na', UI.Modules.COMMON)}>N/A</Trans>;\r\n};\r\n\r\nexport const Row: React.FC<RowProps> = ({\r\n title,\r\n text,\r\n className,\r\n titleWidth = 'four',\r\n noText,\r\n}) => (\r\n <div className={classNames('ui row', className)}>\r\n <div className={classNames(noText ? 'sixteen' : titleWidth, 'wide column title')}>\r\n <div className=\"ui tiny header\" style={{ overflow: 'hidden' }}>\r\n {title}\r\n </div>\r\n </div>\r\n {!noText && <div className=\"column value\">{formatText(text)}</div>}\r\n </div>\r\n);\r\n\r\nexport interface HeaderProps {\r\n title: React.ReactNode;\r\n}\r\n\r\nexport const Header: React.FC<HeaderProps> = ({ title }) => (\r\n <div className=\"ui row\">\r\n <div className=\"sixteen wide column\">\r\n <div className=\"ui blue section header\">{title}</div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\r\n columns?: string;\r\n stackable?: boolean;\r\n}\r\n\r\nexport const Grid: React.FC<GridProps> = ({\r\n className,\r\n children,\r\n columns,\r\n stackable,\r\n ...other\r\n}) => (\r\n <div\r\n className={classNames(\r\n 'ui grid',\r\n //`${columns} column`,\r\n { [`${columns} column`]: !!columns },\r\n { stackable: stackable },\r\n className,\r\n )}\r\n {...other}\r\n >\r\n {children}\r\n </div>\r\n);\r\n","const MODULE_URL = 'extensions';\n\nconst NPM_URL = 'https://registry.npmjs.org/';\n\nexport default {\n MODULE_URL: MODULE_URL,\n EXTENSIONS_URL: MODULE_URL,\n DOWNLOAD_URL: MODULE_URL + '/download',\n\n ENGINES_URL: MODULE_URL + '/engines',\n ENGINES_STATUS_URL: MODULE_URL + '/engines/status',\n\n DEFAULT_ENGINE: 'node',\n\n STARTED: 'extension_started',\n STOPPED: 'extension_stopped',\n\n ADDED: 'extension_added',\n REMOVED: 'extension_removed',\n UPDATED: 'extension_updated',\n\n INSTALLATION_STARTED: 'extension_installation_started',\n INSTALLATION_SUCCEEDED: 'extension_installation_succeeded',\n INSTALLATION_FAILED: 'extension_installation_failed',\n\n NPM_PACKAGES_URL:\n NPM_URL + '-/v1/search?text=keywords:airdcpp-extensions-public&size=100',\n NPM_PACKAGE_URL: NPM_URL,\n NPM_HOMEPAGE_URL: 'https://www.npmjs.com/package/',\n};\n","const MODULE_URL = 'favorite_directories';\nexport default {\n MODULE_URL: MODULE_URL,\n\n GROUPED_DIRECTORIES_URL: MODULE_URL + '/grouped_paths',\n DIRECTORIES_URL: MODULE_URL,\n\n DIRECTORIES_UPDATED: 'favorite_directories_updated',\n};\n","const MODULE_URL = 'share_profiles';\nexport default {\n MODULE_URL: MODULE_URL,\n PROFILES_URL: MODULE_URL,\n\n PROFILE_ADDED: 'share_profile_added',\n PROFILE_UPDATED: 'share_profile_updated',\n PROFILE_REMOVED: 'share_profile_removed',\n\n HIDDEN_PROFILE_ID: 1,\n};\n","const MODULE_URL = 'share_roots';\n\nexport default {\n MODULE_URL: MODULE_URL,\n ROOTS_URL: MODULE_URL,\n\n CREATED: 'share_root_created',\n UPDATED: 'share_root_updated',\n REMOVED: 'share_root_removed',\n};\n","const MODULE_URL = 'web_users';\n\nexport default {\n MODULE_URL: MODULE_URL,\n USERS_URL: MODULE_URL,\n\n ADDED: 'web_user_added',\n UPDATED: 'web_user_updated',\n REMOVED: 'web_user_removed',\n};\n","import * as React from 'react';\r\nimport { merge } from 'lodash';\r\n\r\nimport ShareProfileConstants from 'constants/ShareProfileConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n DataProviderDecoratorSettings,\r\n DataConverter,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport * as API from 'types/api';\r\n\r\ninterface ShareProfileDecoratorDataProps {\r\n profiles: API.ShareProfile[];\r\n}\r\n\r\nexport type ShareProfileDecoratorChildProps = DataProviderDecoratorChildProps &\r\n ShareProfileDecoratorDataProps;\r\n\r\nconst ShareProfileDecorator = function <PropsT extends object>(\r\n Component: React.ComponentType<PropsT & ShareProfileDecoratorChildProps>,\r\n listHidden: boolean,\r\n dataProviderDecoratorSettings?: DataProviderDecoratorSettings<\r\n PropsT,\r\n ShareProfileDecoratorDataProps\r\n >,\r\n) {\r\n const convertProfiles: DataConverter<PropsT> = (data: API.ShareProfile[], { t }) => {\r\n const profiles = data.filter(\r\n (p) => listHidden || p.id !== ShareProfileConstants.HIDDEN_PROFILE_ID,\r\n );\r\n\r\n return profiles;\r\n };\r\n\r\n return DataProviderDecorator<PropsT, ShareProfileDecoratorDataProps>(\r\n Component,\r\n merge(dataProviderDecoratorSettings, {\r\n urls: {\r\n profiles: ShareProfileConstants.PROFILES_URL,\r\n },\r\n dataConverters: {\r\n profiles: convertProfiles,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_ADDED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_UPDATED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_REMOVED,\r\n () => refetchData(),\r\n );\r\n },\r\n } as DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>),\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator;\r\n","import * as React from 'react';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport { ErrorResponse } from 'airdcpp-apisocket';\r\n\r\nimport { Translation } from 'react-i18next';\r\nimport { translate } from 'utils/TranslationUtils';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { useSocket } from 'context/SocketContext';\r\n\r\nexport interface StatisticsDecoratorProps<DataT> {}\r\n\r\nexport interface StatisticsDecoratorChildProps<DataT> {\r\n stats: DataT;\r\n}\r\n\r\n// Decorator for statistics pages that fetch the content from API\r\nconst StatisticsDecorator = function <DataT extends object, PropsT>(\r\n Component: React.ComponentType<StatisticsDecoratorChildProps<DataT> & PropsT>,\r\n fetchUrl: string,\r\n unavailableMessage: ((t: UI.TranslateF, props: PropsT) => string) | null,\r\n fetchIntervalSeconds = 0,\r\n) {\r\n const Decorator: React.FC<StatisticsDecoratorProps<DataT> & PropsT> = (props) => {\r\n const [stats, setStats] = React.useState<DataT | null | undefined>(null);\r\n\r\n const socket = useSocket();\r\n\r\n const onStatsReceived = (data: DataT) => {\r\n setStats(data);\r\n };\r\n\r\n const fetchStats = () => {\r\n socket\r\n .get<DataT | undefined>(fetchUrl)\r\n .then(onStatsReceived)\r\n .catch((error: ErrorResponse) =>\r\n console.error('Failed to fetch stats', error.message),\r\n );\r\n };\r\n\r\n React.useEffect(() => {\r\n fetchStats();\r\n\r\n const fetchInterval = window.setInterval(fetchStats, fetchIntervalSeconds * 1000);\r\n return () => {\r\n window.clearTimeout(fetchInterval);\r\n };\r\n }, []);\r\n\r\n if (stats === null) {\r\n return null;\r\n }\r\n\r\n // The returned stats can be undefined if the daemon has no data to generate them\r\n // (e.g. no hub stats if there are no connected hubs)\r\n if (stats === undefined) {\r\n return (\r\n <Translation>\r\n {(t) => (\r\n <Message\r\n title={translate('Statistics not available', t, UI.Modules.COMMON)}\r\n description={!unavailableMessage ? undefined : unavailableMessage(t, props)}\r\n />\r\n )}\r\n </Translation>\r\n );\r\n }\r\n\r\n return <Component {...props} stats={stats} />;\r\n };\r\n\r\n return Decorator;\r\n};\r\n\r\nexport default StatisticsDecorator;\r\n","import { useContext, useMemo, useState } from 'react';\r\n\r\nimport LocalSettingStore from 'stores/reflux/LocalSettingStore';\r\n\r\nimport Form, {\r\n FormProps,\r\n FormSaveHandler,\r\n FormFieldChangeHandler,\r\n} from 'components/form/Form';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translateForm } from 'utils/FormUtils';\r\nimport { SettingSaveContext, getSettingFormId } from '../effects/useSettingSaveContext';\r\n\r\nexport interface LocalSettingFormProps\r\n extends Omit<FormProps, 'onSave' | 'fieldDefinitions' | 'value' | 'location'> {\r\n keys: string[];\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst LocalSettingForm: React.FC<LocalSettingFormProps> = ({\r\n moduleT,\r\n keys,\r\n onFieldChanged,\r\n}) => {\r\n const [settings, setSettings] = useState(LocalSettingStore.getValues());\r\n const definitions = useMemo(() => {\r\n return translateForm(LocalSettingStore.getDefinitions(keys), moduleT);\r\n }, []);\r\n\r\n const saveContext = useContext(SettingSaveContext)!;\r\n\r\n const onSave: FormSaveHandler<UI.FormValueMap> = (changedSettingArray, allFields) => {\r\n LocalSettingStore.setValues(changedSettingArray);\r\n setSettings(LocalSettingStore.getValues());\r\n return Promise.resolve();\r\n };\r\n\r\n const handleFieldChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n saveContext.onFieldChanged(id, value, hasChanges);\r\n if (onFieldChanged) {\r\n return onFieldChanged(id, value, hasChanges);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"local setting-form\">\r\n <Form\r\n ref={(f) => saveContext.addFormRef(keys, f)}\r\n id={getSettingFormId(keys)}\r\n onSave={onSave}\r\n fieldDefinitions={definitions}\r\n sourceValue={settings}\r\n onFieldChanged={handleFieldChanged}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default LocalSettingForm;\r\n","import { useContext } from 'react';\r\nimport SettingConstants from 'constants/SettingConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport Form, {\r\n FormProps,\r\n FormSaveHandler,\r\n FormFieldChangeHandler,\r\n} from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { SettingSaveContext, getSettingFormId } from '../effects/useSettingSaveContext';\r\nimport { useSocket } from 'context/SocketContext';\r\n\r\nexport interface RemoteSettingFormProps\r\n extends Omit<FormProps, 'onSave' | 'value' | 'fieldDefinitions' | 'location'> {\r\n keys: string[];\r\n onSettingValuesReceived?: (settings: API.SettingValueMap) => void;\r\n valueMode?: API.SettingValueMode;\r\n}\r\n\r\ninterface RemoteSettingFormDataProps extends DataProviderDecoratorChildProps {\r\n settings: API.SettingValueMap;\r\n fieldDefinitions: UI.FormFieldDefinition[];\r\n}\r\n\r\ntype Props = RemoteSettingFormProps & RemoteSettingFormDataProps;\r\n\r\nconst RemoteSettingForm: React.FC<Props> = ({\r\n onFieldChanged,\r\n refetchData,\r\n keys,\r\n fieldDefinitions,\r\n settings,\r\n ...other\r\n}) => {\r\n const saveContext = useContext(SettingSaveContext)!;\r\n const socket = useSocket();\r\n\r\n const refetchValues = () => {\r\n refetchData(['settings']);\r\n };\r\n\r\n const onSave: FormSaveHandler<UI.FormValueMap> = (changedValues) => {\r\n if (Object.keys(changedValues).length === 0) {\r\n return Promise.resolve();\r\n }\r\n\r\n return socket.post(SettingConstants.ITEMS_SET_URL, changedValues).then(refetchValues);\r\n };\r\n\r\n const handleFieldChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n saveContext.onFieldChanged(id, value, hasChanges);\r\n if (onFieldChanged) {\r\n return onFieldChanged(id, value, hasChanges);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"remote setting-form\">\r\n <Form\r\n {...other}\r\n id={getSettingFormId(keys)}\r\n ref={(f) => saveContext.addFormRef(keys, f)}\r\n onSave={onSave}\r\n fieldDefinitions={fieldDefinitions}\r\n sourceValue={settings}\r\n onFieldChanged={handleFieldChanged}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<RemoteSettingFormProps, RemoteSettingFormDataProps>(\r\n RemoteSettingForm,\r\n {\r\n urls: {\r\n fieldDefinitions: ({ keys }, socket) =>\r\n socket.post(SettingConstants.ITEMS_DEFINITIONS_URL, { keys }),\r\n settings: async (\r\n { keys, onSettingValuesReceived, valueMode = API.SettingValueMode.CURRENT },\r\n socket,\r\n ) => {\r\n const settings: API.SettingValueMap = await socket.post(\r\n SettingConstants.ITEMS_GET_URL,\r\n {\r\n keys,\r\n value_mode: valueMode,\r\n },\r\n );\r\n\r\n if (!!onSettingValuesReceived) {\r\n onSettingValuesReceived(settings);\r\n }\r\n\r\n return settings;\r\n },\r\n },\r\n },\r\n);\r\n","import RouterMenuItemLink from 'components/semantic/RouterMenuItemLink';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { ChildSectionType, RootSectionType, SectionBase } from '../types';\r\nimport { Location } from 'react-router';\r\nimport { AuthenticatedSession } from 'context/SessionContext';\r\n\r\nexport const sectionToUrl = (section: SectionBase, parent?: RootSectionType) => {\r\n if (typeof parent === 'object') {\r\n return `/settings/${parent.url}/${section.url}`;\r\n }\r\n\r\n return `/settings/${section.url}`;\r\n};\r\n\r\nexport const translateSettingSectionTitle = (\r\n title: string,\r\n settingsT: UI.ModuleTranslator,\r\n) => {\r\n return settingsT.translate(title, [UI.SubNamespaces.NAVIGATION]);\r\n};\r\n\r\nconst menuItemToLinkComponent = (\r\n url: string,\r\n menuItemInfo: SectionBase,\r\n settingsT: UI.ModuleTranslator,\r\n { hasAccess }: AuthenticatedSession,\r\n) => {\r\n if (menuItemInfo.access && !hasAccess(menuItemInfo.access)) {\r\n return null;\r\n }\r\n\r\n return (\r\n <RouterMenuItemLink\r\n key={url}\r\n url={url}\r\n icon={'icon' in menuItemInfo ? `green ${menuItemInfo.icon}` : null}\r\n >\r\n {translateSettingSectionTitle(menuItemInfo.title, settingsT)}\r\n </RouterMenuItemLink>\r\n );\r\n};\r\n\r\nexport const rootMenuItemToLinkComponent = (\r\n rootMenuItem: RootSectionType,\r\n settingsT: UI.ModuleTranslator,\r\n location: Location,\r\n session: AuthenticatedSession,\r\n) => {\r\n // Browsing is smoother when the child page is loaded directly\r\n // Don't use the child URL for currently active parent so that the route is detected as active correctly\r\n let url = sectionToUrl(rootMenuItem);\r\n if (rootMenuItem.menuItems && !location.pathname.startsWith(url)) {\r\n url = sectionToUrl(rootMenuItem.menuItems[0], rootMenuItem);\r\n }\r\n\r\n return menuItemToLinkComponent(url, rootMenuItem, settingsT, session);\r\n};\r\n\r\nexport const childMenuItemToLinkComponent = (\r\n childMenuItem: ChildSectionType,\r\n parent: RootSectionType | undefined,\r\n settingsT: UI.ModuleTranslator,\r\n session: AuthenticatedSession,\r\n) => {\r\n const url = sectionToUrl(childMenuItem, parent);\r\n return menuItemToLinkComponent(url, childMenuItem, settingsT, session);\r\n};\r\n\r\nexport const findMainSection = (\r\n mainSection: string | undefined,\r\n rootMenuItems: RootSectionType[],\r\n) => {\r\n const item = rootMenuItems.find((rootMenuItem) => rootMenuItem.url === mainSection);\r\n return item || rootMenuItems[0];\r\n};\r\n\r\nexport const findChildSection = (\r\n childSection: string | undefined,\r\n mainSection: RootSectionType,\r\n) => {\r\n const item = [...mainSection.menuItems, ...(mainSection.advancedMenuItems || [])].find(\r\n (childMenuItem) => childMenuItem.url === childSection,\r\n );\r\n\r\n return item || mainSection.menuItems[0];\r\n};\r\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { SettingSectionLayoutProps } from 'routes/Settings/types';\r\nimport { translateSettingSectionTitle } from './MenuItems';\r\nimport Icon from 'components/semantic/Icon';\r\n\r\ntype SideMenuProps = Pick<SettingSectionLayoutProps, 'menu' | 'settingsT'>;\r\n\r\nconst SideChildSectionMenu: React.FC<SideMenuProps> = ({ menu, settingsT }) => {\r\n return (\r\n <div className=\"three wide column menu-column\">\r\n <div className=\"ui vertical secondary menu\">\r\n {menu.childMenuItems}\r\n {!!menu.childAdvancedMenuItems && (\r\n <div>\r\n <div className=\"item header\">{settingsT.translate('Advanced')}</div>\r\n <div className=\"menu\">{menu.childAdvancedMenuItems}</div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\ntype TopMenuProps = Pick<SettingSectionLayoutProps, 'menu'>;\r\n\r\nconst TopRootSectionMenu: React.FC<TopMenuProps> = ({ menu }) => (\r\n <div className=\"ui secondary pointing menu settings top-menu\">{menu.rootMenuItems}</div>\r\n);\r\n\r\n// eslint-disable-next-line max-len\r\ntype ContentProps = React.PropsWithChildren<\r\n Pick<\r\n SettingSectionLayoutProps,\r\n | 'contentClassname'\r\n | 'selectedRootMenuItem'\r\n | 'selectedChildMenuItem'\r\n | 'getSaveButton'\r\n | 'message'\r\n | 'settingsT'\r\n >\r\n>;\r\n\r\nconst Content: React.FC<ContentProps> = ({\r\n contentClassname,\r\n selectedChildMenuItem,\r\n selectedRootMenuItem,\r\n getSaveButton,\r\n children,\r\n message,\r\n settingsT,\r\n}) => (\r\n <div className={classNames('thirteen wide column', contentClassname)}>\r\n <div className=\"ui segment\">\r\n <LayoutHeader\r\n title={translateSettingSectionTitle(selectedChildMenuItem.title, settingsT)}\r\n icon={<Icon color=\"green\" icon={selectedRootMenuItem.icon} />}\r\n rightComponent={getSaveButton()}\r\n />\r\n <div className=\"options\">\r\n {message}\r\n {children}\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nconst SideMenuLayout: React.FC<SettingSectionLayoutProps> = ({ children, ...other }) => (\r\n <div className=\"full\">\r\n <TopRootSectionMenu {...other} />\r\n <div id=\"setting-scroll-context\" className=\"ui segment grid main\">\r\n <SideChildSectionMenu {...other} />\r\n <Content {...other}>{children}</Content>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default SideMenuLayout;\r\n","import * as React from 'react';\r\n\r\nimport Dropdown from 'components/semantic/Dropdown';\r\nimport SectionedDropdown from 'components/semantic/SectionedDropdown';\r\nimport MenuSection from 'components/semantic/MenuSection';\r\nimport Icon from 'components/semantic/Icon';\r\nimport { SettingSectionLayoutProps } from 'routes/Settings/types';\r\nimport { translateSettingSectionTitle } from './MenuItems';\r\n\r\ntype TopSectionSelectionMenuProps = Pick<\r\n SettingSectionLayoutProps,\r\n 'selectedRootMenuItem' | 'selectedChildMenuItem' | 'menu' | 'settingsT'\r\n>;\r\n\r\nconst TopSectionSelectionMenu: React.FC<TopSectionSelectionMenuProps> = ({\r\n selectedChildMenuItem,\r\n menu,\r\n selectedRootMenuItem,\r\n settingsT,\r\n}) => (\r\n <div className=\"ui top-menu\">\r\n <Dropdown\r\n selection={true}\r\n caption={translateSettingSectionTitle(selectedRootMenuItem.title, settingsT)}\r\n captionIcon={`green ${selectedRootMenuItem.icon}`}\r\n >\r\n {menu.rootMenuItems}\r\n </Dropdown>\r\n\r\n <Icon icon=\"caret right\" size=\"large\" />\r\n\r\n <SectionedDropdown\r\n selection={true}\r\n caption={translateSettingSectionTitle(selectedChildMenuItem.title, settingsT)}\r\n >\r\n <MenuSection>{menu.childMenuItems}</MenuSection>\r\n <MenuSection caption={settingsT.translate('Advanced')}>\r\n {menu.childAdvancedMenuItems}\r\n </MenuSection>\r\n </SectionedDropdown>\r\n </div>\r\n);\r\n\r\nconst TopMenuLayout: React.FC<SettingSectionLayoutProps> = ({\r\n getSaveButton,\r\n children,\r\n contentClassname,\r\n settingsT,\r\n message,\r\n ...other\r\n}) => (\r\n <div className=\"mobile\">\r\n <TopSectionSelectionMenu settingsT={settingsT} {...other} />\r\n <div id=\"setting-scroll-context\" className={contentClassname}>\r\n {getSaveButton('fluid')}\r\n <div className=\"options\">\r\n {message}\r\n {children}\r\n </div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default TopMenuLayout;\r\n","import { useState } from 'react';\r\nimport Button from 'components/semantic/Button';\r\n\r\nimport classNames from 'classnames';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { SettingSaveState } from '../effects/useSettingSaveContext';\r\nimport { useSession } from 'context/SessionContext';\r\n\r\nexport interface SaveButtonProps {\r\n saveState: SettingSaveState;\r\n className?: string;\r\n settingsT: UI.ModuleTranslator;\r\n}\r\n\r\nconst SaveButton: React.FC<SaveButtonProps> = ({ saveState, settingsT, className }) => {\r\n const { local, handleSave, hasChanges } = saveState;\r\n const [saving, setSaving] = useState(false);\r\n const { hasAccess } = useSession();\r\n\r\n const onClick = async () => {\r\n setSaving(true);\r\n\r\n try {\r\n await handleSave();\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const hasEditAccess: boolean = local || hasAccess(API.AccessEnum.SETTINGS_EDIT);\r\n\r\n let title;\r\n if (!hasEditAccess) {\r\n title = settingsT.translate('No save permission');\r\n } else {\r\n title = settingsT.translate(hasChanges ? 'Save changes' : 'No unsaved changes');\r\n }\r\n\r\n return (\r\n <Button\r\n className={classNames('save', className)}\r\n caption={title}\r\n icon={hasEditAccess && hasChanges ? 'green checkmark' : null}\r\n loading={saving}\r\n disabled={!hasChanges || !hasEditAccess}\r\n onClick={onClick}\r\n />\r\n );\r\n};\r\n\r\nexport default SaveButton;\r\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport { usingMobileLayout } from 'utils/BrowserUtils';\r\n\r\nimport SettingsSideMenuLayout from './SettingsSideMenuLayout';\r\nimport SettingsTopMenuLayout from './SettingsTopMenuLayout';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { childMenuItemToLinkComponent, rootMenuItemToLinkComponent } from './MenuItems';\r\nimport { useLocation } from 'react-router';\r\nimport { ChildSectionType, RootSectionType } from '../types';\r\nimport {\r\n SettingSaveContext,\r\n useSettingSaveContext,\r\n} from '../effects/useSettingSaveContext';\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport SaveButton from './SaveButton';\r\nimport { useSession } from 'context/SessionContext';\r\n\r\nexport interface SettingRootSectionProps {\r\n settingsT: UI.ModuleTranslator;\r\n rootMenuItems: RootSectionType[];\r\n selectedRootMenuItem: RootSectionType;\r\n selectedChildMenuItem: ChildSectionType;\r\n children: React.ReactNode;\r\n}\r\n\r\nexport type SettingSectionProps = SettingRootSectionProps;\r\n\r\nconst getMessage = (childMenuItem: ChildSectionType, settingsT: UI.ModuleTranslator) => {\r\n return (\r\n childMenuItem.local && (\r\n <Message\r\n description={settingsT.t(\r\n 'browserSpecificNote',\r\n 'Settings listed on this page are browser-specific',\r\n )}\r\n icon={IconConstants.INFO}\r\n />\r\n )\r\n );\r\n};\r\n\r\nconst SettingSection: React.FC<SettingSectionProps> = (props) => {\r\n const login = useSession();\r\n const {\r\n rootMenuItems,\r\n selectedRootMenuItem,\r\n settingsT,\r\n children,\r\n selectedChildMenuItem,\r\n } = props;\r\n\r\n const location = useLocation();\r\n const { saveState, saveContext } = useSettingSaveContext({\r\n selectedChildMenuItem,\r\n settingsT,\r\n });\r\n\r\n const SectionLayoutComponent =\r\n usingMobileLayout() || window.innerWidth < 1000\r\n ? SettingsTopMenuLayout\r\n : SettingsSideMenuLayout;\r\n\r\n const { menuItems, advancedMenuItems } = selectedRootMenuItem;\r\n\r\n const contentClassname = classNames(\r\n 'section-content',\r\n selectedRootMenuItem.url,\r\n selectedChildMenuItem.url,\r\n );\r\n\r\n const menu = {\r\n rootMenuItems: rootMenuItems.map((item) =>\r\n rootMenuItemToLinkComponent(item, settingsT, location, login),\r\n ),\r\n childMenuItems: menuItems.map((item) =>\r\n childMenuItemToLinkComponent(item, selectedRootMenuItem, settingsT, login),\r\n ),\r\n childAdvancedMenuItems: advancedMenuItems?.map((item) =>\r\n childMenuItemToLinkComponent(item, selectedRootMenuItem, settingsT, login),\r\n ),\r\n };\r\n\r\n const getSaveButton = (className: string) => {\r\n if (selectedChildMenuItem.noSave) {\r\n return null;\r\n }\r\n\r\n return (\r\n <SaveButton settingsT={settingsT} saveState={saveState} className={className} />\r\n );\r\n };\r\n\r\n return (\r\n <SettingSaveContext.Provider value={saveContext}>\r\n <SectionLayoutComponent\r\n settingsT={settingsT}\r\n location={location}\r\n getSaveButton={getSaveButton}\r\n message={getMessage(selectedChildMenuItem, settingsT)}\r\n contentClassname={contentClassname}\r\n menu={menu}\r\n selectedChildMenuItem={selectedChildMenuItem}\r\n selectedRootMenuItem={selectedRootMenuItem}\r\n >\r\n {children}\r\n </SectionLayoutComponent>\r\n </SettingSaveContext.Provider>\r\n );\r\n};\r\n\r\nexport default SettingSection;\r\n","import * as React from 'react';\r\nimport invariant from 'invariant';\r\n\r\nimport NotificationActions from 'actions/NotificationActions';\r\n\r\nimport Form, { FormFieldChangeHandler } from 'components/form/Form';\r\n\r\nimport * as UI from 'types/ui';\r\n\r\nimport { ChildSectionType } from '../types';\r\nimport { useBlocker } from 'react-router';\r\n\r\ntype SaveableRef = Pick<Form, 'save'>;\r\n\r\nexport interface SettingSaveContext {\r\n onFieldChanged: FormFieldChangeHandler;\r\n addFormRef: (keys: string[], c: SaveableRef | null) => void;\r\n getFormRef: (keys: string[]) => SaveableRef;\r\n}\r\n\r\nexport const SettingSaveContext = React.createContext<SettingSaveContext | undefined>(\r\n undefined,\r\n);\r\n\r\nexport interface SettingSaveState {\r\n handleSave: () => Promise<void>;\r\n hasChanges: boolean;\r\n\r\n local: boolean | undefined;\r\n}\r\n\r\nexport interface SettingSaveContextProps {\r\n saveContext: SettingSaveContext;\r\n}\r\n\r\nexport const getSettingFormId = (keys: string[]) => {\r\n return keys.join('|');\r\n};\r\n\r\ninterface UseSaveContextProps {\r\n selectedChildMenuItem: ChildSectionType;\r\n settingsT: UI.ModuleTranslator;\r\n}\r\n\r\nexport const useSettingSaveContext = ({\r\n settingsT,\r\n selectedChildMenuItem,\r\n}: UseSaveContextProps) => {\r\n const forms = React.useMemo(() => new Map<string, SaveableRef>(), []);\r\n const [changedProperties, setChangedProperties] = React.useState<string[]>([]);\r\n\r\n React.useEffect(() => {\r\n setChangedProperties([]);\r\n }, [selectedChildMenuItem.url]);\r\n\r\n const onSettingsChanged: FormFieldChangeHandler = (id, value, hasChanges) => {\r\n if (hasChanges) {\r\n setChangedProperties([...changedProperties, id]);\r\n } else {\r\n setChangedProperties(changedProperties.filter((prop) => prop !== id));\r\n }\r\n };\r\n\r\n const onSettingsSaved = () => {\r\n const { translate } = settingsT;\r\n NotificationActions.success({\r\n title: translate('Saving completed'),\r\n message: translate('Settings were saved successfully'),\r\n });\r\n };\r\n\r\n const handleSave = async () => {\r\n invariant(forms.size > 0, 'No forms exist in SaveDecorator');\r\n const promises = Array.from(forms.values()).map((c) => c.save());\r\n\r\n await Promise.all(promises);\r\n setChangedProperties([]);\r\n\r\n onSettingsSaved();\r\n };\r\n\r\n const hasChanges = changedProperties.length > 0;\r\n\r\n useBlocker(({ currentLocation, nextLocation, historyAction }) => {\r\n if (selectedChildMenuItem.noSave) {\r\n return false;\r\n }\r\n\r\n // Closing/opening a modal?\r\n if (\r\n currentLocation.pathname.includes(nextLocation.pathname) ||\r\n nextLocation.pathname.includes(currentLocation.pathname)\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!hasChanges) {\r\n return false;\r\n }\r\n\r\n const message = settingsT.t(\r\n 'unsavedChangesPrompt',\r\n 'You have unsaved changes. Are you sure you want to leave?',\r\n );\r\n\r\n const answer = window.confirm(message);\r\n return !answer;\r\n });\r\n\r\n const addFormRef = (keys: string[], c: SaveableRef | null) => {\r\n if (c) {\r\n invariant(\r\n c.hasOwnProperty('save'),\r\n 'Invalid setting form component supplied for SaveDecorator (save property missing)',\r\n );\r\n forms.set(getSettingFormId(keys), c);\r\n } else {\r\n // Switching to another page\r\n // Single forms shouldn't be unmounted otherwise, but using identifiers would still be safer...\r\n forms.clear();\r\n }\r\n };\r\n\r\n const getFormRef = (keys: string[]) => {\r\n return forms.get(getSettingFormId(keys))!;\r\n };\r\n\r\n const saveContext: SettingSaveContext = {\r\n onFieldChanged: onSettingsChanged,\r\n addFormRef: addFormRef,\r\n getFormRef: getFormRef,\r\n };\r\n\r\n const saveState: SettingSaveState = {\r\n handleSave,\r\n hasChanges,\r\n\r\n local: selectedChildMenuItem.local,\r\n };\r\n\r\n return {\r\n saveContext,\r\n saveState,\r\n };\r\n};\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nconst Profile: RootSectionType = {\r\n url: 'profile',\r\n title: 'Profile',\r\n icon: 'user',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'User',\r\n url: 'user',\r\n component: require('./components/UserPage').default,\r\n },\r\n {\r\n title: 'Away mode',\r\n url: 'away',\r\n component: require('./components/AwayPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'Ignored users',\r\n url: 'ignored-users',\r\n noSave: true,\r\n component: require('./components/IgnorePage').default,\r\n },\r\n {\r\n title: 'Miscellaneous',\r\n url: 'miscellaneous',\r\n component: require('./components/MiscPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default Profile;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nconst Connectivity: RootSectionType = {\r\n url: 'connectivity',\r\n title: 'Connectivity',\r\n icon: 'signal',\r\n component: require('../../components/SettingSection').default,\r\n\r\n menuItems: [\r\n {\r\n title: 'Auto detection',\r\n url: 'detection',\r\n noSave: true,\r\n component: require('./components/DetectionPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'IPv4 connectivity (manual)',\r\n url: 'v4',\r\n component: require('./components/IPv4Page').default,\r\n },\r\n {\r\n title: 'IPv6 connectivity (manual)',\r\n url: 'v6',\r\n component: require('./components/IPv6Page').default,\r\n },\r\n {\r\n title: 'Ports (manual)',\r\n url: 'ports',\r\n component: require('./components/PortsPage').default,\r\n },\r\n {\r\n title: 'Proxies',\r\n url: 'proxies',\r\n component: require('./components/ProxiesPage').default,\r\n },\r\n {\r\n title: 'Encryption',\r\n url: 'encryption',\r\n component: require('./components/EncryptionPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default Connectivity;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nconst SpeedLimits: RootSectionType = {\r\n url: 'speed-limits',\r\n title: 'Speed and limits',\r\n icon: 'dashboard',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'Connection speed',\r\n url: 'speed',\r\n component: require('./components/SpeedPage').default,\r\n },\r\n {\r\n title: 'Bandwidth limiting',\r\n url: 'limiter',\r\n component: require('./components/LimiterPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'Download limits',\r\n url: 'download-limits',\r\n component: require('./components/DownloadLimitPage').default,\r\n },\r\n {\r\n title: 'Upload limits',\r\n url: 'upload-limits',\r\n component: require('./components/UploadLimitPage').default,\r\n },\r\n {\r\n title: 'Per-user limits',\r\n url: 'user-limits',\r\n component: require('./components/UserLimitPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default SpeedLimits;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nconst Downloads: RootSectionType = {\r\n url: 'downloads',\r\n title: 'Downloads',\r\n icon: 'download',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'Locations',\r\n url: 'locations',\r\n component: require('./components/LocationsPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'Skipping options',\r\n url: 'skipping-options',\r\n component: require('./components/SkippingOptionsPage').default,\r\n },\r\n {\r\n title: 'Search matching',\r\n url: 'search-matching',\r\n component: require('./components/SearchMatchingPage').default,\r\n },\r\n {\r\n title: 'Download options',\r\n url: 'download-options',\r\n component: require('./components/DownloadOptionsPage').default,\r\n },\r\n {\r\n title: 'Priorities',\r\n url: 'priorities',\r\n component: require('./components/PrioritiesPage').default,\r\n },\r\n {\r\n title: 'Search types',\r\n url: 'search-types',\r\n component: require('./components/SearchTypesPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default Downloads;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nconst Sharing: RootSectionType = {\r\n url: 'sharing',\r\n title: 'Sharing',\r\n icon: 'tasks',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'Refresh options',\r\n url: 'refresh-options',\r\n component: require('./components/RefreshOptionsPage').default,\r\n },\r\n {\r\n title: 'Share profiles',\r\n url: 'profiles',\r\n noSave: true,\r\n component: require('./components/ShareProfilesPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'Sharing options',\r\n url: 'sharing-options',\r\n component: require('./components/SharingOptionsPage').default,\r\n },\r\n {\r\n title: 'Hashing',\r\n url: 'hashing',\r\n component: require('./components/HashingPage').default,\r\n },\r\n {\r\n title: 'Excluded paths',\r\n url: 'excludes',\r\n noSave: true,\r\n component: require('./components/ExcludePage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default Sharing;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nconst View: RootSectionType = {\r\n url: 'view',\r\n title: 'View',\r\n icon: 'browser',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'Notifications',\r\n url: 'notifications',\r\n local: true,\r\n component: require('./components/NotificationPage').default,\r\n },\r\n {\r\n title: 'Histories',\r\n url: 'histories',\r\n component: require('./components/HistoryPage').default,\r\n },\r\n {\r\n title: 'Events',\r\n url: 'events',\r\n component: require('./components/EventPage').default,\r\n },\r\n {\r\n title: 'Appearance',\r\n url: 'appearance',\r\n component: require('./components/AppearancePage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'Miscellaneous',\r\n url: 'miscellaneous',\r\n local: true,\r\n component: require('./components/MiscellaneousPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default View;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\nimport * as API from 'types/api';\r\n\r\nconst About: RootSectionType = {\r\n url: 'about',\r\n title: 'About',\r\n icon: 'info',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'Application',\r\n noSave: true,\r\n url: 'application',\r\n component: require('./components/ApplicationPage').default,\r\n },\r\n {\r\n title: 'Transfer statistics',\r\n noSave: true,\r\n url: 'transfers',\r\n access: API.AccessEnum.TRANSFERS,\r\n component: require('./components/TransferStatisticsPage').default,\r\n },\r\n {\r\n title: 'Share statistics',\r\n noSave: true,\r\n url: 'share',\r\n component: require('./components/ShareStatisticsPage').default,\r\n },\r\n {\r\n title: 'Hub statistics',\r\n noSave: true,\r\n url: 'hubs',\r\n access: API.AccessEnum.HUBS_VIEW,\r\n component: require('./components/HubStatisticsPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default About;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nconst Extensions: RootSectionType = {\r\n url: 'extensions',\r\n title: 'Extensions',\r\n icon: 'puzzle',\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'Manage installed',\r\n url: 'manage',\r\n noSave: true,\r\n component: require('./components/ExtensionsManagePage').default,\r\n },\r\n {\r\n title: 'Extension catalog',\r\n url: 'packages',\r\n noSave: true,\r\n component: require('./components/ExtensionsBrowsePage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'Extension options',\r\n url: 'extension-options',\r\n component: require('./components/ExtensionsOptionsPage').default,\r\n },\r\n {\r\n title: 'Extension engines',\r\n url: 'extension-engines',\r\n component: require('./components/ExtensionEnginesPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default Extensions;\r\n","import { RootSectionType } from 'routes/Settings/types';\r\n\r\nimport * as API from 'types/api';\r\n\r\nconst System: RootSectionType = {\r\n url: 'system',\r\n title: 'System',\r\n icon: 'settings',\r\n access: API.AccessEnum.ADMIN,\r\n component: require('../../components/SettingSection').default,\r\n menuItems: [\r\n {\r\n title: 'Users',\r\n url: 'users',\r\n noSave: true,\r\n component: require('./components/WebUsersPage').default,\r\n },\r\n {\r\n title: 'Logging',\r\n url: 'logging',\r\n component: require('./components/LoggingPage').default,\r\n },\r\n {\r\n title: 'Web server',\r\n url: 'server-settings',\r\n component: require('./components/ServerSettingsPage').default,\r\n },\r\n ],\r\n advancedMenuItems: [\r\n {\r\n title: 'Advanced server settings',\r\n url: 'advanced-server-settings',\r\n component: require('./components/AdvancedServerSettingsPage').default,\r\n },\r\n ],\r\n};\r\n\r\nexport default System;\r\n","import * as UI from 'types/ui';\r\n\r\nimport '../style.css';\r\n\r\nimport Profile from '../routes/Profile';\r\nimport Connectivity from '../routes/Connectivity';\r\nimport SpeedLimits from '../routes/SpeedLimits';\r\nimport Downloads from '../routes/Downloads';\r\nimport Sharing from '../routes/Sharing';\r\nimport View from '../routes/View';\r\nimport About from '../routes/About';\r\nimport Extensions from '../routes/Extensions';\r\nimport System from '../routes/System';\r\n\r\nimport { ChildSectionType, RootSectionType } from '../types';\r\nimport { Navigate, Route, Routes } from 'react-router';\r\nimport SettingSection from './SettingSection';\r\nimport { getModuleT, getSubModuleT } from 'utils/TranslationUtils';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { camelCase } from 'lodash';\r\n\r\nconst SettingsMenu = [\r\n Profile,\r\n Connectivity,\r\n SpeedLimits,\r\n Downloads,\r\n Sharing,\r\n View,\r\n About,\r\n Extensions,\r\n System,\r\n];\r\n\r\nexport interface SettingsProps {}\r\n\r\nconst childToRoute = (\r\n section: ChildSectionType,\r\n parent: RootSectionType,\r\n settingsT: UI.ModuleTranslator,\r\n) => {\r\n const url = `${section.url}/*`;\r\n const moduleT = getSubModuleT(settingsT, [\r\n camelCase(parent.url),\r\n camelCase(section.url),\r\n ]);\r\n return (\r\n <Route\r\n key={url}\r\n path={url}\r\n element={\r\n <SettingSection\r\n settingsT={settingsT}\r\n selectedRootMenuItem={parent}\r\n rootMenuItems={SettingsMenu}\r\n selectedChildMenuItem={section}\r\n >\r\n <section.component settingsT={settingsT} moduleT={moduleT} />\r\n </SettingSection>\r\n }\r\n />\r\n );\r\n};\r\n\r\nconst rootToRoute = (rootSection: RootSectionType, settingsT: UI.ModuleTranslator) => {\r\n return (\r\n <Route key={rootSection.url} path={rootSection.url}>\r\n {rootSection.menuItems.map((child) => childToRoute(child, rootSection, settingsT))}\r\n {rootSection.advancedMenuItems?.map((child) =>\r\n childToRoute(child, rootSection, settingsT),\r\n )}\r\n <Route index element={<Navigate to={rootSection.menuItems[0].url} replace />} />\r\n </Route>\r\n );\r\n};\r\n\r\n// Only to pass menu items to the decorated component\r\nconst Settings: React.FC<SettingsProps> = (props) => {\r\n const { t } = useTranslation();\r\n const settingsT = getModuleT(t, UI.Modules.SETTINGS);\r\n\r\n return (\r\n <div className=\"ui segment settings-layout\">\r\n <Routes>\r\n <Route index element={<Navigate to={SettingsMenu[0].url} replace />} />\r\n {SettingsMenu.map((rootMenuItem) => rootToRoute(rootMenuItem, settingsT))}\r\n </Routes>\r\n </div>\r\n );\r\n};\r\n\r\nexport default Settings;\r\n","import * as React from 'react';\r\n\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\nimport StatisticsDecorator, {\r\n StatisticsDecoratorChildProps,\r\n} from 'decorators/StatisticsDecorator';\r\nimport SystemConstants from 'constants/SystemConstants';\r\nimport { useFormatter } from 'context/FormatterContext';\r\nimport InstallPrompt from 'components/InstallPrompt';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport { useSession } from 'context/SessionContext';\r\n\r\ninterface ApplicationPageProps extends SettingPageProps {}\r\n\r\nconst ApplicationPage: React.FC<\r\n ApplicationPageProps & StatisticsDecoratorChildProps<any>\r\n> = ({ stats, moduleT }) => {\r\n const { translate } = moduleT;\r\n const { systemInfo } = useSession();\r\n const { formatRelativeTime, formatDateTime } = useFormatter();\r\n\r\n const buildDate = formatDateTime(UI_BUILD_DATE / 1000);\r\n return (\r\n <>\r\n <Grid columns=\"two\" stackable={true}>\r\n <Row title={translate('Application version')} text={systemInfo.client_version} />\r\n <Row title={translate('Web UI version')} text={UI_VERSION} />\r\n <Row title={translate('Web UI build date')} text={buildDate} />\r\n <Row title={translate('API version')} text={systemInfo.api_version} />\r\n <Row title={translate('API feature level')} text={systemInfo.api_feature_level} />\r\n <Row\r\n title={translate('Started')}\r\n text={formatRelativeTime(systemInfo.client_started)}\r\n />\r\n <Row title={translate('Active sessions')} text={stats.active_sessions} />\r\n <Row title={translate('Server threads')} text={stats.server_threads} />\r\n\r\n <Header title={translate('Resources')} />\r\n <Row\r\n title={\r\n <ExternalLink url={LinkConstants.HOME_PAGE_URL}>\r\n {translate('Home page')}\r\n </ExternalLink>\r\n }\r\n noText={true}\r\n />\r\n <Row\r\n title={\r\n <ExternalLink url={LinkConstants.HELP_URL}>\r\n {translate('Documentation')}\r\n </ExternalLink>\r\n }\r\n noText={true}\r\n />\r\n <Row\r\n title={\r\n <ExternalLink url={LinkConstants.ISSUE_TRACKER_URL}>\r\n {translate('Feature request/bug tracker')}\r\n </ExternalLink>\r\n }\r\n noText={true}\r\n />\r\n <Header title={translate('Third-party credits')} />\r\n <Row\r\n title={\r\n <ExternalLink url={LinkConstants.DBIP_URL}>\r\n IP Geolocation by DB-IP\r\n </ExternalLink>\r\n }\r\n noText={true}\r\n />\r\n </Grid>\r\n <InstallPrompt alwaysShow={true} />\r\n </>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(ApplicationPage, SystemConstants.STATS_URL, null, 5);\r\n","import * as React from 'react';\r\n\r\nimport { useFormatter } from 'context/FormatterContext';\r\n\r\nimport HubConstants from 'constants/HubConstants';\r\n\r\nimport StatisticsDecorator, {\r\n StatisticsDecoratorChildProps,\r\n} from 'decorators/StatisticsDecorator';\r\n\r\nimport { Grid, Row, Header } from 'components/semantic/Grid';\r\n\r\n//import * as UI from 'types/ui';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { formatAverage, formatPercentage } from 'utils/ValueFormat';\r\n\r\ninterface HubStatisticsPageProps extends SettingPageProps {}\r\n\r\ninterface ClientInfo {\r\n name: string;\r\n count: number;\r\n}\r\n\r\nconst formatClientRow = (uniqueUsers: number, client: ClientInfo) => {\r\n return (\r\n <Row\r\n key={client.name}\r\n title={client.name}\r\n text={`${client.count} (${formatPercentage(client.count, uniqueUsers)})`}\r\n />\r\n );\r\n};\r\n\r\nconst HubStatisticsPage: React.FC<\r\n HubStatisticsPageProps & StatisticsDecoratorChildProps<any>\r\n> = ({ stats, moduleT }) => {\r\n const { formatSize, formatConnection } = useFormatter();\r\n const { translate } = moduleT;\r\n return (\r\n <Grid columns=\"two\" stackable={true}>\r\n <Row title={translate('Total users')} text={stats.total_users} />\r\n <Row\r\n title={translate('Unique users')}\r\n text={`${stats.unique_users} (${formatPercentage(\r\n stats.unique_users,\r\n stats.total_users,\r\n )})`}\r\n />\r\n <Row\r\n title={translate('Active users')}\r\n text={`${stats.active_users} (${formatPercentage(\r\n stats.active_users,\r\n stats.unique_users,\r\n )})`}\r\n />\r\n <Row title={translate('Total share')} text={formatSize(stats.total_share)} />\r\n <Row\r\n title={translate('Average share per user')}\r\n text={formatSize(\r\n formatAverage(stats.total_share, stats.unique_users) as any as number,\r\n )}\r\n />\r\n <Row\r\n title={translate('Average ADC download speed')}\r\n text={formatConnection(stats.adc_down_per_user)}\r\n />\r\n <Row\r\n title={translate('Average ADC upload speed')}\r\n text={formatConnection(stats.adc_up_per_user)}\r\n />\r\n <Header title={translate('Clients')} />\r\n {stats.clients.map((c: ClientInfo) => formatClientRow(stats.unique_users, c))}\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(\r\n HubStatisticsPage,\r\n HubConstants.STATS_URL,\r\n (t, props) => props.moduleT.translate('No hubs online'),\r\n 10,\r\n);\r\n","import * as React from 'react';\r\n\r\nimport { useFormatter } from 'context/FormatterContext';\r\n\r\nimport ShareConstants from 'constants/ShareConstants';\r\n\r\nimport StatisticsDecorator, {\r\n StatisticsDecoratorChildProps,\r\n} from 'decorators/StatisticsDecorator';\r\n\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\n//import * as UI from 'types/ui';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { formatAverage, formatPercentage } from 'utils/ValueFormat';\r\n\r\ntype ShareStatisticsPageProps = SettingPageProps;\r\n\r\nconst ShareStatisticsPage: React.FC<\r\n ShareStatisticsPageProps & StatisticsDecoratorChildProps<any>\r\n> = ({ stats, moduleT }) => {\r\n const { formatSize, formatSeconds } = useFormatter();\r\n const { translate, t } = moduleT;\r\n return (\r\n <Grid columns=\"two\" stackable={true}>\r\n <Row title={translate('Total share size')} text={formatSize(stats.total_size)} />\r\n <Row\r\n title={translate('Total files')}\r\n // eslint-disable-next-line max-len\r\n text={t('totalFilesValue', {\r\n defaultValue: '{{totalCount}} ({{uniqueCount}} unique)',\r\n replace: {\r\n totalCount: stats.total_file_count,\r\n uniqueCount: formatPercentage(\r\n stats.unique_file_count,\r\n stats.total_file_count,\r\n ),\r\n },\r\n })}\r\n />\r\n <Row title={translate('Total directories')} text={stats.total_directory_count} />\r\n <Row\r\n title={translate('Average file age')}\r\n text={formatSeconds(stats.average_file_age)}\r\n />\r\n <Row\r\n title={translate('Average files per directory')}\r\n text={formatAverage(stats.total_file_count, stats.total_directory_count)}\r\n />\r\n\r\n <Header title={translate('Incoming searches')} />\r\n <Row\r\n title={translate('Total searches')}\r\n text={t('searchesTotalValue', {\r\n defaultValue: '{{totalCount}} ({{perSecondCount}} per second)',\r\n replace: {\r\n totalCount: stats.total_searches,\r\n perSecondCount: stats.total_searches_per_second.toFixed(1),\r\n },\r\n })}\r\n />\r\n <Row\r\n title={translate('TTH searches')}\r\n text={formatPercentage(stats.tth_searches, stats.total_searches)}\r\n />\r\n <Row\r\n title={translate('Text searches')}\r\n // eslint-disable-next-line max-len\r\n text={t('searchesPerSecondValue', {\r\n defaultValue: '{{totalCount}} ({{matchedCount}} matched per second)',\r\n replace: {\r\n totalCount: stats.recursive_searches,\r\n matchedCount: stats.unfiltered_recursive_searches_per_second.toFixed(2),\r\n },\r\n })}\r\n />\r\n <Row\r\n title={translate('Filtered text searches')}\r\n text={t('searchesFilteredValue', {\r\n defaultValue:\r\n '{{filteredPercentage}} ({{resultPercentage}} of the matched ones returned results)',\r\n replace: {\r\n filteredPercentage: formatPercentage(\r\n stats.filtered_searches,\r\n stats.recursive_searches,\r\n ),\r\n resultPercentage: formatPercentage(\r\n stats.recursive_searches_responded,\r\n stats.recursive_searches - stats.filtered_searches,\r\n ),\r\n },\r\n })}\r\n />\r\n <Row\r\n title={translate('Average text search tokens (non-filtered)')}\r\n // eslint-disable-next-line max-len\r\n text={t('searchesAverageTokensValue', {\r\n defaultValue: '{{tokenCount}} ({{tokenLength}} bytes per token)',\r\n replace: {\r\n tokenCount: stats.average_search_token_count.toFixed(1),\r\n tokenLength: stats.average_search_token_length.toFixed(1),\r\n },\r\n })}\r\n />\r\n <Row\r\n title={translate('Average matching time per text search')}\r\n text={t('searchesAverageMatchTimeValue', {\r\n defaultValue: '{{matchTime}} ms',\r\n replace: {\r\n matchTime: stats.average_match_ms,\r\n },\r\n })}\r\n />\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(\r\n ShareStatisticsPage,\r\n ShareConstants.STATS_URL,\r\n (t, props) => props.moduleT.translate('No files shared'),\r\n 60,\r\n);\r\n","import * as React from 'react';\r\n\r\nimport { useFormatter } from 'context/FormatterContext';\r\nimport { Row, Header, Grid } from 'components/semantic/Grid';\r\n\r\nimport TransferConstants from 'constants/TransferConstants';\r\nimport StatisticsDecorator, {\r\n StatisticsDecoratorChildProps,\r\n} from 'decorators/StatisticsDecorator';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\ninterface TransferStatisticsPageProps extends SettingPageProps {}\r\n\r\nconst TransferStatisticsPage: React.FC<\r\n TransferStatisticsPageProps & StatisticsDecoratorChildProps<any>\r\n> = ({ stats, moduleT }) => {\r\n const { translate } = moduleT;\r\n const { formatSize } = useFormatter();\r\n\r\n const totalUp = stats.session_uploaded + stats.start_total_uploaded;\r\n const totalDown = stats.session_downloaded + stats.start_total_downloaded;\r\n\r\n return (\r\n <Grid columns=\"two\" stackable={true}>\r\n <Row title={translate('Total downloaded')} text={formatSize(totalDown)} />\r\n <Row title={translate('Total uploaded')} text={formatSize(totalUp)} />\r\n <Header title={translate('Session')} />\r\n <Row\r\n title={translate('Session downloaded')}\r\n text={formatSize(stats.session_downloaded)}\r\n />\r\n <Row\r\n title={translate('Session uploaded')}\r\n text={formatSize(stats.session_uploaded)}\r\n />\r\n </Grid>\r\n );\r\n};\r\n\r\nexport default StatisticsDecorator(\r\n TransferStatisticsPage,\r\n TransferConstants.TRANSFERRED_BYTES_URL,\r\n null,\r\n 5,\r\n);\r\n","const MODULE_URL = 'connectivity';\nexport default {\n MODULE_URL: MODULE_URL,\n DETECT_URL: MODULE_URL + '/detect',\n STATUS_URL: MODULE_URL + '/status',\n\n CONNECTIVITY_MESSAGE: 'connectivity_detection_message',\n CONNECTIVITY_STARTED: 'connectivity_detection_started',\n CONNECTIVITY_FINISHED: 'connectivity_detection_finished',\n};\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import ConnectivityConstants from 'constants/ConnectivityConstants';\n\nimport IconConstants from 'constants/IconConstants';\n\nimport * as API from 'types/api';\nimport * as UI from 'types/ui';\n\nconst handleDetectConnection: UI.ActionHandler<void> = ({ socket }) => {\n return socket.post(ConnectivityConstants.DETECT_URL);\n};\n\nexport const ConnectivityDetectAction = {\n id: 'detect',\n displayName: 'Detect now',\n access: API.AccessEnum.SETTINGS_EDIT,\n icon: IconConstants.CONFIGURE,\n handler: handleDetectConnection,\n};\n\nexport const ConnectivityActionModule = {\n moduleId: UI.Modules.SETTINGS,\n};\n","import * as React from 'react';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport ConnectivityConstants from 'constants/ConnectivityConstants';\r\n\r\nimport { Row, Grid } from 'components/semantic/Grid';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport {\r\n ConnectivityActionModule,\r\n ConnectivityDetectAction,\r\n} from 'actions/ui/connectivity';\r\nimport Button from 'components/semantic/Button';\r\n\r\nconst formatProtocolStatus = (\r\n protocolStatus: API.ConnectivityProtocolStatus,\r\n running: boolean,\r\n moduleT: UI.ModuleTranslator,\r\n) => {\r\n const { translate, t } = moduleT;\r\n if (running) {\r\n return translate('Detecting...');\r\n }\r\n\r\n const auto = protocolStatus.auto_detect;\r\n const ret = t(auto ? 'autoDetected' : 'manualConfiguration', {\r\n defaultValue: auto\r\n ? '{{status}} (auto detected)'\r\n : '{{status}} (manual configuration)',\r\n replace: {\r\n status: protocolStatus.text,\r\n },\r\n });\r\n\r\n return ret;\r\n};\r\n\r\ninterface DetectPanelProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DetectPanelDataProps extends DataProviderDecoratorChildProps {\r\n status: API.ConnectivityStatus;\r\n runningV4: boolean;\r\n runningV6: boolean;\r\n}\r\n\r\nconst DetectPanel: React.FC<DetectPanelProps & DetectPanelDataProps> = ({\r\n status,\r\n runningV4,\r\n runningV6,\r\n moduleT,\r\n}) => {\r\n const [showDetails, setShowDetails] = React.useState(false);\r\n return (\r\n <div className=\"ui segment detect-panel\">\r\n <h3 className=\"header\">{moduleT.translate('Current auto detection status')}</h3>\r\n <Grid columns=\"two\">\r\n <Row\r\n title={moduleT.translate('IPv4 connectivity')}\r\n text={formatProtocolStatus(status.status_v4, runningV4, moduleT)}\r\n />\r\n <Row\r\n title={moduleT.translate('IPv6 connectivity')}\r\n text={formatProtocolStatus(status.status_v6, runningV6, moduleT)}\r\n />\r\n {showDetails && (\r\n <>\r\n <Row\r\n title={moduleT.translate('Bound interface (IPv4)')}\r\n text={status.status_v4.bind_address}\r\n />\r\n <Row\r\n title={moduleT.translate('Bound interface (IPv6)')}\r\n text={status.status_v6.bind_address}\r\n />\r\n <Row title={moduleT.translate('Transfer port')} text={status.tcp_port} />\r\n <Row\r\n title={moduleT.translate('Encrypted transfer port')}\r\n text={status.tls_port}\r\n />\r\n <Row title={moduleT.translate('Search/UDP port')} text={status.udp_port} />\r\n </>\r\n )}\r\n </Grid>\r\n <ActionButton\r\n className=\"detect-button\"\r\n action={ConnectivityDetectAction}\r\n moduleData={ConnectivityActionModule}\r\n disabled={!status.status_v4.auto_detect && !status.status_v6.auto_detect}\r\n loading={runningV6 || runningV4}\r\n />\r\n {!showDetails && (\r\n <Button\r\n icon=\"info\"\r\n caption={moduleT.translate('View all')}\r\n onClick={() => setShowDetails(!showDetails)}\r\n />\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<DetectPanelProps, DetectPanelDataProps>(\r\n DetectPanel,\r\n {\r\n urls: {\r\n status: ConnectivityConstants.STATUS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData, mergeData }) => {\r\n const setDetectState = (v6: boolean, running: boolean) => {\r\n const value = 'running' + (v6 ? 'V6' : 'V4');\r\n mergeData({\r\n [value]: running,\r\n });\r\n };\r\n\r\n addSocketListener<API.ConnectivityDetectionStarted>(\r\n ConnectivityConstants.MODULE_URL,\r\n ConnectivityConstants.CONNECTIVITY_STARTED,\r\n (data) => {\r\n setDetectState(data.v6, true);\r\n },\r\n );\r\n\r\n addSocketListener<API.ConnectivityDetectionFinished>(\r\n ConnectivityConstants.MODULE_URL,\r\n ConnectivityConstants.CONNECTIVITY_FINISHED,\r\n (data) => {\r\n setDetectState(data.v6, false);\r\n refetchData();\r\n },\r\n );\r\n },\r\n },\r\n);\r\n","import * as React from 'react';\r\n\r\nimport DetectPanel from 'routes/Settings/routes/Connectivity/components/DetectPanel';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport { Trans } from 'react-i18next';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nconst DetectionPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { toI18nKey } = moduleT;\r\n const defaults =\r\n \"In case of file transfer connectivity issues, please confirm that \\\r\nyour TCP ports are really open by using <portChecker>an online port checker</portChecker>. \\\r\nNote that validity of the UDP port (search) can't be checked online. \\\r\nFor more information about different connectivity modes, please visit <faq>DC++'s connectivity FAQ</faq>.\";\r\n\r\n return (\r\n <div>\r\n <DetectPanel moduleT={moduleT} />\r\n <Message\r\n description={\r\n <Trans\r\n i18nKey={toI18nKey('connectivityDetectionNote')}\r\n defaults={defaults}\r\n components={{\r\n portChecker: <ExternalLink url={LinkConstants.PORTCHECK_URL} />,\r\n faq: <ExternalLink url={LinkConstants.CONNECTIVITY_HELP_URL} />,\r\n }}\r\n />\r\n }\r\n icon={IconConstants.INFO}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DetectionPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'always_ccpm',\r\n 'tls_mode',\r\n 'tls_allow_untrusted_clients',\r\n 'tls_allow_untrusted_hubs',\r\n];\r\n\r\nconst Encryption: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default Encryption;\r\n","import * as React from 'react';\r\nimport ProtocolPage from 'routes/Settings/routes/Connectivity/components/ProtocolPage';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'connection_auto_v4',\r\n 'connection_bind_v4',\r\n 'connection_mode_v4',\r\n 'connection_ip_v4',\r\n 'connection_update_ip_v4',\r\n 'connection_ip_override_v4',\r\n];\r\n\r\nconst IPv4: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <ProtocolPage moduleT={moduleT} keys={Entry} protocol=\"v4\" />\r\n </div>\r\n);\r\n\r\nexport default IPv4;\r\n","import * as React from 'react';\r\nimport ProtocolPage from 'routes/Settings/routes/Connectivity/components/ProtocolPage';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'connection_auto_v6',\r\n 'connection_bind_v6',\r\n 'connection_mode_v6',\r\n 'connection_ip_v6',\r\n 'connection_update_ip_v6',\r\n 'connection_ip_override_v6',\r\n];\r\n\r\nconst IPv6: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <ProtocolPage keys={Entry} moduleT={moduleT} protocol=\"v6\" />\r\n </div>\r\n);\r\n\r\nexport default IPv6;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nconst Entry = ['tcp_port', 'udp_port', 'tls_port', 'preferred_port_mapper'];\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const translate = (text: string) => {\r\n return moduleT.t(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined),\r\n text,\r\n );\r\n };\r\n\r\n if (id === 'tcp_port') {\r\n fieldOptions.help = translate('TCP port is used for unencrypted transfers');\r\n } else if (id === 'tls_port') {\r\n fieldOptions.help = translate('TLS port (TCP) is used for encrypted transfers');\r\n } else if (id === 'udp_port') {\r\n fieldOptions.help = translate('UDP port is used for searching');\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\nconst PortsPage: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <Message\r\n description={moduleT.t(\r\n 'portsAutoValuesNote',\r\n 'Port numbers listed on this page can be overridden by port mappers (if enabled)',\r\n )}\r\n icon={IconConstants.INFO}\r\n />\r\n <RemoteSettingForm\r\n keys={Entry}\r\n onFieldSetting={FieldOptionGetter(moduleT)}\r\n valueMode={API.SettingValueMode.FORCE_MANUAL}\r\n />\r\n </div>\r\n);\r\n\r\nexport default PortsPage;\r\n","import { Component } from 'react';\r\nimport RemoteSettingForm, {\r\n RemoteSettingFormProps,\r\n} from 'routes/Settings/components/RemoteSettingForm';\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport { IncomingConnectionModeEnum } from 'constants/SettingConstants';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\ninterface ProtocolPageProps extends RemoteSettingFormProps {\r\n moduleT: UI.ModuleTranslator;\r\n protocol: string;\r\n}\r\n\r\nclass ProtocolPage extends Component<ProtocolPageProps> {\r\n state = {\r\n autoDetectEnabled: false,\r\n };\r\n\r\n convertValue = (key: string) => {\r\n return `${key}_${this.props.protocol}`;\r\n };\r\n\r\n onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const protocolEnabled =\r\n formValue[this.convertValue('connection_mode')] !==\r\n IncomingConnectionModeEnum.INCOMING_DISABLED;\r\n const autoDetect = formValue[this.convertValue('connection_auto')];\r\n\r\n if (\r\n (!protocolEnabled || autoDetect) &&\r\n (id.indexOf('connection_ip') === 0 ||\r\n id.indexOf('connection_bind') === 0 ||\r\n id.indexOf('connection_update_ip') === 0 ||\r\n id.indexOf('connection_ip_override') === 0)\r\n ) {\r\n fieldOptions.disabled = true;\r\n }\r\n\r\n if (autoDetect && id.indexOf('connection_mode') === 0 && protocolEnabled) {\r\n fieldOptions.disabled = true;\r\n }\r\n\r\n if (!protocolEnabled && id.indexOf('connection_auto') === 0) {\r\n fieldOptions.disabled = true;\r\n }\r\n };\r\n\r\n onSettingValuesReceived = (settings: API.SettingValueMap) => {\r\n this.setState({\r\n autoDetectEnabled: settings[this.convertValue('connection_auto')],\r\n });\r\n };\r\n\r\n render() {\r\n return (\r\n <div>\r\n {this.state.autoDetectEnabled && (\r\n <Message\r\n description={this.props.moduleT.t(\r\n 'protocolAutoValuesNote',\r\n 'Connectivity auto detection is currently enabled; setting values listed on this page are not being used',\r\n )}\r\n icon={IconConstants.INFO}\r\n />\r\n )}\r\n <RemoteSettingForm\r\n {...this.props}\r\n onFieldSetting={this.onFieldSetting}\r\n onSettingValuesReceived={this.onSettingValuesReceived}\r\n valueMode={API.SettingValueMode.FORCE_MANUAL}\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default ProtocolPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport { OutgoingConnectionModeEnum } from 'constants/SettingConstants';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nconst Entry = [\r\n 'outgoing_mode',\r\n 'socks_server',\r\n 'socks_port',\r\n 'socks_resolve',\r\n 'socks_user',\r\n 'socks_password',\r\n 'http_proxy',\r\n];\r\n\r\nconst onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n const socksEnabled =\r\n formValue.outgoing_mode === OutgoingConnectionModeEnum.OUTGOING_SOCKS;\r\n\r\n if (!socksEnabled && id.indexOf('socks_') === 0) {\r\n fieldOptions.disabled = true;\r\n }\r\n};\r\n\r\nconst Encryption: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} onFieldSetting={onFieldSetting} />\r\n </div>\r\n);\r\n\r\nexport default Encryption;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['allow_slow_overlap', 'finished_remove_exit', 'use_partial_sharing'];\r\n\r\nconst SegmentsEntry = ['segmented_downloads', 'min_segment_size'];\r\n\r\nconst BufferEntry = ['socket_read_buffer', 'socket_write_buffer', 'buffer_size'];\r\n\r\nconst CompressionEntry = ['compress_transfers', 'max_compression'];\r\n\r\nconst DownloadOptionsPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n <RemoteSettingForm keys={SegmentsEntry} title={translate('Segments')} />\r\n <RemoteSettingForm keys={CompressionEntry} title={translate('Compression')} />\r\n <RemoteSettingForm keys={BufferEntry} title={translate('Buffers')} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DownloadOptionsPage;\r\n","import FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst handleCreate: UI.ActionHandler<undefined> = ({ navigate }) => {\r\n navigate(`directories`);\r\n};\r\n\r\nconst handleEdit: UI.ActionHandler<API.FavoriteDirectoryEntry> = ({\r\n itemData: directory,\r\n navigate,\r\n}) => {\r\n navigate(`directories/${directory.id}`);\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.FavoriteDirectoryEntry> = ({\r\n itemData: directory,\r\n socket,\r\n}) => {\r\n return socket.delete(`${FavoriteDirectoryConstants.DIRECTORIES_URL}/${directory.id}`);\r\n};\r\n\r\nexport const FavoriteDirectoryCreateAction = {\r\n id: 'create',\r\n displayName: 'Add directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.CREATE,\r\n handler: handleCreate,\r\n};\r\n\r\nexport const FavoriteDirectoryEditAction = {\r\n id: 'edit',\r\n displayName: 'Edit directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.EDIT,\r\n handler: handleEdit,\r\n};\r\n\r\nexport const FavoriteDirectoryRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Remove directory',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REMOVE,\r\n confirmation: {\r\n content: 'Are you sure that you want to remove the favorite directory {{item.name}}?',\r\n approveCaption: 'Remove directory',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst FavoriteDirectoryEditActions: UI.ActionListType<API.FavoriteDirectoryEntry> = {\r\n edit: FavoriteDirectoryEditAction,\r\n remove: FavoriteDirectoryRemoveAction,\r\n};\r\n\r\nexport const FavoriteDirectoryActionModule = {\r\n moduleId: UI.Modules.SETTINGS,\r\n subId: 'favoriteDirectory',\r\n};\r\n\r\nexport const FavoriteDirectoryEditActionMenu = {\r\n moduleData: FavoriteDirectoryActionModule,\r\n actions: FavoriteDirectoryEditActions,\r\n};\r\n","import { useMemo, useRef } from 'react';\r\nimport RouteModal from 'components/semantic/RouteModal';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from 'decorators/ModalRouteDecorator';\r\n\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport { getLastDirectory } from 'utils/FileUtils';\r\n\r\nimport Form, {\r\n FormFieldChangeHandler,\r\n FormSaveHandler,\r\n FormFieldSettingHandler,\r\n} from 'components/form';\r\nimport { AutoSuggestField } from 'components/form/fields';\r\n\r\nimport FilesystemConstants from 'constants/FilesystemConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { translateForm } from 'utils/FormUtils';\r\n\r\nconst Entry: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'path',\r\n title: 'Path',\r\n type: API.SettingTypeEnum.DIRECTORY_PATH,\r\n },\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n];\r\n\r\nexport interface FavoriteDirectoryDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.FavoriteDirectoryEntryBase, UI.FormValueMap {}\r\n\r\nexport interface DataProps extends DataProviderDecoratorChildProps {\r\n virtualNames: string[];\r\n directoryEntry?: API.FavoriteDirectoryEntryBase;\r\n}\r\n\r\ntype Props = FavoriteDirectoryDialogProps & DataProps & ModalRouteDecoratorChildProps;\r\n\r\nconst FavoriteDirectoryDialog: React.FC<Props> = ({\r\n directoryEntry,\r\n moduleT,\r\n virtualNames,\r\n socket,\r\n}) => {\r\n const formRef = useRef<Form<Entry>>(null);\r\n const fieldDefinitions = useMemo(() => translateForm(Entry, moduleT), []);\r\n\r\n const isNew = !directoryEntry;\r\n\r\n const onFieldChanged: FormFieldChangeHandler<Entry> = (id, value, hasChanges) => {\r\n if (id.includes('path')) {\r\n return Promise.resolve({\r\n name: !!value.path ? getLastDirectory(value.path) : undefined,\r\n });\r\n }\r\n\r\n return null;\r\n };\r\n\r\n const handleSave = () => {\r\n return formRef.current!.save();\r\n };\r\n\r\n const onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (isNew) {\r\n return socket.post(FavoriteDirectoryConstants.DIRECTORIES_URL, changedFields);\r\n }\r\n\r\n return socket.patch(\r\n `${FavoriteDirectoryConstants.DIRECTORIES_URL}/${directoryEntry.id}`,\r\n changedFields,\r\n );\r\n };\r\n\r\n const onFieldSetting: FormFieldSettingHandler<Entry> = (\r\n id,\r\n fieldOptions,\r\n formValue,\r\n ) => {\r\n if (id === 'path') {\r\n fieldOptions.disabled = !isNew;\r\n fieldOptions.config = Object.assign(fieldOptions.config || {}, {\r\n historyId: FilesystemConstants.LOCATION_DOWNLOAD,\r\n });\r\n } else if (id === 'name') {\r\n fieldOptions.factory = t.form.Textbox;\r\n fieldOptions.template = AutoSuggestField;\r\n fieldOptions.config = {\r\n suggestionGetter: () => virtualNames,\r\n };\r\n }\r\n };\r\n\r\n const title = moduleT.translate(\r\n isNew ? 'Add favorite directory' : 'Edit favorite directory',\r\n );\r\n\r\n return (\r\n <RouteModal\r\n className=\"favorite-directory\"\r\n title={title}\r\n onApprove={handleSave}\r\n closable={false}\r\n icon={IconConstants.FOLDER}\r\n >\r\n <Form<Entry>\r\n ref={formRef}\r\n fieldDefinitions={fieldDefinitions}\r\n onFieldChanged={onFieldChanged}\r\n onFieldSetting={onFieldSetting}\r\n onSave={onSave}\r\n sourceValue={directoryEntry as Entry}\r\n />\r\n </RouteModal>\r\n );\r\n};\r\n\r\nexport default ModalRouteDecorator<FavoriteDirectoryDialogProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(\r\n FavoriteDirectoryDialog,\r\n {\r\n urls: {\r\n virtualNames: FavoriteDirectoryConstants.GROUPED_DIRECTORIES_URL,\r\n directoryEntry: ({ params }, socket) => {\r\n if (!params.directoryId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(\r\n `${FavoriteDirectoryConstants.DIRECTORIES_URL}/${params.directoryId}`,\r\n );\r\n },\r\n },\r\n dataConverters: {\r\n virtualNames: (data: API.GroupedPath[]) => data.map((item) => item.name, []),\r\n },\r\n },\r\n ),\r\n 'directories/:directoryId?',\r\n);\r\n","import * as React from 'react';\r\n\r\nimport {\r\n FavoriteDirectoryActionModule,\r\n FavoriteDirectoryCreateAction,\r\n FavoriteDirectoryEditActionMenu,\r\n} from 'actions/ui/favorite-directory/FavoriteDirectoryActions';\r\nimport FavoriteDirectoryConstants from 'constants/FavoriteDirectoryConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/action-menu';\r\nimport FavoriteDirectoryDialog from 'routes/Settings/routes/Downloads/components/FavoriteDirectoryDialog';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst Row: React.FC<{ directory: API.FavoriteDirectoryEntry }> = ({ directory }) => (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu\r\n caption={<strong>{directory.name}</strong>}\r\n actions={FavoriteDirectoryEditActionMenu}\r\n itemData={directory}\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"path\">{directory.path}</td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (directory: API.FavoriteDirectoryEntry) => {\r\n return <Row key={directory.path} directory={directory} />;\r\n};\r\n\r\ninterface FavoriteDirectoryPageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface FavoriteDirectoryPageDataProps extends DataProviderDecoratorChildProps {\r\n directories: API.FavoriteDirectoryEntry[];\r\n}\r\n\r\nconst FavoriteDirectoryPage: React.FC<\r\n FavoriteDirectoryPageProps & FavoriteDirectoryPageDataProps\r\n> = ({ directories, moduleT }) => (\r\n <div id=\"directory-table\">\r\n <ActionButton\r\n action={FavoriteDirectoryCreateAction}\r\n moduleData={FavoriteDirectoryActionModule}\r\n />\r\n\r\n {directories.length === 0 ? null : (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{moduleT.translate('Name')}</th>\r\n <th>{moduleT.translate('Path')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>{directories.map(getRow)}</tbody>\r\n </table>\r\n )}\r\n <FavoriteDirectoryDialog moduleT={moduleT} />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<\r\n FavoriteDirectoryPageProps,\r\n FavoriteDirectoryPageDataProps\r\n>(FavoriteDirectoryPage, {\r\n urls: {\r\n directories: FavoriteDirectoryConstants.DIRECTORIES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n FavoriteDirectoryConstants.MODULE_URL,\r\n FavoriteDirectoryConstants.DIRECTORIES_UPDATED,\r\n () => refetchData(),\r\n );\r\n },\r\n});\r\n","import * as React from 'react';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport FavoriteDirectoryTable from 'routes/Settings/routes/Downloads/components/FavoriteDirectoryTable';\r\nimport LayoutHeader from 'components/semantic/LayoutHeader';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nconst Entry = ['download_directory'];\r\n\r\nconst LocationsPage: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n\r\n <Message\r\n description={\r\n <ExternalLink url={LinkConstants.VARIABLE_HELP_URL}>\r\n {moduleT.translate('Available path variables')}\r\n </ExternalLink>\r\n }\r\n icon={IconConstants.INFO}\r\n />\r\n\r\n <div className=\"ui segment setting-form\">\r\n <LayoutHeader\r\n title={moduleT.translate('Favorite download directories')}\r\n icon={IconConstants.FOLDER}\r\n size=\"normal\"\r\n />\r\n <FavoriteDirectoryTable moduleT={moduleT} />\r\n </div>\r\n </div>\r\n);\r\n\r\nexport default LocationsPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'prio_highest_size',\r\n 'prio_high_size',\r\n 'prio_normal_size',\r\n 'prio_auto_default',\r\n];\r\n\r\nconst HighPrioEntry = [\r\n 'prio_high_files_to_highest',\r\n 'prio_high_files',\r\n 'prio_high_files_regex',\r\n];\r\n\r\nconst PrioritiesPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm title={translate('File priorities')} keys={Entry} />\r\n <RemoteSettingForm title={translate('High priority files')} keys={HighPrioEntry} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default PrioritiesPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'auto_add_sources',\r\n 'alt_search_auto',\r\n 'alt_search_max_sources',\r\n 'max_sources_match_queue',\r\n 'allow_match_full_list',\r\n];\r\n\r\nconst SearchMatchingPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default SearchMatchingPage;\r\n","import { useMemo, useRef } from 'react';\r\nimport RouteModal from 'components/semantic/RouteModal';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from 'decorators/ModalRouteDecorator';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport Form, { FormFieldSettingHandler, FormSaveHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { translateForm } from 'utils/FormUtils';\r\nimport SearchConstants from 'constants/SearchConstants';\r\n\r\nconst Entry: UI.FormFieldDefinition[] = [\r\n {\r\n key: 'name',\r\n title: 'Name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'extensions',\r\n title: 'File extensions',\r\n type: API.SettingTypeEnum.LIST,\r\n item_type: API.SettingTypeEnum.STRING,\r\n },\r\n];\r\n\r\nexport interface SearchTypeDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.SearchType, UI.FormValueMap {}\r\n\r\nexport interface DataProps extends DataProviderDecoratorChildProps {\r\n searchTypeEntry?: API.SearchType;\r\n}\r\n\r\ntype Props = SearchTypeDialogProps & DataProps & ModalRouteDecoratorChildProps;\r\n\r\nconst SearchTypeDialog: React.FC<Props> = ({\r\n moduleT,\r\n searchTypeEntry,\r\n socket,\r\n ...other\r\n}) => {\r\n const isNew = !searchTypeEntry;\r\n\r\n const formRef = useRef<Form<Entry>>(null);\r\n const definitions = useMemo(() => translateForm(Entry, moduleT), []);\r\n\r\n const handleSave = () => {\r\n return formRef.current!.save();\r\n };\r\n\r\n const onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (isNew) {\r\n return socket.post(SearchConstants.SEARCH_TYPES_URL, changedFields);\r\n }\r\n\r\n return socket.patch(\r\n `${SearchConstants.SEARCH_TYPES_URL}/${searchTypeEntry.id}`,\r\n changedFields,\r\n );\r\n };\r\n\r\n const onFieldSetting: FormFieldSettingHandler<Entry> = (\r\n id,\r\n fieldOptions,\r\n formValue,\r\n ) => {\r\n if (id === 'name') {\r\n fieldOptions.disabled = !!searchTypeEntry && searchTypeEntry.default_type;\r\n }\r\n };\r\n\r\n const title = moduleT.translate(isNew ? 'Add search type' : 'Edit search type');\r\n return (\r\n <RouteModal\r\n className=\"search-type\"\r\n title={title}\r\n onApprove={handleSave}\r\n closable={false}\r\n icon={IconConstants.FOLDER}\r\n {...other}\r\n >\r\n <Form<Entry>\r\n ref={formRef}\r\n fieldDefinitions={definitions}\r\n onFieldSetting={onFieldSetting}\r\n onSave={onSave}\r\n sourceValue={searchTypeEntry as Entry}\r\n />\r\n </RouteModal>\r\n );\r\n};\r\n\r\nexport default ModalRouteDecorator<SearchTypeDialogProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(SearchTypeDialog, {\r\n urls: {\r\n searchTypeEntry: ({ params }, socket) => {\r\n if (!params.searchTypeId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${SearchConstants.SEARCH_TYPES_URL}/${params.searchTypeId}`);\r\n },\r\n },\r\n }),\r\n 'types/:searchTypeId?',\r\n);\r\n","import * as React from 'react';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/action-menu';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport {\r\n SearchTypeActionModule,\r\n SearchTypeCreateAction,\r\n SearchTypeEditActionMenu,\r\n} from 'actions/ui/search/SearchTypeActions';\r\nimport SearchConstants from 'constants/SearchConstants';\r\nimport SearchTypeDialog from './SearchTypeDialog';\r\nimport Message from 'components/semantic/Message';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { useFormatter } from 'context/FormatterContext';\r\n\r\nconst Row: React.FC<{ type: API.SearchType; moduleT: UI.ModuleTranslator }> = ({\r\n type,\r\n moduleT,\r\n}) => {\r\n const { formatBoolean } = useFormatter();\r\n return (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu\r\n caption={<strong>{type.str}</strong>}\r\n actions={SearchTypeEditActionMenu}\r\n itemData={type}\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"extensions\">{type.extensions.join(', ')}</td>\r\n <td className=\"default\">{formatBoolean(type.default_type)}</td>\r\n </tr>\r\n );\r\n};\r\n\r\nconst getRow = (type: API.SearchType, moduleT: UI.ModuleTranslator) => {\r\n return <Row key={type.id} type={type} moduleT={moduleT} />;\r\n};\r\n\r\ninterface SearchTypesPageProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n searchTypes: API.SearchType[];\r\n}\r\n\r\ntype Props = SearchTypesPageProps & DataProps;\r\n\r\nconst SearchTypesPage: React.FC<Props> = ({ searchTypes, moduleT }) => (\r\n <div id=\"directory-table\">\r\n <ActionButton action={SearchTypeCreateAction} moduleData={SearchTypeActionModule} />\r\n\r\n {searchTypes.length === 0 ? null : (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{moduleT.translate('Name')}</th>\r\n <th>{moduleT.translate('File extensions')}</th>\r\n <th>{moduleT.translate('Default')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>{searchTypes.map((type) => getRow(type, moduleT))}</tbody>\r\n </table>\r\n )}\r\n <Message\r\n icon={IconConstants.NOTE}\r\n description={moduleT.t(\r\n 'searchTypesNote',\r\n // eslint-disable-next-line max-len\r\n 'Note; Custom search types will only be applied to ADC hubs! On NMDC hubs, using a predefined search type will only search for a set of predefined, unconfigurable extensions; using a custom type will default to searching for any extension.',\r\n )}\r\n />\r\n <SearchTypeDialog moduleT={moduleT} />\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<SearchTypesPageProps, DataProps>(SearchTypesPage, {\r\n urls: {\r\n searchTypes: SearchConstants.SEARCH_TYPES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n SearchConstants.MODULE_URL,\r\n SearchConstants.SEARCH_TYPES_UPDATED,\r\n () => refetchData(),\r\n );\r\n },\r\n});\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['dont_download_shared', 'dont_download_queued', 'download_dupe_min_size'];\r\n\r\nconst Skiplist = ['download_skiplist', 'download_skiplist_regex'];\r\n\r\nconst SkippingOptionsPage: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n <RemoteSettingForm title={moduleT.translate('Skiplist')} keys={Skiplist} />\r\n </div>\r\n);\r\n\r\nexport default SkippingOptionsPage;\r\n","import * as React from 'react';\n\nimport ExtensionConstants from 'constants/ExtensionConstants';\nimport LinkConstants from 'constants/LinkConstants';\nimport DataProviderDecorator, {\n DataProviderDecoratorChildProps,\n} from 'decorators/DataProviderDecorator';\n\nimport ExternalLink from 'components/ExternalLink';\nimport Message from 'components/semantic/Message';\n\nimport * as API from 'types/api';\nimport * as UI from 'types/ui';\n\nimport { Trans } from 'react-i18next';\nimport IconConstants from 'constants/IconConstants';\n\ninterface EngineStatusMessageProps {\n moduleT: UI.ModuleTranslator;\n}\n\ninterface EngineStatusMessageDataProps extends DataProviderDecoratorChildProps {\n enginesStatus: API.ExtensionEngineStatus;\n}\n\n// Show an info message if the default extension engine is not installed\nconst EngineStatusMessage: React.FC<\n EngineStatusMessageProps & EngineStatusMessageDataProps\n> = ({ enginesStatus, moduleT }) => {\n if (enginesStatus[ExtensionConstants.DEFAULT_ENGINE]) {\n return null;\n }\n\n const defaults =\n \"The default extension engine <strong>{{engineName}}</strong> is not installed on your system. \\\nPlease visit <url>engine's home page</url> for installation instructions.\";\n\n return (\n <Message\n description={\n <Trans\n i18nKey={moduleT.toI18nKey('defaultExtensionEngineMissing')}\n defaults={defaults}\n values={{\n engineName: ExtensionConstants.DEFAULT_ENGINE,\n }}\n components={{\n url: <ExternalLink url={LinkConstants.DEFAULT_ENGINE_URL} />,\n }}\n />\n }\n icon={IconConstants.WARNING}\n />\n );\n};\n\nexport default DataProviderDecorator<\n EngineStatusMessageProps,\n EngineStatusMessageDataProps\n>(EngineStatusMessage, {\n urls: {\n enginesStatus: ExtensionConstants.ENGINES_STATUS_URL,\n },\n loaderText: null,\n});\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['extension_engines'];\r\n\r\nconst ExtensionEnginesPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default ExtensionEnginesPage;\r\n","import * as React from 'react';\r\n\r\nimport Extension from 'routes/Settings/routes/Extensions/components/extension/Extension';\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport 'fomantic-ui-css/components/item.min.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\ninterface NpmPackageLayoutProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface NpmCatalogItem {\r\n package: UI.NpmPackage;\r\n}\r\n\r\ninterface NpmPackageLayoutDataProps extends DataProviderDecoratorChildProps {\r\n installedPackages: API.Extension[];\r\n packageCatalog: NpmCatalogItem[];\r\n}\r\n\r\nconst getItem = (\r\n npmPackage: UI.NpmPackage,\r\n moduleT: UI.ModuleTranslator,\r\n installedPackages: API.Extension[],\r\n) => {\r\n const installedPackage = installedPackages.find((p) => p.name === npmPackage.name);\r\n return (\r\n <Extension\r\n key={npmPackage.name}\r\n npmPackage={npmPackage}\r\n installedPackage={installedPackage}\r\n moduleT={moduleT}\r\n />\r\n );\r\n};\r\n\r\nconst NpmPackageLayout: React.FC<NpmPackageLayoutProps & NpmPackageLayoutDataProps> = ({\r\n packageCatalog,\r\n moduleT,\r\n installedPackages,\r\n}) => (\r\n <div className=\"extension-layout\">\r\n <div className=\"ui divider\" />\r\n {packageCatalog.length > 0 && (\r\n <div className=\"ui divided items\">\r\n {packageCatalog.map((data) => getItem(data.package, moduleT, installedPackages))}\r\n </div>\r\n )}\r\n </div>\r\n);\r\n\r\nexport default DataProviderDecorator<NpmPackageLayoutProps, NpmPackageLayoutDataProps>(\r\n NpmPackageLayout,\r\n {\r\n urls: {\r\n installedPackages: ExtensionConstants.EXTENSIONS_URL,\r\n packageCatalog: () => fetchCorsSafeData(ExtensionConstants.NPM_PACKAGES_URL, true),\r\n },\r\n dataConverters: {\r\n packageCatalog: ({ objects }) => objects,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n const refetchInstalled = () => refetchData(['installedPackages']);\r\n\r\n addSocketListener(\r\n ExtensionConstants.MODULE_URL,\r\n ExtensionConstants.ADDED,\r\n refetchInstalled,\r\n );\r\n addSocketListener(\r\n ExtensionConstants.MODULE_URL,\r\n ExtensionConstants.REMOVED,\r\n refetchInstalled,\r\n );\r\n addSocketListener(\r\n ExtensionConstants.MODULE_URL,\r\n ExtensionConstants.UPDATED,\r\n refetchInstalled,\r\n );\r\n },\r\n },\r\n);\r\n","import * as React from 'react';\n\nimport {\n ExtensionInstallActionModule,\n ExtensionInstallURLAction,\n} from 'actions/ui/extension/ExtensionInstallActions';\n\nimport ActionButton from 'components/ActionButton';\n\nimport EngineStatusMessage from 'routes/Settings/routes/Extensions/components/EngineStatusMessage';\nimport NpmPackageLayout from 'routes/Settings/routes/Extensions/components/NpmPackageLayout';\nimport ExtensionsConfigureDialog from 'routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog';\n\nimport * as UI from 'types/ui';\n\ninterface ExtensionBrowsePageProps {\n moduleT: UI.ModuleTranslator;\n}\n\nconst ExtensionBrowsePage: React.FC<ExtensionBrowsePageProps> = ({ moduleT }) => {\n return (\n <>\n <EngineStatusMessage moduleT={moduleT} />\n <div className=\"table-actions\">\n <ActionButton\n action={ExtensionInstallURLAction}\n moduleData={ExtensionInstallActionModule}\n className=\"add\"\n />\n </div>\n <NpmPackageLayout moduleT={moduleT} />\n <ExtensionsConfigureDialog />\n </>\n );\n};\n\nexport default ExtensionBrowsePage;\n","import { useRef } from 'react';\r\n\r\nimport RouteModal from 'components/semantic/RouteModal';\r\nimport Form, { FormSaveHandler } from 'components/form/Form';\r\n\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from 'decorators/ModalRouteDecorator';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nconst getSettingsUrl = (extensionId: string) => {\r\n return `${ExtensionConstants.EXTENSIONS_URL}/${extensionId}/settings`;\r\n};\r\n\r\ninterface ExtensionsConfigureDialogProps {}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n fieldDefinitions: UI.FormFieldDefinition[];\r\n settings: UI.FormValueMap;\r\n extension: API.Extension;\r\n}\r\n\r\ntype Props = ExtensionsConfigureDialogProps & DataProps & ModalRouteDecoratorChildProps;\r\n\r\nconst ExtensionsConfigureDialog: React.FC<Props> = ({\r\n extension,\r\n settings,\r\n fieldDefinitions,\r\n socket,\r\n ...other\r\n}) => {\r\n const formRef = useRef<Form>(null);\r\n const handleSave = () => {\r\n return formRef.current!.save();\r\n };\r\n\r\n const onSave: FormSaveHandler<UI.FormValueMap> = (changedFields) => {\r\n return socket.patch(getSettingsUrl(extension.id), changedFields);\r\n };\r\n\r\n return (\r\n <RouteModal\r\n {...other}\r\n className=\"extensions configure\"\r\n title={extension.name}\r\n onApprove={handleSave}\r\n closable={false}\r\n icon={IconConstants.EDIT}\r\n dynamicHeight={true}\r\n >\r\n <Form\r\n ref={formRef}\r\n onSave={onSave}\r\n fieldDefinitions={fieldDefinitions}\r\n sourceValue={settings}\r\n />\r\n </RouteModal>\r\n );\r\n};\r\n\r\nexport default ModalRouteDecorator<ExtensionsConfigureDialogProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(\r\n ExtensionsConfigureDialog,\r\n {\r\n urls: {\r\n fieldDefinitions: ({ params }, socket) => {\r\n return socket.get(`${getSettingsUrl(params.extensionId!)}/definitions`);\r\n },\r\n settings: ({ params }, socket) => socket.get(getSettingsUrl(params.extensionId!)),\r\n extension: ({ params }, socket) => {\r\n return socket.get(`${ExtensionConstants.EXTENSIONS_URL}/${params.extensionId}`);\r\n },\r\n },\r\n },\r\n ),\r\n 'extensions/:extensionId',\r\n);\r\n","import DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport Extension from 'routes/Settings/routes/Extensions/components/extension/Extension';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { fetchCorsSafeData } from 'services/HttpService';\r\n\r\nexport interface NpmPackageData {\r\n name: string;\r\n description: string;\r\n version: string;\r\n _npmUser: {\r\n name: string;\r\n };\r\n}\r\n\r\n// The npm registry API returns different data/fieldnames for different calls\r\n// so we must do some conversions (the primary data format is the one used by the package search method)\r\nconst convertNpmPackage = ({\r\n name,\r\n description,\r\n version,\r\n _npmUser,\r\n}: NpmPackageData): UI.NpmPackage => {\r\n return {\r\n id: name,\r\n name,\r\n description,\r\n version,\r\n publisher: {\r\n username: _npmUser.name,\r\n },\r\n date: '',\r\n };\r\n};\r\n\r\ninterface LocalExtensionProps {\r\n installedPackage: API.Extension;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface LocalExtensionDataProps extends DataProviderDecoratorChildProps {\r\n npmPackage: NpmPackageData;\r\n}\r\n\r\nconst LocalExtension = DataProviderDecorator<\r\n LocalExtensionProps,\r\n LocalExtensionDataProps\r\n>(\r\n ({ installedPackage, npmPackage, dataError, moduleT }) => (\r\n <Extension\r\n key={installedPackage.name}\r\n installedPackage={installedPackage}\r\n npmPackage={!!npmPackage ? convertNpmPackage(npmPackage) : undefined}\r\n npmError={dataError}\r\n moduleT={moduleT}\r\n />\r\n ),\r\n {\r\n urls: {\r\n npmPackage: ({ installedPackage }) => {\r\n if (installedPackage.private || !installedPackage.managed) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return fetchCorsSafeData(\r\n `${ExtensionConstants.NPM_PACKAGE_URL}${installedPackage.name}/latest`,\r\n true,\r\n );\r\n },\r\n },\r\n renderOnError: true,\r\n },\r\n);\r\n\r\nexport default LocalExtension;\r\n","import * as React from 'react';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport EngineStatusMessage from 'routes/Settings/routes/Extensions/components/EngineStatusMessage';\r\nimport ExtensionsConfigureDialog from 'routes/Settings/routes/Extensions/components/ExtensionsConfigureDialog';\r\n\r\nimport { Link } from 'react-router';\r\nimport Message from 'components/semantic/Message';\r\nimport LocalExtension from 'routes/Settings/routes/Extensions/components/LocalExtension';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\ninterface ExtensionsManagePageProps extends SettingPageProps {}\r\n\r\ninterface ExtensionsManagePageDataProps extends DataProviderDecoratorChildProps {\r\n installedPackages: API.Extension[];\r\n}\r\n\r\nconst getItem = (extension: API.Extension, moduleT: UI.ModuleTranslator) => {\r\n return (\r\n <LocalExtension key={extension.name} installedPackage={extension} moduleT={moduleT} />\r\n );\r\n};\r\n\r\nconst ExtensionsManagePage: React.FC<\r\n ExtensionsManagePageProps & ExtensionsManagePageDataProps\r\n> = ({ installedPackages, moduleT }) => {\r\n if (installedPackages.length === 0) {\r\n const defaults =\r\n 'No installed extensions were found. \\\r\nNew extensions can be installed from the <url>Extension catalog</url> page.';\r\n return (\r\n <Message\r\n description={\r\n <Trans\r\n i18nKey={moduleT.toI18nKey('noInstalledExtensions')}\r\n defaults={defaults}\r\n components={{\r\n url: <Link to=\"/settings/extensions/packages\" />,\r\n }}\r\n />\r\n }\r\n icon={IconConstants.INFO}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"extension-layout\">\r\n <EngineStatusMessage moduleT={moduleT} />\r\n <div className=\"ui divider\" />\r\n <div className=\"ui divided items\">\r\n {installedPackages.map((p) => getItem(p, moduleT))}\r\n </div>\r\n <ExtensionsConfigureDialog />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<\r\n ExtensionsManagePageProps,\r\n ExtensionsManagePageDataProps\r\n>(ExtensionsManagePage, {\r\n urls: {\r\n installedPackages: ExtensionConstants.EXTENSIONS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.ADDED, () =>\r\n refetchData(),\r\n );\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.REMOVED, () =>\r\n refetchData(),\r\n );\r\n addSocketListener(ExtensionConstants.MODULE_URL, ExtensionConstants.UPDATED, () =>\r\n refetchData(),\r\n );\r\n },\r\n});\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'extensions_debug_mode',\r\n 'extensions_auto_update',\r\n 'extensions_init_timeout',\r\n];\r\n\r\nconst ExtensionOptionsPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default ExtensionOptionsPage;\r\n","import ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { MENU_DIVIDER } from 'constants/ActionConstants';\r\n\r\ntype Filter = UI.ActionFilter<API.Extension>;\r\nconst isManaged: Filter = ({ itemData: extension }) => extension.managed;\r\nconst isRunning: Filter = ({ itemData: extension }) => extension.running;\r\nconst isDisabled: Filter = ({ itemData: extension }) => extension.disabled;\r\nconst hasSettings: Filter = ({ itemData: extension }) => extension.has_settings;\r\n\r\nconst canStart: Filter = (data) => isManaged(data) && !isRunning(data);\r\nconst canStop: Filter = (data) => isManaged(data) && isRunning(data);\r\n\r\nconst canDisable: Filter = (data) => isManaged(data) && !isDisabled(data);\r\nconst canEnable: Filter = (data) => isManaged(data) && isDisabled(data);\r\n\r\nconst handleConfigure: UI.ActionHandler<API.Extension> = ({\r\n itemData: extension,\r\n navigate,\r\n}) => {\r\n navigate(`extensions/${extension.id}`);\r\n};\r\n\r\nconst handleStart: UI.ActionHandler<API.Extension> = ({\r\n itemData: extension,\r\n socket,\r\n}) => {\r\n return socket.post(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}/start`);\r\n};\r\n\r\nconst handleStop: UI.ActionHandler<API.Extension> = ({ itemData: extension, socket }) => {\r\n return socket.post(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}/stop`);\r\n};\r\n\r\nconst handleDisable: UI.ActionHandler<API.Extension> = ({\r\n itemData: extension,\r\n socket,\r\n}) => {\r\n return socket.patch(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}`, {\r\n disabled: true,\r\n });\r\n};\r\n\r\nconst handleEnable: UI.ActionHandler<API.Extension> = ({\r\n itemData: extension,\r\n socket,\r\n}) => {\r\n return socket.patch(`${ExtensionConstants.EXTENSIONS_URL}/${extension.name}`, {\r\n disabled: false,\r\n });\r\n};\r\n\r\nconst handleRemove: UI.ActionHandler<API.Extension> = ({ itemData, socket }) => {\r\n return socket.delete(ExtensionConstants.EXTENSIONS_URL + '/' + itemData.name);\r\n};\r\n\r\nexport const ExtensionStartAction = {\r\n id: 'start',\r\n displayName: 'Start',\r\n icon: IconConstants.PLAY,\r\n filter: canStart,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleStart,\r\n};\r\n\r\nexport const ExtensionStopAction = {\r\n id: 'stop',\r\n displayName: 'Stop',\r\n icon: IconConstants.STOP,\r\n filter: canStop,\r\n access: API.AccessEnum.ADMIN,\r\n handler: handleStop,\r\n};\r\n\r\nexport const ExtensionConfigureAction = {\r\n id: 'configure',\r\n displayName: 'Configure',\r\n icon: IconConstants.EDIT,\r\n filter: hasSettings,\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n handler: handleConfigure,\r\n};\r\n\r\nexport const ExtensionDisableAction = {\r\n id: 'disable',\r\n displayName: 'Disable',\r\n icon: IconConstants.DISABLE,\r\n filter: canDisable,\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n handler: handleDisable,\r\n};\r\n\r\nexport const ExtensionEnableAction = {\r\n id: 'enable',\r\n displayName: 'Enable',\r\n icon: IconConstants.ENABLE,\r\n filter: canEnable,\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n handler: handleEnable,\r\n};\r\n\r\nexport const ExtensionRemoveAction = {\r\n id: 'remove',\r\n displayName: 'Uninstall',\r\n icon: IconConstants.REMOVE,\r\n filter: isManaged,\r\n access: API.AccessEnum.ADMIN,\r\n confirmation: {\r\n content:\r\n // eslint-disable-next-line max-len\r\n 'Are you sure that you want to remove the extension {{item.name}}? This will also remove possible extension-specific settings.',\r\n approveCaption: 'Remove extension',\r\n rejectCaption: `Don't remove`,\r\n },\r\n handler: handleRemove,\r\n};\r\n\r\nconst ExtensionManageActions: UI.ActionListType<API.Extension> = {\r\n start: ExtensionStartAction,\r\n stop: ExtensionStopAction,\r\n configure: ExtensionConfigureAction,\r\n disable: ExtensionDisableAction,\r\n enable: ExtensionEnableAction,\r\n divider: MENU_DIVIDER,\r\n remove: ExtensionRemoveAction,\r\n};\r\n\r\nexport const ExtensionManageActionModule = {\r\n moduleId: UI.Modules.EXTENSIONS,\r\n};\r\n\r\nexport const ExtensionManageActionsMenu = {\r\n moduleData: ExtensionManageActionModule,\r\n actions: ExtensionManageActions,\r\n};\r\n","import * as React from 'react';\n\nimport {\n ExtensionInstallNpmAction,\n ExtensionUpdateNpmAction,\n} from 'actions/ui/extension/ExtensionInstallActions';\nimport ExtensionConstants from 'constants/ExtensionConstants';\n\nimport ActionButton from 'components/ActionButton';\nimport ExternalLink from 'components/ExternalLink';\n\nimport * as API from 'types/api';\nimport * as UI from 'types/ui';\nimport { ActionMenu } from 'components/action-menu';\nimport MenuConstants from 'constants/MenuConstants';\nimport IconConstants from 'constants/IconConstants';\nimport Icon from 'components/semantic/Icon';\nimport {\n ExtensionManageActionModule,\n ExtensionManageActionsMenu,\n ExtensionStartAction,\n ExtensionStopAction,\n} from 'actions/ui/extension/ExtensionManageActions';\n\nexport interface ExtensionActionButtonsProps {\n npmPackage?: UI.NpmPackage;\n installedPackage?: API.Extension;\n hasUpdate: boolean;\n installing: boolean;\n moduleT: UI.ModuleTranslator;\n}\n\ntype InstallButtonProps = Omit<ExtensionActionButtonsProps, 'moduleT'>;\n\nconst InstallButton: React.FC<InstallButtonProps> = ({\n npmPackage,\n installedPackage,\n hasUpdate,\n installing,\n}) => {\n if (installedPackage && !hasUpdate) {\n return null;\n }\n\n return (\n <ActionButton\n action={hasUpdate ? ExtensionUpdateNpmAction : ExtensionInstallNpmAction}\n moduleData={ExtensionManageActionModule}\n className=\"right floated primary\"\n itemData={npmPackage}\n loading={installing}\n />\n );\n};\n\nconst ExtensionActionButtons: React.FC<ExtensionActionButtonsProps> = ({\n npmPackage,\n installedPackage,\n hasUpdate,\n installing,\n moduleT,\n}) => (\n <div className=\"extra buttons\">\n {npmPackage && (\n <InstallButton\n npmPackage={npmPackage}\n installedPackage={installedPackage}\n hasUpdate={hasUpdate}\n installing={installing}\n />\n )}\n {installedPackage && (\n <ActionMenu\n actions={ExtensionManageActionsMenu}\n ids={['configure', 'enable', 'disable', 'divider', 'remove']}\n remoteMenuId={MenuConstants.EXTENSION}\n remoteMenuNestingThreshold={10}\n itemData={installedPackage}\n className=\"right floated\"\n caption={moduleT.translate('Manage...')}\n button={true}\n contextElement=\"#setting-scroll-context\"\n menuElementClassName=\"left floated\"\n />\n )}\n {npmPackage && (\n <ExternalLink\n className=\"ui right floated button\"\n url={ExtensionConstants.NPM_HOMEPAGE_URL + npmPackage.name}\n >\n <Icon icon={IconConstants.EXTERNAL} />\n {moduleT.translate('Read more')}\n </ExternalLink>\n )}\n {installedPackage && (\n <ActionButton\n action={installedPackage.running ? ExtensionStopAction : ExtensionStartAction}\n moduleData={ExtensionManageActionModule}\n className=\"right floated\"\n itemData={installedPackage}\n />\n )}\n </div>\n);\n\nexport default ExtensionActionButtons;\n","import * as React from 'react';\r\nimport Moment from 'moment';\r\n\r\nimport ExtensionConstants from 'constants/ExtensionConstants';\r\n\r\nimport ExtensionIcon from 'routes/Settings/routes/Extensions/components/extension/ExtensionIcon';\r\nimport ExtensionActionButtons from 'routes/Settings/routes/Extensions/components/extension/ExtensionActionButtons';\r\n\r\nimport { compareVersions } from 'compare-versions';\r\n\r\nimport 'fomantic-ui-css/components/item.min.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport {\r\n SocketSubscriptionDecoratorChildProps,\r\n SocketSubscriptionDecorator,\r\n} from 'decorators/SocketSubscriptionDecorator';\r\nimport { errorResponseToString } from 'utils/TypeConvert';\r\nimport { DataFetchError } from 'decorators/DataProviderDecorator';\r\nimport classNames from 'classnames';\r\n\r\ninterface VersionProps {\r\n title: string;\r\n className?: string;\r\n packageInfo?: {\r\n date?: string;\r\n version: string;\r\n };\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst Version: React.FC<VersionProps> = ({ title, packageInfo, className, moduleT }) => {\r\n if (!packageInfo) {\r\n return null;\r\n }\r\n\r\n const versionDesc = !packageInfo.date\r\n ? packageInfo.version\r\n : moduleT.t('datePublished', {\r\n defaultValue: '{{version}} (published {{date}})',\r\n replace: {\r\n version: packageInfo.version,\r\n date: Moment(packageInfo.date).from(Moment()),\r\n },\r\n });\r\n\r\n return (\r\n <div className={className}>\r\n {`${title}: `}\r\n <span>{versionDesc}</span>\r\n </div>\r\n );\r\n};\r\n\r\nconst formatAuthor = (\r\n moduleT: UI.ModuleTranslator,\r\n npmPackage?: UI.NpmPackage,\r\n installedPackage?: API.Extension,\r\n) => {\r\n const author = npmPackage ? npmPackage.publisher.username : installedPackage?.author;\r\n if (!author) {\r\n return null;\r\n }\r\n\r\n return moduleT.t('byAuthor', {\r\n defaultValue: 'by {{author}}',\r\n replace: {\r\n author,\r\n },\r\n });\r\n};\r\n\r\nconst formatNote = (\r\n moduleT: UI.ModuleTranslator,\r\n installedPackage?: API.Extension,\r\n npmError?: DataFetchError | null,\r\n) => {\r\n if (installedPackage && !installedPackage.managed) {\r\n return moduleT.translate('Unmanaged extension');\r\n }\r\n\r\n if (npmError) {\r\n return moduleT.t('extensionDirectoryFetchError', {\r\n defaultValue: 'Failed to fetch information from the extension directory: {{error}}',\r\n replace: {\r\n error: errorResponseToString(npmError),\r\n },\r\n });\r\n }\r\n\r\n return moduleT.translate('Non-listed extension');\r\n};\r\n\r\nexport interface ExtensionProps {\r\n installedPackage?: API.Extension;\r\n npmPackage?: UI.NpmPackage;\r\n npmError?: DataFetchError | null;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface State {\r\n installing: boolean;\r\n}\r\nclass Extension extends React.PureComponent<\r\n ExtensionProps & SocketSubscriptionDecoratorChildProps,\r\n State\r\n> {\r\n //displayName: 'Extension',\r\n\r\n state: State = {\r\n installing: false,\r\n };\r\n\r\n onInstallationStarted = (data: API.ExtensionInstallEvent) => {\r\n if (data.install_id !== this.props.npmPackage!.name) {\r\n return;\r\n }\r\n\r\n this.setState({\r\n installing: true,\r\n });\r\n };\r\n\r\n onInstallationCompleted = (data: API.ExtensionInstallEvent) => {\r\n if (data.install_id !== this.props.npmPackage!.name) {\r\n return;\r\n }\r\n\r\n this.setState({\r\n installing: false,\r\n });\r\n };\r\n\r\n componentDidMount() {\r\n const { addSocketListener, npmPackage } = this.props;\r\n\r\n if (!!npmPackage) {\r\n // eslint-disable-next-line max-len\r\n addSocketListener(\r\n ExtensionConstants.MODULE_URL,\r\n ExtensionConstants.INSTALLATION_STARTED,\r\n this.onInstallationStarted,\r\n );\r\n // eslint-disable-next-line max-len\r\n addSocketListener(\r\n ExtensionConstants.MODULE_URL,\r\n ExtensionConstants.INSTALLATION_SUCCEEDED,\r\n this.onInstallationCompleted,\r\n );\r\n // eslint-disable-next-line max-len\r\n addSocketListener(\r\n ExtensionConstants.MODULE_URL,\r\n ExtensionConstants.INSTALLATION_FAILED,\r\n this.onInstallationCompleted,\r\n );\r\n }\r\n }\r\n\r\n render() {\r\n const { npmPackage, installedPackage, npmError, moduleT } = this.props;\r\n const { installing } = this.state;\r\n const { translate } = moduleT;\r\n\r\n const hasUpdate =\r\n !!installedPackage &&\r\n !!npmPackage &&\r\n compareVersions(installedPackage.version, npmPackage.version) < 0;\r\n\r\n return (\r\n <div className=\"item extension\">\r\n <ExtensionIcon installedPackage={installedPackage} hasUpdate={hasUpdate} />\r\n <div className=\"content\">\r\n <div className=\"header\">\r\n {npmPackage ? npmPackage.name : installedPackage!.name}\r\n </div>\r\n <div className=\"meta author\">\r\n {formatAuthor(moduleT, npmPackage, installedPackage)}\r\n </div>\r\n <div className=\"description\">\r\n <span>\r\n {npmPackage ? npmPackage.description : installedPackage!.description}\r\n </span>\r\n </div>\r\n <div className=\"extra version\">\r\n <Version\r\n className=\"npm\"\r\n title={translate('Latest version')}\r\n packageInfo={npmPackage}\r\n moduleT={moduleT}\r\n />\r\n <div>{!npmPackage && formatNote(moduleT, installedPackage, npmError)}</div>\r\n <Version\r\n className={classNames({\r\n outdated: hasUpdate,\r\n latest: npmPackage && !hasUpdate,\r\n })}\r\n title={translate('Installed version')}\r\n packageInfo={installedPackage}\r\n moduleT={moduleT}\r\n />\r\n </div>\r\n <ExtensionActionButtons\r\n installedPackage={installedPackage}\r\n npmPackage={npmPackage}\r\n installing={installing}\r\n hasUpdate={hasUpdate}\r\n moduleT={moduleT}\r\n />\r\n </div>\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default SocketSubscriptionDecorator<ExtensionProps>(Extension);\r\n","import * as React from 'react';\r\n\r\nimport Icon from 'components/semantic/Icon';\r\n\r\nimport * as API from 'types/api';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nconst getCornerIcon = (\r\n installedPackage: API.Extension | undefined,\r\n hasUpdate: boolean,\r\n) => {\r\n if (!installedPackage) {\r\n return null;\r\n }\r\n\r\n if (hasUpdate) {\r\n return 'yellow warning circle';\r\n }\r\n\r\n if (!installedPackage.managed) {\r\n return 'blue external square';\r\n }\r\n\r\n if (installedPackage.running) {\r\n return 'green play';\r\n }\r\n\r\n if (installedPackage.disabled) {\r\n return 'grey check circle';\r\n }\r\n\r\n return 'green check circle';\r\n};\r\n\r\ninterface ExtensionIconProps {\r\n installedPackage?: API.Extension;\r\n hasUpdate: boolean;\r\n size?: string;\r\n}\r\n\r\nconst ExtensionIcon: React.FC<ExtensionIconProps> = ({\r\n installedPackage,\r\n hasUpdate,\r\n size = 'huge',\r\n}) => (\r\n <div className=\"ui image\">\r\n <Icon\r\n icon={IconConstants.EXTENSION}\r\n color={installedPackage?.disabled ? 'grey' : undefined}\r\n size={size}\r\n cornerIcon={getCornerIcon(installedPackage, hasUpdate)}\r\n />\r\n </div>\r\n);\r\n\r\nexport default ExtensionIcon;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['away_message', 'away_no_bots', 'away_idle_time'];\r\n\r\nconst AwayPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default AwayPage;\r\n","import * as React from 'react';\r\n\r\nimport UserConstants from 'constants/UserConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport { UserMenu } from 'components/action-menu';\r\n\r\nimport * as API from 'types/api';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport MenuConstants from 'constants/MenuConstants';\r\n\r\nconst Row: React.FC<{ ignoreInfo: API.IgnoredUser }> = ({ ignoreInfo }) => (\r\n <tr>\r\n <td className=\"user dropdown\">\r\n <UserMenu\r\n ids={['unignore']}\r\n userIcon=\"simple\"\r\n user={ignoreInfo.user}\r\n contextElement=\"#setting-scroll-context\"\r\n remoteMenuId={MenuConstants.USER}\r\n />\r\n </td>\r\n <td className=\"count\">{ignoreInfo.ignored_messages}</td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (ignoreInfo: API.IgnoredUser) => {\r\n return <Row key={ignoreInfo.user.cid} ignoreInfo={ignoreInfo} />;\r\n};\r\n\r\ntype IgnorePageProps = SettingPageProps;\r\n\r\ninterface IgnorePageDataProps extends DataProviderDecoratorChildProps {\r\n ignores: API.IgnoredUser[];\r\n}\r\n\r\nconst IgnorePage: React.FC<IgnorePageProps & IgnorePageDataProps> = ({\r\n ignores,\r\n moduleT,\r\n}) => {\r\n const { translate } = moduleT;\r\n if (ignores.length === 0) {\r\n return <Message title={translate('No ignored users')} />;\r\n }\r\n\r\n return (\r\n <div>\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{translate('User')}</th>\r\n <th>{translate('Messages ignored')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>{ignores.map(getRow)}</tbody>\r\n </table>\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<IgnorePageProps, IgnorePageDataProps>(IgnorePage, {\r\n urls: {\r\n ignores: UserConstants.IGNORES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(UserConstants.MODULE_URL, UserConstants.IGNORE_ADDED, () =>\r\n refetchData(),\r\n );\r\n addSocketListener(UserConstants.MODULE_URL, UserConstants.IGNORE_REMOVED, () =>\r\n refetchData(),\r\n );\r\n },\r\n});\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport '../style.css';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\nimport { Trans } from 'react-i18next';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\nimport { useSession } from 'context/SessionContext';\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n //const { toI18nKey } = this.props.moduleT;\r\n if (id === 'nmdc_encoding') {\r\n fieldOptions.help = (\r\n <Trans\r\n i18nKey={moduleT.toI18nKey(\r\n toFormI18nKey(UI.TranslatableFormDefinitionProperties.HELP, id, undefined),\r\n )}\r\n >\r\n <div>\r\n Encoding setting is only used in NMDC hubs. ADC hubs will always use UTF-8\r\n encoding.\r\n <br />\r\n <br />\r\n <div>\r\n Commonly used values:\r\n <ul>\r\n <li>Central Europe: cp1250</li>\r\n <li>Cyrillic: cp1251</li>\r\n <li>Western Europe: cp1252</li>\r\n <li>Greek: cp1253</li>\r\n <li>Turkish: cp1254</li>\r\n <li>Hebrew: cp1256</li>\r\n </ul>\r\n </div>\r\n </div>\r\n </Trans>\r\n );\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\nconst Entry = [\r\n 'auto_follow_redirects',\r\n 'disconnect_offline_users',\r\n 'disconnect_hubs_noreg',\r\n 'min_search_interval',\r\n];\r\n\r\nconst MiscPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { systemInfo } = useSession();\r\n // The locale-specific system encoding is used on Windows by default\r\n // while other system use UTF-8\r\n if (systemInfo.platform !== API.PlatformEnum.WINDOWS) {\r\n Entry.push('nmdc_encoding');\r\n }\r\n\r\n return (\r\n <div>\r\n <RemoteSettingForm keys={Entry} onFieldSetting={FieldOptionGetter(moduleT)} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default MiscPage;\r\n","import * as React from 'react';\r\nimport { SettingProfileEnum } from 'constants/SettingConstants';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { toFormI18nKey } from 'utils/FormUtils';\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\nimport { Trans } from 'react-i18next';\r\n\r\nconst Entry = ['nick', 'description', 'email', 'setting_profile', 'language_file'];\r\n\r\nconst FieldOptionGetter = (moduleT: UI.ModuleTranslator) => {\r\n const onFieldSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n if (id === 'setting_profile') {\r\n let message;\r\n\r\n const profileId = formValue[id] as number;\r\n switch (profileId) {\r\n case SettingProfileEnum.NORMAL: {\r\n message =\r\n // eslint-disable-next-line max-len\r\n 'The client is used in normal private/public hubs for transferring files via internet. Use this profile if unsure.';\r\n break;\r\n }\r\n case SettingProfileEnum.RAR: {\r\n message =\r\n // eslint-disable-next-line max-len\r\n 'The client is used for transferring files that are split in RAR archives (or in other small-sized formats)';\r\n break;\r\n }\r\n case SettingProfileEnum.LAN: {\r\n message =\r\n // eslint-disable-next-line max-len\r\n 'The client is used for transferring files in local network (e.g. LAN parties) or in another closed network (e.g. university network)';\r\n break;\r\n }\r\n default:\r\n }\r\n\r\n if (message) {\r\n fieldOptions.help = moduleT.t(\r\n toFormI18nKey(\r\n UI.TranslatableFormDefinitionProperties.HELP,\r\n id,\r\n profileId.toString(),\r\n ),\r\n message,\r\n );\r\n }\r\n } else if (id === 'language_file') {\r\n const translateHelp =\r\n 'If you want to help with improving the existing translations or translate the \\\r\napplication into a new language, please see the \\\r\n<url>instructions for translators</url>.';\r\n\r\n fieldOptions.help = (\r\n <>\r\n <p>\r\n <Trans\r\n i18nKey={moduleT.toI18nKey(\r\n toFormI18nKey(\r\n UI.TranslatableFormDefinitionProperties.HELP,\r\n id,\r\n 'Restart',\r\n ),\r\n )}\r\n defaults=\"The application must be restarted for the new language to take effect.\"\r\n />\r\n </p>\r\n <p>\r\n <Trans\r\n i18nKey={moduleT.toI18nKey(\r\n toFormI18nKey(\r\n UI.TranslatableFormDefinitionProperties.HELP,\r\n id,\r\n 'Translate',\r\n ),\r\n )}\r\n defaults={translateHelp}\r\n components={{\r\n url: <ExternalLink url={LinkConstants.TRANSLATOR_HELP} />,\r\n }}\r\n />\r\n </p>\r\n </>\r\n );\r\n }\r\n };\r\n\r\n return onFieldSetting;\r\n};\r\n\r\nconst UserPage: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} onFieldSetting={FieldOptionGetter(moduleT)} />\r\n </div>\r\n);\r\n\r\nexport default UserPage;\r\n","import * as React from 'react';\r\n\r\nimport { ShareActionModule, ShareRefreshAction } from 'actions/ui/share/ShareActions';\r\nimport {\r\n ShareExcludeActionModule,\r\n ShareExcludeAddAction,\r\n ShareExcludeEditMenu,\r\n} from 'actions/ui/share/ShareExcludeActions';\r\nimport ShareConstants from 'constants/ShareConstants';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport { ActionMenu } from 'components/action-menu';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\nimport { FileBrowserRouteDialog } from 'components/filebrowser';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport Message from 'components/semantic/Message';\r\nimport FilesystemConstants from 'constants/FilesystemConstants';\r\n\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\n\r\nimport * as UI from 'types/ui';\r\nimport { Trans } from 'react-i18next';\r\nimport { useSocket } from 'context/SocketContext';\r\n\r\nconst Row: React.FC<{ path: string }> = ({ path }) => (\r\n <tr>\r\n <td className=\"path dropdown\">\r\n <ActionMenu\r\n caption={<strong>{path}</strong>}\r\n actions={ShareExcludeEditMenu}\r\n itemData={path}\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n </tr>\r\n);\r\n\r\nconst getRow = (path: string) => {\r\n return <Row key={path} path={path} />;\r\n};\r\n\r\ntype ExcludePageProps = SettingPageProps;\r\n\r\ninterface ExcludePageDataProps extends DataProviderDecoratorChildProps {\r\n excludes: string[];\r\n}\r\n\r\nconst ExcludePage: React.FC<ExcludePageProps & ExcludePageDataProps> = ({\r\n excludes,\r\n moduleT,\r\n}) => {\r\n const socket = useSocket();\r\n const { translate, toI18nKey } = moduleT;\r\n return (\r\n <div>\r\n <Message\r\n title={\r\n <div>\r\n <div>\r\n <Trans i18nKey={toI18nKey('shareRefreshNote')}>\r\n Share must be refreshed for the changes to take effect\r\n </Trans>\r\n </div>\r\n <br />\r\n <ActionButton action={ShareRefreshAction} moduleData={ShareActionModule} />\r\n </div>\r\n }\r\n icon={IconConstants.INFO}\r\n />\r\n\r\n <ActionButton\r\n action={ShareExcludeAddAction}\r\n moduleData={ShareExcludeActionModule}\r\n className=\"add\"\r\n />\r\n\r\n {excludes.length > 0 && (\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{translate('Path')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>{excludes.map(getRow)}</tbody>\r\n </table>\r\n )}\r\n\r\n <FileBrowserRouteDialog\r\n onConfirm={(path) =>\r\n runBackgroundSocketAction(\r\n () => socket.post(ShareConstants.EXCLUDES_ADD_URL, { path }),\r\n moduleT.plainT,\r\n )\r\n }\r\n initialPath=\"\"\r\n historyId={FilesystemConstants.LOCATION_GENERIC}\r\n subHeader={translate('Add excluded path')}\r\n selectMode={UI.FileSelectModeEnum.DIRECTORY}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator(ExcludePage, {\r\n urls: {\r\n excludes: ShareConstants.EXCLUDES_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(ShareConstants.MODULE_URL, ShareConstants.EXCLUDE_ADDED, () =>\r\n refetchData(),\r\n );\r\n addSocketListener(ShareConstants.MODULE_URL, ShareConstants.EXCLUDE_REMOVED, () =>\r\n refetchData(),\r\n );\r\n },\r\n});\r\n","import * as React from 'react';\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport Checkbox from 'components/semantic/Checkbox';\r\nimport Button from 'components/semantic/Button';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport HashConstants from 'constants/HashConstants';\r\n\r\nimport { useFormatter } from 'context/FormatterContext';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { runBackgroundSocketAction } from 'utils/ActionUtils';\r\nimport { Row, Grid } from 'components/semantic/Grid';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { useSocket } from 'context/SocketContext';\r\nimport { useSession } from 'context/SessionContext';\r\n\r\ninterface OptimizeLayoutProps {\r\n running: boolean;\r\n startHandler: (verify: boolean) => void;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst OptimizeLayout: React.FC<OptimizeLayoutProps> = ({\r\n startHandler,\r\n running,\r\n moduleT,\r\n}) => {\r\n const { toI18nKey, translate } = moduleT;\r\n const [verify, setVerify] = React.useState(false);\r\n return (\r\n <div className=\"optimize-layout\">\r\n <h4 className=\"header\" style={{ marginTop: '30px' }}>\r\n {translate('Maintenance')}\r\n </h4>\r\n <Message\r\n description={\r\n <Trans i18nKey={toI18nKey('hashDBOptimizeNote')}>\r\n This operation will delete all hash information for files that aren't\r\n currently in share. If you are sharing files from network disks or from a\r\n removable storage, make sure that the files are currently shown in share\r\n (otherwise they have to be rehashed)\r\n </Trans>\r\n }\r\n icon={IconConstants.NOTE}\r\n />\r\n\r\n <Checkbox\r\n caption={translate('Verify integrity of hash data')}\r\n checked={verify}\r\n disabled={running}\r\n onChange={setVerify}\r\n floating={true}\r\n id=\"verify-hash-data\"\r\n />\r\n <Button\r\n className=\"optimize-button\"\r\n caption={translate('Optimize now')}\r\n icon={IconConstants.CONFIGURE}\r\n loading={running}\r\n onClick={() => startHandler(verify)}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\ninterface HashDatabaseLayoutProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\ninterface HashDatabaseLayoutDataProps extends DataProviderDecoratorChildProps {\r\n status: API.HashDatabaseStatus;\r\n}\r\n\r\nconst HashDatabaseLayout: React.FC<\r\n HashDatabaseLayoutProps & HashDatabaseLayoutDataProps\r\n> = ({ status, moduleT }) => {\r\n const { hasAccess } = useSession();\r\n const { formatSize } = useFormatter();\r\n const socket = useSocket();\r\n const handleOptimize = (verify: boolean) => {\r\n runBackgroundSocketAction(\r\n () => socket.post(HashConstants.OPTIMIZE_DATABASE_URL, { verify }),\r\n moduleT.plainT,\r\n );\r\n };\r\n\r\n const { translate } = moduleT;\r\n return (\r\n <div className=\"ui segment hash-database\">\r\n <h3 className=\"header\">{translate('Hash database')}</h3>\r\n <Grid columns=\"two\">\r\n <Row\r\n title={translate('File index size')}\r\n text={formatSize(status.file_index_size)}\r\n titleWidth=\"five\"\r\n />\r\n <Row\r\n title={translate('Hash store size')}\r\n text={formatSize(status.hash_store_size)}\r\n titleWidth=\"five\"\r\n />\r\n </Grid>\r\n {hasAccess(API.AccessEnum.SETTINGS_EDIT) && (\r\n <OptimizeLayout\r\n running={status.maintenance_running}\r\n startHandler={handleOptimize}\r\n moduleT={moduleT}\r\n />\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport default DataProviderDecorator<\r\n HashDatabaseLayoutProps,\r\n HashDatabaseLayoutDataProps\r\n>(HashDatabaseLayout, {\r\n urls: {\r\n status: HashConstants.DATABASE_STATUS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(HashConstants.MODULE_URL, HashConstants.DATABASE_STATUS, () =>\r\n refetchData(),\r\n );\r\n },\r\n});\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport HashDatabaseLayout from 'routes/Settings/routes/Sharing/components/HashDatabaseLayout';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['max_hash_speed', 'max_total_hashers', 'max_volume_hashers'];\r\n\r\nconst HashingPage: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n\r\n <HashDatabaseLayout moduleT={moduleT} />\r\n </div>\r\n);\r\n\r\nexport default HashingPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'refresh_time',\r\n 'refresh_time_incoming',\r\n 'refresh_startup',\r\n 'refresh_threading',\r\n];\r\n\r\nconst RefreshOptionsPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default RefreshOptionsPage;\r\n","import * as React from 'react';\r\n\r\nimport MenuItemLink from 'components/semantic/MenuItemLink';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport {\r\n ActionHandlerDecorator,\r\n ActionClickHandler,\r\n} from 'decorators/ActionHandlerDecorator';\r\nimport {\r\n ShareProfileActionModule,\r\n ShareProfileCloneAction,\r\n ShareProfileCreateAction,\r\n} from 'actions/ui/share';\r\nimport SectionedDropdown from 'components/semantic/SectionedDropdown';\r\nimport MenuSection from 'components/semantic/MenuSection';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { translateActionName } from 'utils/ActionUtils';\r\nimport { formatProfileNameWithSize } from 'utils/ShareProfileUtils';\r\nimport { Formatter, useFormatter } from 'context/FormatterContext';\r\nimport { useSession } from 'context/SessionContext';\r\n\r\nconst getProfileItem = (\r\n profile: API.ShareProfile,\r\n formatter: Formatter,\r\n onClickAction: ActionClickHandler<API.ShareProfile>,\r\n) => {\r\n return (\r\n <MenuItemLink\r\n key={profile.id}\r\n onClick={() =>\r\n onClickAction({\r\n action: ShareProfileCloneAction,\r\n itemData: profile,\r\n moduleData: ShareProfileActionModule,\r\n entity: undefined,\r\n })\r\n }\r\n icon={IconConstants.COPY}\r\n >\r\n {formatProfileNameWithSize(profile, formatter)}\r\n </MenuItemLink>\r\n );\r\n};\r\n\r\nexport interface ShareProfileCloneDropdownProps {\r\n profiles: API.ShareProfile[];\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst ShareProfileCloneDropdown: React.FC<ShareProfileCloneDropdownProps> = ({\r\n profiles,\r\n moduleT,\r\n}) => {\r\n const { hasAccess } = useSession();\r\n const formatter = useFormatter();\r\n if (!hasAccess(ShareProfileCreateAction.access)) {\r\n return null;\r\n }\r\n\r\n return (\r\n <ActionHandlerDecorator<API.ShareProfile | void>>\r\n {({ onClickAction }) => {\r\n return (\r\n <SectionedDropdown\r\n caption={moduleT.translate('Add profile')}\r\n className=\"clone-profile\"\r\n button={true}\r\n >\r\n <MenuItemLink\r\n onClick={() => {\r\n onClickAction({\r\n itemData: undefined,\r\n action: ShareProfileCreateAction,\r\n entity: undefined,\r\n moduleData: ShareProfileActionModule,\r\n });\r\n }}\r\n icon={IconConstants.CREATE}\r\n >\r\n {translateActionName(\r\n ShareProfileCreateAction,\r\n ShareProfileActionModule,\r\n moduleT.plainT,\r\n )}\r\n </MenuItemLink>\r\n <MenuSection caption={moduleT.translate('Clone from an existing profile')}>\r\n {profiles.map((profile) =>\r\n getProfileItem(profile, formatter, onClickAction),\r\n )}\r\n </MenuSection>\r\n </SectionedDropdown>\r\n );\r\n }}\r\n </ActionHandlerDecorator>\r\n );\r\n};\r\n\r\nexport default ShareProfileCloneDropdown;\r\n","import * as React from 'react';\r\n\r\nimport { ShareProfileEditMenu } from 'actions/ui/share/ShareProfileActions';\r\n\r\nimport { ActionMenu } from 'components/action-menu';\r\n\r\nimport { Link } from 'react-router';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport ShareProfileDecorator, {\r\n ShareProfileDecoratorChildProps,\r\n} from 'decorators/ShareProfileDecorator';\r\nimport { useFormatter } from 'context/FormatterContext';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from 'types/api';\r\n\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { Trans } from 'react-i18next';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport ShareProfileCloneDropdown from './ShareProfileCloneDropdown';\r\n\r\ninterface ShareProfileRowProps {\r\n profile: API.ShareProfile;\r\n}\r\n\r\nconst ShareProfileRow: React.FC<ShareProfileRowProps> = ({ profile }) => {\r\n const { formatSize } = useFormatter();\r\n return (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu\r\n caption={<strong>{profile.str}</strong>}\r\n actions={ShareProfileEditMenu}\r\n itemData={profile}\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"size\">{formatSize(profile.size)}</td>\r\n <td className=\"files\">{profile.files}</td>\r\n </tr>\r\n );\r\n};\r\n\r\ntype ShareProfilesPageProps = SettingPageProps;\r\n\r\nconst ShareProfilesPage: React.FC<\r\n ShareProfilesPageProps & ShareProfileDecoratorChildProps\r\n> = ({ moduleT, profiles }) => {\r\n const { translate, toI18nKey } = moduleT;\r\n const shareProfilesPartialNote =\r\n 'Queued files are shared via the partial file sharing feature in all hubs \\\r\nwhere the share has not been hidden, regardless of the configured share \\\r\nprofiles.';\r\n\r\n const shareProfilesHelp =\r\n 'Share profiles are assigned for individual directories from the \\\r\n<url>Share</url> page.';\r\n\r\n return (\r\n <div>\r\n <Message\r\n description={\r\n <div>\r\n <p>\r\n <Trans\r\n i18nKey={toI18nKey('shareProfilesPartialNote')}\r\n defaults={shareProfilesPartialNote}\r\n components={{\r\n url: <Link to=\"/share\" />,\r\n }}\r\n />\r\n </p>\r\n <p>\r\n <Trans\r\n i18nKey={toI18nKey('shareProfilesHelp')}\r\n defaults={shareProfilesHelp}\r\n components={{\r\n url: <Link to=\"/share\" />,\r\n }}\r\n />\r\n </p>\r\n </div>\r\n }\r\n icon={IconConstants.INFO}\r\n />\r\n <ShareProfileCloneDropdown profiles={profiles} moduleT={moduleT} />\r\n\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{translate('Name')}</th>\r\n <th>{translate('Total size')}</th>\r\n <th>{translate('Total files')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {profiles.map((profile) => (\r\n <ShareProfileRow key={profile.id} profile={profile} />\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator(ShareProfilesPage, false);\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'share_hidden',\r\n 'share_no_empty_dirs',\r\n 'share_no_zero_byte',\r\n 'share_follow_symlinks',\r\n 'share_max_size',\r\n];\r\n\r\nconst Skiplist = ['share_skiplist', 'share_skiplist_regex'];\r\n\r\nconst SharingOptionsPage: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n <RemoteSettingForm title={moduleT.translate('Skiplist')} keys={Skiplist} />\r\n </div>\r\n);\r\n\r\nexport default SharingOptionsPage;\r\n","import RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport SettingConstants from 'constants/SettingConstants';\r\nimport { FormFieldChangeHandler, FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\nimport { useSocket } from 'context/SocketContext';\r\n\r\ninterface AutoValuePanelProps {\r\n // Type of the value section (from the setting key)\r\n type: string;\r\n\r\n // Form items to list\r\n keys: string[];\r\n}\r\n\r\nconst AutoValuePanel: React.FC<AutoValuePanelProps> = ({ type, keys }) => {\r\n const socket = useSocket();\r\n const getAutoKey = () => {\r\n return `${type}_auto_limits`;\r\n };\r\n\r\n // Fetch auto settings when enabling auto detection\r\n const onFieldChanged: FormFieldChangeHandler = (changedKey, formValue, hasChanges) => {\r\n const autoSettingKey = getAutoKey();\r\n if (changedKey !== autoSettingKey || !formValue[autoSettingKey]) {\r\n return null;\r\n }\r\n\r\n return socket.post(SettingConstants.ITEMS_GET_URL, {\r\n keys: keys.filter((key) => key !== autoSettingKey),\r\n value_mode: API.SettingValueMode.FORCE_AUTO,\r\n });\r\n };\r\n\r\n // Disable other fields when auto detection is enabled\r\n const onFieldSetting: FormFieldSettingHandler<any> = (\r\n settingKey,\r\n fieldOptions,\r\n formValue,\r\n ) => {\r\n if (formValue[getAutoKey()] && settingKey !== getAutoKey()) {\r\n fieldOptions.disabled = true;\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm\r\n keys={keys}\r\n onFieldChanged={onFieldChanged}\r\n onFieldSetting={onFieldSetting}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default AutoValuePanel;\r\n","import * as React from 'react';\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Auto = ['download_auto_limits', 'download_slots', 'download_max_start_speed'];\r\n\r\nconst Manual = ['download_highest_prio_slots'];\r\n\r\nconst DownloadLimitPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <AutoValuePanel keys={Auto} type=\"download\" />\r\n\r\n <RemoteSettingForm title={translate('Manually set')} keys={Manual} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default DownloadLimitPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['upload_limit_main', 'download_limit_main'];\r\n\r\nconst LimiterPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default LimiterPage;\r\n","import * as React from 'react';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { Trans } from 'react-i18next';\r\n\r\nconst Entry = ['download_speed', 'upload_speed'];\r\n\r\nconst SpeedPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { toI18nKey } = moduleT;\r\n const defaults =\r\n 'Please be as accurate as possible and set the ACTUAL speed of your connection. \\\r\nYou may use an online tester, such as <speedtest>{{name}}</speedtest>, to test your speed.';\r\n\r\n return (\r\n <div>\r\n <div className=\"ui message\">\r\n <Trans\r\n i18nKey={toI18nKey('connectionSpeedNote')}\r\n defaults={defaults}\r\n values={{ name: 'Speedtest.net' }}\r\n components={{\r\n speedtest: <ExternalLink url={LinkConstants.SPEEDTEST_URL} />,\r\n }}\r\n />\r\n </div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default SpeedPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Auto = [\r\n 'upload_auto_limits',\r\n 'upload_slots',\r\n 'upload_auto_grant_speed',\r\n 'upload_max_granted',\r\n];\r\n\r\nconst Manual = ['upload_minislot_size', 'upload_minislot_ext'];\r\n\r\nconst UploadLimitPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <AutoValuePanel keys={Auto} type=\"upload\" />\r\n <RemoteSettingForm title={translate('Manually set')} keys={Manual} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default UploadLimitPage;\r\n","import * as React from 'react';\r\n\r\nimport AutoValuePanel from 'routes/Settings/routes/SpeedLimits/components/AutoValuePanel';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Auto = ['mcn_auto_limits', 'mcn_down', 'mcn_up'];\r\n\r\nconst UserLimitPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <AutoValuePanel keys={Auto} type=\"mcn\" />\r\n </div>\r\n);\r\n\r\nexport default UserLimitPage;\r\n","import * as React from 'react';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { SystemActionModule, SystemRestartWebAction } from 'actions/ui/system';\r\n\r\nconst Generic = [\r\n 'web_server_threads',\r\n 'default_idle_timeout',\r\n 'ping_interval',\r\n 'ping_timeout',\r\n];\r\n\r\nconst Hooks = [\r\n 'share_file_validation_hook_timeout',\r\n 'share_directory_validation_hook_timeout',\r\n 'new_share_file_validation_hook_timeout',\r\n 'new_share_directory_validation_hook_timeout',\r\n\r\n 'outgoing_chat_message_hook_timeout',\r\n 'incoming_chat_message_hook_timeout',\r\n\r\n 'queue_add_bundle_hook_timeout',\r\n 'queue_add_bundle_file_hook_timeout',\r\n 'queue_add_source_hook_timeout',\r\n 'queue_bundle_finished_hook_timeout',\r\n 'queue_file_finished_hook_timeout',\r\n\r\n 'list_menuitems_hook_timeout',\r\n];\r\n\r\nconst ServerSettingsPage: React.FC<SettingPageProps> = (props) => {\r\n const { translate } = props.moduleT;\r\n return (\r\n <div>\r\n <ActionButton action={SystemRestartWebAction} moduleData={SystemActionModule} />\r\n <RemoteSettingForm keys={Generic} />\r\n <div className=\"ui header\">{translate('Hook timeouts')}</div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm keys={Hooks} />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ServerSettingsPage;\r\n","import { Component } from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport '../style.css';\r\nimport { FormFieldChangeHandler, FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport * as API from 'types/api';\r\n\r\nexport interface LogSectionProps {\r\n section: string;\r\n simple?: boolean;\r\n}\r\n\r\nclass LogSection extends Component<LogSectionProps> {\r\n state = {\r\n enabled: false,\r\n };\r\n\r\n convertKey = (optionalSuffix?: string) => {\r\n const suffix = optionalSuffix ? `_${optionalSuffix}` : '';\r\n return `log_${this.props.section}${suffix}`;\r\n };\r\n\r\n onSettingsReceived = (settings: API.SettingValueMap) => {\r\n this.setState({\r\n enabled: settings[this.convertKey()],\r\n });\r\n };\r\n\r\n onEnableStateChanged: FormFieldChangeHandler = (id, formValue, hasChanges) => {\r\n this.setState({\r\n enabled: formValue[id],\r\n });\r\n };\r\n\r\n onContentSetting: FormFieldSettingHandler = (id, fieldOptions, formValue) => {\r\n fieldOptions.disabled = !this.state.enabled;\r\n };\r\n\r\n getChildClass = (className: string) => {\r\n if (this.state.enabled) {\r\n return className + ' active';\r\n }\r\n\r\n return className;\r\n };\r\n\r\n render() {\r\n const Title = [this.convertKey()];\r\n\r\n const Content = [this.convertKey('file'), this.convertKey('format')];\r\n\r\n const { simple } = this.props;\r\n return (\r\n <div className={this.getChildClass('log-section')}>\r\n <div className={this.getChildClass('title')}>\r\n <RemoteSettingForm\r\n keys={Title}\r\n onFieldChanged={this.onEnableStateChanged}\r\n onSettingValuesReceived={this.onSettingsReceived}\r\n />\r\n </div>\r\n\r\n {!simple && (\r\n <div className={this.getChildClass('content')}>\r\n <RemoteSettingForm keys={Content} onFieldSetting={this.onContentSetting} />\r\n </div>\r\n )}\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default LogSection;\r\n","import * as React from 'react';\r\n\r\nimport Accordion from 'components/semantic/Accordion';\r\n\r\nimport LogSection from 'routes/Settings/routes/System/components/LogSection';\r\n\r\ninterface LogSectionGroupProps {\r\n sectionKeys: string[];\r\n title: string;\r\n simpleKeys?: string[];\r\n}\r\n\r\nconst LogSectionGroup: React.FC<LogSectionGroupProps> = (props) => {\r\n const { title, sectionKeys, simpleKeys, ...other } = props;\r\n return (\r\n <div>\r\n <div className=\"sections\">\r\n <div className=\"ui header\">{title}</div>\r\n <Accordion className=\"styled\" controlled={true}>\r\n {sectionKeys.map((sectionKey) => (\r\n <LogSection\r\n {...other}\r\n key={sectionKey}\r\n section={sectionKey}\r\n simple={!!simpleKeys && simpleKeys.includes(sectionKey)}\r\n />\r\n ))}\r\n </Accordion>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default LogSectionGroup;\r\n","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport ExternalLink from 'components/ExternalLink';\r\nimport LinkConstants from 'constants/LinkConstants';\r\n\r\nimport Message from 'components/semantic/Message';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport LogSectionGroup from './LogSectionGroup';\r\nimport { Trans } from 'react-i18next';\r\n\r\n// Generic options\r\nconst Entry = ['log_directory'];\r\n\r\n// Sections\r\nconst MessageSectionKeys = ['main', 'pm', 'syslog', 'status'];\r\n\r\nconst TransferSectionKeys = ['downloads', 'uploads', 'list_transfers'];\r\n\r\nconst SimpleSectionKeys = ['list_transfers'];\r\n\r\nconst LoggingPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { translate, toI18nKey } = moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n <div className=\"sections\">\r\n <Message\r\n icon={IconConstants.INFO}\r\n description={\r\n <ExternalLink url={LinkConstants.VARIABLE_HELP_URL}>\r\n <Trans i18nKey={toI18nKey('variableHelp')}>\r\n Variable information for Filename and Format fields\r\n </Trans>\r\n </ExternalLink>\r\n }\r\n />\r\n <LogSectionGroup sectionKeys={MessageSectionKeys} title={translate('Messages')} />\r\n <LogSectionGroup\r\n sectionKeys={TransferSectionKeys}\r\n title={translate('Transfers')}\r\n simpleKeys={SimpleSectionKeys}\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default LoggingPage;\r\n","import * as React from 'react';\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport Message from 'components/semantic/Message';\r\nimport {\r\n SystemActionModule,\r\n SystemRestartWebAction,\r\n} from 'actions/ui/system/SystemActions';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport IconConstants from 'constants/IconConstants';\r\n\r\nconst PlainEntry = ['web_plain_port', 'web_plain_bind_address'];\r\n\r\nconst TlsEntry = [\r\n 'web_tls_port',\r\n 'web_tls_bind_address',\r\n 'web_tls_certificate_path',\r\n 'web_tls_certificate_key_path',\r\n];\r\n\r\nconst ServerSettingsPage: React.FC<SettingPageProps> = (props) => {\r\n const { t } = props.moduleT;\r\n return (\r\n <div>\r\n {/*<Message \r\n description={ (\r\n <div>\r\n <div>\r\n New settings will take effect after restarting the management interface\r\n </div>\r\n <ActionButton \r\n action={ SystemActions.restartWeb }\r\n />\r\n </div>\r\n ) }\r\n icon={ IconConstants.INFO }\r\n />*/}\r\n\r\n <ActionButton action={SystemRestartWebAction} moduleData={SystemActionModule} />\r\n\r\n <div className=\"ui header\">HTTP</div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm {...props} keys={PlainEntry} />\r\n </div>\r\n\r\n <div className=\"ui header\">HTTPS</div>\r\n <div className=\"ui segment\">\r\n <RemoteSettingForm {...props} keys={TlsEntry} />\r\n\r\n <Message\r\n description={t(\r\n 'defaultCertNote',\r\n 'The default client certificate is used if the certificate paths are empty',\r\n )}\r\n icon={IconConstants.INFO}\r\n />\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ServerSettingsPage;\r\n","const AccessConstants = {\n ADMIN: 'admin',\n\n SEARCH: 'search',\n DOWNLOAD: 'download',\n TRANSFERS: 'transfers',\n\n EVENTS_VIEW: 'events_view',\n EVENTS_EDIT: 'events_edit',\n\n QUEUE_VIEW: 'queue_view',\n QUEUE_EDIT: 'queue_edit',\n\n FAVORITE_HUBS_VIEW: 'favorite_hubs_view',\n FAVORITE_HUBS_EDIT: 'favorite_hubs_edit',\n\n SETTINGS_VIEW: 'settings_view',\n SETTINGS_EDIT: 'settings_edit',\n\n FILESYSTEM_VIEW: 'filesystem_view',\n FILESYSTEM_EDIT: 'filesystem_edit',\n\n HUBS_VIEW: 'hubs_view',\n HUBS_EDIT: 'hubs_edit',\n HUBS_SEND: 'hubs_send',\n\n PRIVATE_CHAT_VIEW: 'private_chat_view',\n PRIVATE_CHAT_EDIT: 'private_chat_edit',\n PRIVATE_CHAT_SEND: 'private_chat_send',\n\n FILELISTS_VIEW: 'filelists_view',\n FILELISTS_EDIT: 'filelists_edit',\n\n VIEW_FILE_VIEW: 'view_file_view',\n VIEW_FILE_EDIT: 'view_file_edit',\n};\n\nexport default AccessConstants;\n","import { useMemo, useRef } from 'react';\r\nimport RouteModal from 'components/semantic/RouteModal';\r\n\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from 'decorators/ModalRouteDecorator';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\nimport AccessConstants from 'constants/AccessConstants';\r\nimport PermissionSelector from 'routes/Settings/routes/System/components/users/PermissionSelector';\r\n\r\nimport t from 'utils/tcomb-form';\r\n\r\nimport Form, { FormSaveHandler, FormFieldSettingHandler } from 'components/form/Form';\r\n\r\nimport '../../style.css';\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { translateForm } from 'utils/FormUtils';\r\nimport { getSubModuleT } from 'utils/TranslationUtils';\r\nimport IconConstants from 'constants/IconConstants';\r\nimport { useSession } from 'context/SessionContext';\r\n\r\nconst enum PermissionAction {\r\n EDIT = 'Edit',\r\n VIEW = 'View',\r\n SEND_MESSAGES = 'Send messages',\r\n}\r\n\r\ntype CaptionEntry =\r\n | string\r\n | {\r\n title: string;\r\n action: PermissionAction;\r\n };\r\n\r\nconst AccessCaptions: { [key in string]: CaptionEntry } = {\r\n ADMIN: 'Administrator',\r\n\r\n SEARCH: 'Search',\r\n DOWNLOAD: 'Download',\r\n TRANSFERS: 'Transfers',\r\n\r\n EVENTS_VIEW: {\r\n title: 'Events',\r\n action: PermissionAction.VIEW,\r\n },\r\n EVENTS_EDIT: {\r\n title: 'Events',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n QUEUE_VIEW: {\r\n title: 'Queue',\r\n action: PermissionAction.VIEW,\r\n },\r\n QUEUE_EDIT: {\r\n title: 'Queue',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n FAVORITE_HUBS_VIEW: {\r\n title: 'Favorite hubs',\r\n action: PermissionAction.VIEW,\r\n },\r\n FAVORITE_HUBS_EDIT: {\r\n title: 'Favorite hubs',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n SETTINGS_VIEW: {\r\n title: 'Settings',\r\n action: PermissionAction.VIEW,\r\n },\r\n SETTINGS_EDIT: {\r\n title: 'Settings',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n FILESYSTEM_VIEW: {\r\n title: 'Local filesystem',\r\n action: PermissionAction.VIEW,\r\n },\r\n FILESYSTEM_EDIT: {\r\n title: 'Local filesystem',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n HUBS_VIEW: {\r\n title: 'Hubs',\r\n action: PermissionAction.VIEW,\r\n },\r\n HUBS_EDIT: {\r\n title: 'Hubs',\r\n action: PermissionAction.EDIT,\r\n },\r\n HUBS_SEND: {\r\n title: 'Hubs',\r\n action: PermissionAction.SEND_MESSAGES,\r\n },\r\n\r\n PRIVATE_CHAT_VIEW: {\r\n title: 'Private chat',\r\n action: PermissionAction.VIEW,\r\n },\r\n PRIVATE_CHAT_EDIT: {\r\n title: 'Private chat',\r\n action: PermissionAction.EDIT,\r\n },\r\n PRIVATE_CHAT_SEND: {\r\n title: 'Private chat',\r\n action: PermissionAction.SEND_MESSAGES,\r\n },\r\n\r\n FILELISTS_VIEW: {\r\n title: 'Filelists',\r\n action: PermissionAction.VIEW,\r\n },\r\n FILELISTS_EDIT: {\r\n title: 'Filelists',\r\n action: PermissionAction.EDIT,\r\n },\r\n\r\n VIEW_FILE_VIEW: {\r\n title: 'Viewed files',\r\n action: PermissionAction.VIEW,\r\n },\r\n VIEW_FILE_EDIT: {\r\n title: 'Viewed files',\r\n action: PermissionAction.EDIT,\r\n },\r\n};\r\n\r\nconst reducePermissionToOption = (\r\n options: API.SettingEnumOption[],\r\n key: keyof typeof AccessConstants,\r\n moduleT: UI.ModuleTranslator,\r\n) => {\r\n const captionEntry = AccessCaptions[key];\r\n if (typeof captionEntry === 'string') {\r\n options.push({\r\n id: AccessConstants[key],\r\n name: moduleT.translate(captionEntry),\r\n });\r\n } else {\r\n options.push({\r\n id: AccessConstants[key],\r\n name: `${moduleT.translate(captionEntry.title)} (${moduleT.translate(\r\n captionEntry.action,\r\n )})`,\r\n });\r\n }\r\n\r\n return options;\r\n};\r\n\r\nconst getEntry = (isNew: boolean): UI.FormFieldDefinition[] => {\r\n return [\r\n {\r\n key: 'username',\r\n title: 'User name',\r\n type: API.SettingTypeEnum.STRING,\r\n },\r\n {\r\n key: 'password',\r\n type: API.SettingTypeEnum.PASSWORD,\r\n title: isNew ? 'Password' : 'New password',\r\n optional: !isNew,\r\n },\r\n {\r\n key: 'permissions',\r\n title: 'Permissions',\r\n type: API.SettingTypeEnum.LIST,\r\n item_type: API.SettingTypeEnum.STRING,\r\n },\r\n ];\r\n};\r\n\r\ninterface WebUserDialogProps {\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\ninterface Entry extends API.WebUserInput, UI.FormValueMap {}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n user: API.WebUserInput;\r\n}\r\n\r\ntype Props = WebUserDialogProps & DataProps & ModalRouteDecoratorChildProps;\r\n\r\nconst buildDefinitions = (isNew: boolean, moduleT: UI.ModuleTranslator) => {\r\n const definitions = translateForm(getEntry(isNew), moduleT);\r\n\r\n const permissionT = getSubModuleT(moduleT, 'permissionSelector');\r\n const permissions = definitions.find((def) => def.key === 'permissions')!;\r\n Object.assign(permissions, {\r\n options: Object.keys(AccessConstants).reduce(\r\n (reduced, cur) =>\r\n reducePermissionToOption(\r\n reduced,\r\n cur as keyof typeof AccessConstants,\r\n permissionT,\r\n ),\r\n [],\r\n ),\r\n });\r\n\r\n return definitions;\r\n};\r\n\r\nconst WebUserDialog: React.FC<Props> = ({ user, moduleT, socket, ...other }) => {\r\n const { user: loginUser } = useSession();\r\n const isNew = !user;\r\n\r\n const definitions = useMemo(() => buildDefinitions(isNew, moduleT), []);\r\n const formRef = useRef<Form<Entry>>(null);\r\n\r\n const handleSave = () => {\r\n return formRef.current!.save();\r\n };\r\n\r\n const onSave: FormSaveHandler<Entry> = (changedFields) => {\r\n if (isNew) {\r\n return socket.post(WebUserConstants.USERS_URL, changedFields);\r\n }\r\n\r\n return socket.patch(`${WebUserConstants.USERS_URL}/${user.id}`, changedFields);\r\n };\r\n\r\n const onFieldSetting: FormFieldSettingHandler<Entry> = (\r\n id,\r\n fieldOptions,\r\n formValue,\r\n ) => {\r\n if (id === 'permissions') {\r\n fieldOptions.factory = t.form.Select;\r\n fieldOptions.template = PermissionSelector(moduleT);\r\n fieldOptions.disabled = !isNew && user.username === loginUser.username;\r\n } else if (id === 'username') {\r\n fieldOptions.disabled = !isNew;\r\n }\r\n };\r\n\r\n const title = moduleT.translate(isNew ? 'Add web user' : 'Edit user');\r\n\r\n return (\r\n <RouteModal\r\n className=\"web-user\"\r\n title={title}\r\n onApprove={handleSave}\r\n closable={false}\r\n icon={IconConstants.USER}\r\n {...other}\r\n >\r\n <Form<Entry>\r\n ref={formRef}\r\n fieldDefinitions={definitions}\r\n onFieldSetting={onFieldSetting}\r\n onSave={onSave}\r\n sourceValue={user as Entry}\r\n />\r\n </RouteModal>\r\n );\r\n};\r\n\r\nexport default ModalRouteDecorator<WebUserDialogProps>(\r\n DataProviderDecorator<Omit<Props, keyof DataProps>, DataProps>(WebUserDialog, {\r\n urls: {\r\n user: ({ params }, socket) => {\r\n if (!params.userId) {\r\n return Promise.resolve(undefined);\r\n }\r\n\r\n return socket.get(`${WebUserConstants.USERS_URL}/${params.userId}`);\r\n },\r\n },\r\n }),\r\n 'users/:userId?',\r\n);\r\n","import t from 'utils/tcomb-form';\r\n\r\nimport Checkbox from 'components/semantic/Checkbox';\r\nimport Message from 'components/semantic/Message';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\nimport { updateMultiselectValues } from 'utils/FormUtils';\r\n\r\ntype AccessOptionType = {\r\n value: API.AccessEnum;\r\n text: string;\r\n};\r\n\r\nconst PermissionSelector = (moduleT: UI.ModuleTranslator) => {\r\n return t.form.Form.templates.select.clone({\r\n renderSelect: (locals: UI.FormLocals<AccessOptionType, API.AccessEnum[]>) => {\r\n const onChange = (access: API.AccessEnum, checked: boolean) => {\r\n locals.onChange(updateMultiselectValues(locals.value, access, checked));\r\n };\r\n\r\n const mapPermission = ({ value, text }: UI.FormOption<API.AccessEnum>) => (\r\n <Checkbox\r\n key={value}\r\n id={`permission-${value}`}\r\n checked={locals.value.includes(value)}\r\n onChange={(checked) => onChange(value, checked)}\r\n caption={text}\r\n name={locals.attrs.name}\r\n />\r\n );\r\n\r\n const filterPermission = ({ value }: UI.FormOption<API.AccessEnum>) => {\r\n if (\r\n locals.value.includes(API.AccessEnum.ADMIN) &&\r\n value !== API.AccessEnum.ADMIN\r\n ) {\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const permissions = locals.options.filter(filterPermission).map(mapPermission);\r\n\r\n return (\r\n <div className=\"permission-select\">\r\n <Message\r\n description={moduleT.t(\r\n 'adminPermissionNote',\r\n 'Administrator permission is required in order to access the System section in settings',\r\n )}\r\n className=\"small\"\r\n />\r\n {permissions}\r\n </div>\r\n );\r\n },\r\n });\r\n};\r\n\r\nexport default PermissionSelector;\r\n","import * as React from 'react';\r\n\r\nimport WebUserConstants from 'constants/WebUserConstants';\r\nimport {\r\n WebUserActionModule,\r\n WebUserCreateAction,\r\n WebUserEditActionMenu,\r\n} from 'actions/ui/system/WebUserActions';\r\n\r\nimport ActionButton from 'components/ActionButton';\r\nimport WebUserDialog from 'routes/Settings/routes/System/components/users/WebUserDialog';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from 'decorators/DataProviderDecorator';\r\n\r\nimport { ActionMenu } from 'components/action-menu';\r\n\r\nimport * as API from 'types/api';\r\nimport * as UI from 'types/ui';\r\n\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\nimport { useFormatter } from 'context/FormatterContext';\r\n\r\ninterface WebUserRowProps {\r\n user: API.WebUser;\r\n moduleT: UI.ModuleTranslator;\r\n}\r\n\r\nconst WebUserRow: React.FC<WebUserRowProps> = ({ user, moduleT }) => {\r\n const { formatRelativeTime } = useFormatter();\r\n return (\r\n <tr>\r\n <td className=\"name dropdown\">\r\n <ActionMenu\r\n caption={<strong>{user.username}</strong>}\r\n actions={WebUserEditActionMenu}\r\n itemData={user}\r\n contextElement=\"#setting-scroll-context\"\r\n />\r\n </td>\r\n <td className=\"permissions\">\r\n {user.permissions.includes(API.AccessEnum.ADMIN)\r\n ? moduleT.translate('Administrator')\r\n : user.permissions.length}\r\n </td>\r\n <td className=\"sessions\">{user.active_sessions}</td>\r\n <td className=\"last-login\">{formatRelativeTime(user.last_login)}</td>\r\n </tr>\r\n );\r\n};\r\n\r\ninterface WebUsersPageProps extends SettingPageProps {}\r\n\r\ninterface WebUsersPageDataProps extends DataProviderDecoratorChildProps {\r\n users: API.WebUser[];\r\n}\r\n\r\nclass WebUsersPage extends React.Component<WebUsersPageProps & WebUsersPageDataProps> {\r\n static readonly displayName = 'WebUsersPage';\r\n\r\n render() {\r\n const { users, moduleT } = this.props;\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <ActionButton action={WebUserCreateAction} moduleData={WebUserActionModule} />\r\n <table className=\"ui striped table\">\r\n <thead>\r\n <tr>\r\n <th>{translate('Username')}</th>\r\n <th>{translate('Permissions')}</th>\r\n <th>{translate('Active sessions')}</th>\r\n <th>{translate('Last logged in')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {users.map((user) => (\r\n <WebUserRow key={user.username} user={user} moduleT={moduleT} />\r\n ))}\r\n </tbody>\r\n </table>\r\n <WebUserDialog moduleT={moduleT} />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default DataProviderDecorator(WebUsersPage, {\r\n urls: {\r\n users: WebUserConstants.USERS_URL,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.ADDED, () =>\r\n refetchData(),\r\n );\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.UPDATED, () =>\r\n refetchData(),\r\n );\r\n addSocketListener(WebUserConstants.MODULE_URL, WebUserConstants.REMOVED, () =>\r\n refetchData(),\r\n );\r\n },\r\n});\r\n","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['use_main_chat_notify', 'show_joins', 'format_release_names'];\r\n\r\nconst GeneralPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default GeneralPage;\r\n","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n 'report_uploads',\r\n 'report_downloads',\r\n 'report_search_alternates',\r\n 'report_added_sources',\r\n 'report_blocked_share',\r\n 'report_hashed_files',\r\n 'report_scheduled_refreshes',\r\n 'report_filelist_dupes',\r\n];\r\n\r\nconst EventPage: React.FC<SettingPageProps> = () => (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default EventPage;\r\n","import * as React from 'react';\r\n\r\nimport RemoteSettingForm from 'routes/Settings/components/RemoteSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = ['history_search_max', 'history_download_max', 'history_chat_log_lines'];\r\n\r\nconst MessageEntry = [\r\n 'history_hub_messages',\r\n 'history_pm_messages',\r\n 'history_log_messages',\r\n];\r\n\r\nconst SessionEntry = [\r\n 'history_hub_sessions',\r\n 'history_pm_sessions',\r\n 'history_filelist_sessions',\r\n];\r\n\r\nconst HistoryPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { t } = moduleT;\r\n return (\r\n <div>\r\n <RemoteSettingForm keys={Entry} />\r\n <RemoteSettingForm\r\n title={t('maxMessageHistory', 'Maximum number of messages to cache')}\r\n keys={MessageEntry}\r\n />\r\n <RemoteSettingForm\r\n title={t('maxSessionHistory', 'Maximum number of previously opened sessions')}\r\n keys={SessionEntry}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default HistoryPage;\r\n","import * as React from 'react';\r\n\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport LocalSettingForm from 'routes/Settings/components/LocalSettingForm';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst Entry = [\r\n LocalSettings.UNREAD_LABEL_DELAY,\r\n LocalSettings.BACKGROUND_IMAGE_URL,\r\n LocalSettings.NO_INSTALL_PROMPT,\r\n];\r\n\r\nconst MiscellaneousPage: React.FC<SettingPageProps> = ({ moduleT }) => (\r\n <div>\r\n <LocalSettingForm moduleT={moduleT} keys={Entry} />\r\n </div>\r\n);\r\n\r\nexport default MiscellaneousPage;\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport { LocalSettings } from 'constants/SettingConstants';\r\nimport LocalSettingForm from 'routes/Settings/components/LocalSettingForm';\r\n\r\nimport '../style.css';\r\nimport { SettingPageProps } from 'routes/Settings/types';\r\n\r\nconst PopupEntry = [\r\n LocalSettings.NOTIFY_MENTION,\r\n LocalSettings.NOTIFY_PM_USER,\r\n LocalSettings.NOTIFY_PM_BOT,\r\n LocalSettings.NOTIFY_HUB_MESSAGE,\r\n\r\n LocalSettings.NOTIFY_BUNDLE_STATUS,\r\n\r\n LocalSettings.NOTIFY_EVENTS_INFO,\r\n LocalSettings.NOTIFY_EVENTS_WARNING,\r\n LocalSettings.NOTIFY_EVENTS_ERROR,\r\n];\r\n\r\nconst NotificationPage: React.FC<SettingPageProps> = ({ moduleT }) => {\r\n const { translate } = moduleT;\r\n return (\r\n <div>\r\n <LocalSettingForm\r\n title={translate('Popup notifications')}\r\n moduleT={moduleT}\r\n keys={PopupEntry}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default NotificationPage;\r\n","import LoginStore from 'stores/reflux/LoginStore';\r\nimport { fetchData } from 'utils/HttpUtils';\r\n\r\nexport const uploadTempFile = async (file: File, authToken: string): Promise<string> => {\r\n // eslint-disable-next-line no-useless-catch\r\n try {\r\n const res = await fetchData(`${getBasePath()}temp`, {\r\n method: 'POST',\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': authToken,\r\n\r\n Authorization: authToken,\r\n },\r\n body: file,\r\n });\r\n\r\n return res.headers.get('Location')!;\r\n } catch (e) {\r\n throw e;\r\n }\r\n};\r\n\r\nconst toCorsSafeUrl = (url: string) => {\r\n const proxyUrl = `${\r\n window.location.origin\r\n }${getBasePath()}proxy?url=${encodeURIComponent(url)}`;\r\n return proxyUrl;\r\n};\r\n\r\nexport const fetchCorsSafeData = async (\r\n url: string,\r\n isJSON: boolean,\r\n options?: RequestInit,\r\n) => {\r\n try {\r\n //console.log(`CORS HTTP request started (${url})`);\r\n\r\n const res = await fetchData(toCorsSafeUrl(url), {\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': LoginStore.authToken,\r\n\r\n // Temp workaround for people upgrading from versions < 2.7.0\r\n // If the new UI was loaded before restarting the app, a cache expiration time of\r\n // one year would have been set for \"Not found\" errors...\r\n 'Cache-Control': 'no-store, must-revalidate, max-age=0',\r\n },\r\n ...options,\r\n });\r\n\r\n const data = (await isJSON) ? res.json() : res.text();\r\n return data;\r\n } catch (e) {\r\n console.error(`CORS HTTP request failed (${url})`, e);\r\n throw e;\r\n }\r\n};\r\n","import ShareProfileConstants from 'constants/ShareProfileConstants';\r\n\r\nimport { Formatter } from 'context/FormatterContext';\r\n\r\nimport * as API from 'types/api';\r\n\r\nexport const formatProfileNameWithSize = (\r\n profile: API.ShareProfile,\r\n { formatSize }: Formatter,\r\n) => {\r\n let str = profile.str;\r\n if (profile.id !== ShareProfileConstants.HIDDEN_PROFILE_ID) {\r\n str += ` (${formatSize(profile.size)})`;\r\n }\r\n\r\n return str;\r\n};\r\n\r\nexport const profileToEnumValue = (profile: API.ShareProfile, formatter: Formatter) => {\r\n return {\r\n id: profile.id,\r\n name: formatProfileNameWithSize(profile, formatter),\r\n };\r\n};\r\n"],"names":["semver","validateAndParse","version","TypeError","match","Error","shift","isWildcard","s","tryParse","v","n","parseInt","isNaN","compareStrings","a","b","ap","bp","String","forceType","compareSegments","i","Math","max","length","r","compareVersions","v1","v2","n1","n2","p1","pop","p2","split","___CSS_LOADER_EXPORT___","push","module","id","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","downloadExtension","socket","url","installId","shasum","post","DOWNLOAD_URL","install_id","handleNpmAction","itemData","npmPackage","data","NPM_PACKAGE_URL","name","tarball","dist","ExtensionInstallURLAction","displayName","icon","CREATE","access","ADMIN","input","approveCaption","content","inputProps","placeholder","type","required","handler","ExtensionInstallNpmAction","ExtensionUpdateNpmAction","REFRESH_COLORED","ExtensionInstallActionModule","moduleId","EXTENSIONS","SearchTypeCreateAction","navigate","SearchTypeEditActions","edit","EDIT","remove","REMOVE","confirmation","rejectCaption","filter","default_type","delete","SEARCH_TYPES_URL","SearchTypeActionModule","SETTINGS","SearchTypeEditActionMenu","moduleData","actions","ShareRefreshAction","SETTINGS_EDIT","REFRESH_URL","ShareActions","refresh","ShareActionModule","SHARE","ShareActionMenu","ShareExcludeAddAction","ShareExcludeEditActions","path","EXCLUDES_REMOVE_URL","ShareExcludeActionModule","subId","ShareExcludeEditMenu","notDefault","profile","default","handleCreate","PROFILES_URL","ShareProfileCreateAction","ShareProfileCloneAction","COPY","newProfile","sourceProfile","roots","get","MODULE_URL","root","rootProfileIds","profiles","map","rootProfile","includes","patch","ShareProfileBrowseAction","FILELISTS_VIEW","FILELIST","location","ownList","sessionStore","ShareProfileEditAction","defaultValue","ShareProfileSetDefaultAction","DEFAULT","ShareProfileRemoveAction","ShareProfileEditActions","browse","divider","ShareProfileActionModule","ShareProfileEditMenu","ShareRootCreateAction","IconConstants","ShareRootEditActions","ShareRootConstants","ROOTS_URL","ShareRootActionModule","ShareRootEditActionMenu","SystemRestartWebAction","SystemShutdownAction","POWER","SystemActionModule","COMMON","WebUserCreateAction","WebUserEditActions","user","USERS_URL","WebUserActionModule","WebUserEditActionMenu","alwaysShow","localSettings","prompt","useContext","t","NO_INSTALL_PROMPT","title","description","className","caption","onClick","setValue","formatText","text","i18nKey","Row","titleWidth","noText","style","overflow","Header","Grid","children","columns","stackable","other","NPM_URL","EXTENSIONS_URL","ENGINES_URL","ENGINES_STATUS_URL","DEFAULT_ENGINE","STARTED","STOPPED","ADDED","REMOVED","UPDATED","INSTALLATION_STARTED","INSTALLATION_SUCCEEDED","INSTALLATION_FAILED","NPM_PACKAGES_URL","NPM_HOMEPAGE_URL","GROUPED_DIRECTORIES_URL","DIRECTORIES_URL","DIRECTORIES_UPDATED","PROFILE_ADDED","PROFILE_UPDATED","PROFILE_REMOVED","HIDDEN_PROFILE_ID","CREATED","Component","listHidden","dataProviderDecoratorSettings","merge","urls","dataConverters","p","onSocketConnected","addSocketListener","refetchData","fetchUrl","unavailableMessage","fetchIntervalSeconds","props","stats","setStats","onStatsReceived","fetchStats","then","catch","error","console","message","fetchInterval","window","setInterval","clearTimeout","undefined","moduleT","keys","onFieldChanged","settings","setSettings","useState","getValues","definitions","useMemo","getDefinitions","saveContext","ref","f","addFormRef","onSave","changedSettingArray","allFields","setValues","Promise","resolve","fieldDefinitions","sourceValue","value","hasChanges","refetchValues","changedValues","Object","ITEMS_SET_URL","ITEMS_DEFINITIONS_URL","onSettingValuesReceived","valueMode","CURRENT","ITEMS_GET_URL","value_mode","sectionToUrl","section","parent","translateSettingSectionTitle","settingsT","translate","NAVIGATION","menuItemToLinkComponent","menuItemInfo","hasAccess","RouterMenuItemLink","childMenuItemToLinkComponent","childMenuItem","session","SideChildSectionMenu","menu","childMenuItems","childAdvancedMenuItems","TopRootSectionMenu","rootMenuItems","Content","contentClassname","selectedChildMenuItem","selectedRootMenuItem","getSaveButton","LayoutHeader","Icon","color","rightComponent","TopSectionSelectionMenu","Dropdown","selection","captionIcon","size","SectionedDropdown","MenuSection","saveState","local","handleSave","saving","setSaving","hasEditAccess","Button","loading","disabled","getMessage","Message","INFO","login","useSettingSaveContext","SectionLayoutComponent","innerWidth","SettingsTopMenuLayout","SettingsSideMenuLayout","menuItems","advancedMenuItems","item","rootMenuItem","pathname","startsWith","rootMenuItemToLinkComponent","Provider","noSave","SettingSaveContext","getSettingFormId","join","forms","Map","changedProperties","setChangedProperties","currentLocation","nextLocation","historyAction","confirm","prop","c","hasOwnProperty","set","clear","getFormRef","promises","Array","from","values","save","all","success","onSettingsSaved","component","TRANSFERS","HUBS_VIEW","SettingsMenu","childToRoute","camelCase","element","SettingSection","index","to","replace","rootSection","child","rootToRoute","systemInfo","formatRelativeTime","formatDateTime","buildDate","client_version","api_version","api_feature_level","client_started","active_sessions","server_threads","HOME_PAGE_URL","HELP_URL","ISSUE_TRACKER_URL","DBIP_URL","STATS_URL","formatSize","formatConnection","total_users","unique_users","active_users","total_share","adc_down_per_user","adc_up_per_user","clients","formatClientRow","uniqueUsers","client","count","formatSeconds","total_size","totalCount","total_file_count","uniqueCount","unique_file_count","total_directory_count","average_file_age","total_searches","perSecondCount","total_searches_per_second","toFixed","tth_searches","recursive_searches","matchedCount","unfiltered_recursive_searches_per_second","filteredPercentage","filtered_searches","resultPercentage","recursive_searches_responded","tokenCount","average_search_token_count","tokenLength","average_search_token_length","matchTime","average_match_ms","totalUp","session_uploaded","start_total_uploaded","totalDown","session_downloaded","start_total_downloaded","TRANSFERRED_BYTES_URL","DETECT_URL","STATUS_URL","CONNECTIVITY_MESSAGE","CONNECTIVITY_STARTED","CONNECTIVITY_FINISHED","ConnectivityDetectAction","CONFIGURE","ConnectivityConstants","ConnectivityActionModule","formatProtocolStatus","protocolStatus","running","auto","auto_detect","status","DataProviderDecorator","runningV4","runningV6","showDetails","setShowDetails","status_v4","status_v6","bind_address","tcp_port","tls_port","udp_port","ActionButton","A","action","mergeData","setDetectState","v6","toI18nKey","defaults","components","portChecker","ExternalLink","LinkConstants","PORTCHECK_URL","faq","CONNECTIVITY_HELP_URL","Entry","protocol","FieldOptionGetter","fieldOptions","formValue","HELP","help","onFieldSetting","FORCE_MANUAL","ProtocolPage","state","autoDetectEnabled","convertValue","key","this","protocolEnabled","INCOMING_DISABLED","autoDetect","indexOf","setState","render","outgoing_mode","OUTGOING_SOCKS","SegmentsEntry","BufferEntry","CompressionEntry","FavoriteDirectoryCreateAction","FavoriteDirectoryEditActions","directory","FavoriteDirectoryConstants","FavoriteDirectoryActionModule","FavoriteDirectoryEditActionMenu","DIRECTORY_PATH","STRING","ModalRouteDecorator","directoryEntry","virtualNames","formRef","useRef","isNew","RouteModal","onApprove","current","closable","FOLDER","Form","config","assign","historyId","FilesystemConstants","LOCATION_DOWNLOAD","factory","form","Textbox","template","suggestionGetter","changedFields","params","directoryId","contextElement","getRow","directories","RemoteSettingForm","VARIABLE_HELP_URL","FavoriteDirectoryTable","HighPrioEntry","LIST","item_type","searchTypeEntry","SearchConstants","searchTypeId","formatBoolean","str","extensions","searchTypes","NOTE","SEARCH_TYPES_UPDATED","Skiplist","enginesStatus","engineName","DEFAULT_ENGINE_URL","WARNING","loaderText","packageCatalog","installedPackages","installedPackage","find","Extension","getItem","package","ExtensionConstants","objects","refetchInstalled","EngineStatusMessage","ExtensionsConfigureDialog","getSettingsUrl","extensionId","extension","dynamicHeight","convertNpmPackage","_npmUser","publisher","username","date","dataError","npmError","private","managed","renderOnError","isManaged","isRunning","isDisabled","ExtensionStartAction","PLAY","ExtensionStopAction","STOP","ExtensionConfigureAction","has_settings","ExtensionDisableAction","DISABLE","ExtensionEnableAction","ENABLE","ExtensionRemoveAction","ExtensionManageActions","start","stop","configure","disable","enable","ExtensionManageActionModule","ExtensionManageActionsMenu","InstallButton","hasUpdate","installing","ids","remoteMenuId","MenuConstants","EXTENSION","remoteMenuNestingThreshold","button","menuElementClassName","EXTERNAL","Version","packageInfo","versionDesc","formatAuthor","author","formatNote","onInstallationStarted","onInstallationCompleted","componentDidMount","ExtensionIcon","outdated","latest","SocketSubscriptionDecorator","getCornerIcon","cornerIcon","ignoreInfo","userIcon","USER","ignored_messages","cid","ignores","IGNORES_URL","IGNORE_ADDED","IGNORE_REMOVED","platform","WINDOWS","profileId","NORMAL","RAR","LAN","toString","translateHelp","TRANSLATOR_HELP","excludes","onConfirm","EXCLUDES_ADD_URL","plainT","initialPath","LOCATION_GENERIC","subHeader","selectMode","DIRECTORY","EXCLUDES_URL","EXCLUDE_ADDED","EXCLUDE_REMOVED","OptimizeLayout","startHandler","verify","setVerify","marginTop","Checkbox","checked","onChange","floating","file_index_size","hash_store_size","maintenance_running","HashConstants","OPTIMIZE_DATABASE_URL","DATABASE_STATUS_URL","DATABASE_STATUS","formatter","ActionHandlerDecorator","onClickAction","MenuItemLink","entity","getProfileItem","ShareProfileRow","files","ShareProfileDecorator","getAutoKey","changedKey","autoSettingKey","FORCE_AUTO","settingKey","Auto","Manual","speedtest","SPEEDTEST_URL","Generic","Hooks","LogSection","enabled","convertKey","optionalSuffix","suffix","onSettingsReceived","onEnableStateChanged","onContentSetting","getChildClass","Title","simple","sectionKeys","simpleKeys","Accordion","controlled","sectionKey","MessageSectionKeys","TransferSectionKeys","SimpleSectionKeys","PlainEntry","TlsEntry","SEARCH","DOWNLOAD","EVENTS_VIEW","EVENTS_EDIT","QUEUE_VIEW","QUEUE_EDIT","FAVORITE_HUBS_VIEW","FAVORITE_HUBS_EDIT","SETTINGS_VIEW","FILESYSTEM_VIEW","FILESYSTEM_EDIT","HUBS_EDIT","HUBS_SEND","PRIVATE_CHAT_VIEW","PRIVATE_CHAT_EDIT","PRIVATE_CHAT_SEND","FILELISTS_EDIT","VIEW_FILE_VIEW","VIEW_FILE_EDIT","PermissionAction","AccessCaptions","VIEW","SEND_MESSAGES","loginUser","PASSWORD","optional","getEntry","permissionT","permissions","def","reduce","reduced","cur","captionEntry","reducePermissionToOption","buildDefinitions","Select","templates","select","clone","renderSelect","attrs","WebUserConstants","userId","WebUserRow","last_login","WebUsersPage","users","MessageEntry","SessionEntry","UNREAD_LABEL_DELAY","BACKGROUND_IMAGE_URL","PopupEntry","NOTIFY_MENTION","NOTIFY_PM_USER","NOTIFY_PM_BOT","NOTIFY_HUB_MESSAGE","NOTIFY_BUNDLE_STATUS","NOTIFY_EVENTS_INFO","NOTIFY_EVENTS_WARNING","NOTIFY_EVENTS_ERROR","LocalSettingForm","uploadTempFile","file","authToken","getBasePath","method","headers","Authorization","body","e","fetchCorsSafeData","isJSON","res","origin","encodeURIComponent","toCorsSafeUrl","json","formatProfileNameWithSize","profileToEnumValue"],"sourceRoot":""}
|