From 95e15152289c3d6c01fcbd902ba6ab8985a71b44 Mon Sep 17 00:00:00 2001 From: liyp Date: Mon, 6 Mar 2023 09:10:48 +0800 Subject: [PATCH] first commit --- CHANGELOG.md | 419 + Dockerfile | 19 + README.md | 38 + assets/CNAME | 1 + assets/_headers | 12 + assets/apple-touch-icon-precomposed.png | Bin 0 -> 48291 bytes assets/logo.png | Bin 0 -> 81167 bytes assets/yacd.ico | Bin 0 -> 181508 bytes assets/yacd.png | Bin 0 -> 48291 bytes docker-entrypoint.sh | 3 + docker/nginx-default.conf | 31 + index.html | 22 + package.json | 100 + pnpm-lock.yaml | 7350 +++++++++++++++++ postcss.config.js | 4 + src/App.module.scss | 20 + src/App.tsx | 75 + src/api/configs.ts | 48 + src/api/connections.ts | 91 + src/api/logs.ts | 151 + src/api/proxies.ts | 78 + src/api/rule-provider.ts | 84 + src/api/rules.ts | 40 + src/api/traffic.ts | 119 + src/api/version.ts | 27 + src/components/APIConfig.module.scss | 52 + src/components/APIConfig.tsx | 162 + src/components/APIDiscovery.module.scss | 33 + src/components/APIDiscovery.tsx | 58 + src/components/BackendList.module.scss | 102 + src/components/BackendList.tsx | 142 + src/components/Button.module.scss | 72 + src/components/Button.tsx | 82 + src/components/Collapsible.tsx | 72 + .../CollapsibleSectionHeader.module.scss | 39 + src/components/CollapsibleSectionHeader.tsx | 49 + src/components/Config.module.scss | 43 + src/components/Config.tsx | 403 + src/components/ConnectionTable.module.scss | 54 + src/components/ConnectionTable.tsx | 111 + src/components/Connections.css | 49 + src/components/Connections.module.scss | 48 + src/components/Connections.tsx | 263 + src/components/ContentHeader.module.scss | 18 + src/components/ContentHeader.tsx | 17 + src/components/ErrorBoundary.tsx | 32 + .../ErrorBoundaryFallback.module.scss | 37 + src/components/ErrorBoundaryFallback.tsx | 31 + src/components/Field.module.scss | 42 + src/components/Field.tsx | 27 + src/components/Home.module.scss | 8 + src/components/Home.tsx | 27 + src/components/Icon.tsx | 20 + src/components/Input.module.scss | 26 + src/components/Input.tsx | 24 + src/components/Loading.module.scss | 28 + src/components/Loading.tsx | 18 + src/components/Loading2.module.scss | 8 + src/components/Loading2.tsx | 14 + src/components/LogSearch.ts | 6 + src/components/Logs.module.scss | 75 + src/components/Logs.tsx | 106 + src/components/Modal.module.scss | 21 + src/components/Modal.tsx | 38 + .../ModalCloseAllConnections.module.scss | 23 + src/components/ModalCloseAllConnections.tsx | 43 + src/components/Rule.module.scss | 38 + src/components/Rule.tsx | 42 + src/components/Rules.module.scss | 23 + src/components/Rules.tsx | 115 + src/components/Search.module.scss | 47 + src/components/Search.tsx | 46 + src/components/Selection.module.scss | 23 + src/components/Selection.tsx | 45 + src/components/SideBar.module.scss | 112 + src/components/SideBar.tsx | 105 + src/components/StateProvider.tsx | 99 + src/components/StyleGuide.tsx | 71 + src/components/SvgGithub.tsx | 24 + src/components/SvgYacd.module.scss | 14 + src/components/SvgYacd.tsx | 92 + src/components/SwitchThemed.tsx | 35 + src/components/ToggleSwitch.module.scss | 39 + src/components/ToggleSwitch.tsx | 65 + src/components/TrafficChart.tsx | 61 + src/components/TrafficChartSample.tsx | 52 + src/components/TrafficNow.module.scss | 28 + src/components/TrafficNow.tsx | 81 + src/components/about/About.module.scss | 20 + src/components/about/About.tsx | 56 + src/components/proxies/ClosePrevConns.tsx | 48 + src/components/proxies/Proxies.module.scss | 38 + src/components/proxies/Proxies.tsx | 128 + src/components/proxies/Proxy.module.scss | 103 + src/components/proxies/Proxy.tsx | 231 + src/components/proxies/ProxyGroup.module.scss | 11 + src/components/proxies/ProxyGroup.tsx | 137 + .../proxies/ProxyLatency.module.scss | 10 + src/components/proxies/ProxyLatency.tsx | 16 + src/components/proxies/ProxyList.module.scss | 19 + src/components/proxies/ProxyList.tsx | 56 + src/components/proxies/ProxyPageFab.tsx | 79 + .../proxies/ProxyProvider.module.scss | 32 + src/components/proxies/ProxyProvider.tsx | 197 + src/components/proxies/ProxyProviderList.tsx | 27 + src/components/proxies/Settings.module.scss | 17 + src/components/proxies/Settings.tsx | 92 + src/components/proxies/hooks.tsx | 133 + src/components/proxies/index.tsx | 1 + src/components/proxies/proxies.hooks.tsx | 50 + .../rules/RuleProviderItem.module.scss | 33 + src/components/rules/RuleProviderItem.tsx | 37 + src/components/rules/RulesPageFab.tsx | 24 + src/components/rules/rules.hooks.tsx | 84 + src/components/shared/BaseModal.module.scss | 17 + src/components/shared/BaseModal.tsx | 29 + src/components/shared/Basic.module.scss | 133 + src/components/shared/Basic.tsx | 16 + src/components/shared/Fab.module.scss | 33 + src/components/shared/Fab.tsx | 152 + src/components/shared/Head.tsx | 34 + src/components/shared/RotateIcon.module.scss | 16 + src/components/shared/RotateIcon.tsx | 16 + src/components/shared/Select.module.scss | 31 + src/components/shared/Select.tsx | 21 + src/components/shared/Styled.module.scss | 5 + src/components/shared/Styled.tsx | 7 + src/components/shared/TextFitler.module.scss | 19 + src/components/shared/TextFitler.tsx | 19 + .../shared/ThemeSwitcher.module.scss | 55 + src/components/shared/ThemeSwitcher.tsx | 138 + src/components/shared/rtf.css | 233 + src/components/svg/Equalizer.tsx | 27 + src/custom.d.ts | 69 + src/hooks/basic.ts | 9 + src/hooks/useLineChart.ts | 25 + src/hooks/useRemainingViewPortHeight.ts | 32 + src/hooks/useTextInput.ts | 21 + src/i18n/en.ts | 60 + src/i18n/zh.ts | 60 + src/main.tsx | 76 + src/misc/chart-lib.ts | 23 + src/misc/chart.ts | 79 + src/misc/createResource.ts | 45 + src/misc/errors.ts | 21 + src/misc/i18n.ts | 61 + src/misc/keycode.ts | 6 + src/misc/motion.ts | 3 + src/misc/pretty-bytes.ts | 13 + src/misc/query.ts | 11 + src/misc/request-helper.ts | 45 + src/misc/shallowEqual.ts | 31 + src/misc/storage.ts | 32 + src/misc/utils.ts | 35 + src/store/app.ts | 219 + src/store/configs.ts | 185 + src/store/index.ts | 33 + src/store/logs.ts | 58 + src/store/modals.ts | 19 + src/store/proxies.tsx | 397 + src/store/rules.ts | 6 + src/store/types.ts | 144 + src/styles/main.scss | 219 + src/styles/utils/custom-media.scss | 3 + src/sw.ts | 74 + src/swRegistration.ts | 127 + src/types.ts | 6 + tsconfig.json | 23 + vite.config.ts | 39 + 169 files changed, 17501 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 assets/CNAME create mode 100644 assets/_headers create mode 100644 assets/apple-touch-icon-precomposed.png create mode 100644 assets/logo.png create mode 100644 assets/yacd.ico create mode 100644 assets/yacd.png create mode 100755 docker-entrypoint.sh create mode 100644 docker/nginx-default.conf create mode 100644 index.html create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 postcss.config.js create mode 100644 src/App.module.scss create mode 100644 src/App.tsx create mode 100644 src/api/configs.ts create mode 100644 src/api/connections.ts create mode 100644 src/api/logs.ts create mode 100644 src/api/proxies.ts create mode 100644 src/api/rule-provider.ts create mode 100644 src/api/rules.ts create mode 100644 src/api/traffic.ts create mode 100644 src/api/version.ts create mode 100644 src/components/APIConfig.module.scss create mode 100644 src/components/APIConfig.tsx create mode 100644 src/components/APIDiscovery.module.scss create mode 100644 src/components/APIDiscovery.tsx create mode 100644 src/components/BackendList.module.scss create mode 100644 src/components/BackendList.tsx create mode 100644 src/components/Button.module.scss create mode 100644 src/components/Button.tsx create mode 100644 src/components/Collapsible.tsx create mode 100644 src/components/CollapsibleSectionHeader.module.scss create mode 100644 src/components/CollapsibleSectionHeader.tsx create mode 100644 src/components/Config.module.scss create mode 100644 src/components/Config.tsx create mode 100644 src/components/ConnectionTable.module.scss create mode 100644 src/components/ConnectionTable.tsx create mode 100644 src/components/Connections.css create mode 100644 src/components/Connections.module.scss create mode 100644 src/components/Connections.tsx create mode 100644 src/components/ContentHeader.module.scss create mode 100644 src/components/ContentHeader.tsx create mode 100644 src/components/ErrorBoundary.tsx create mode 100644 src/components/ErrorBoundaryFallback.module.scss create mode 100644 src/components/ErrorBoundaryFallback.tsx create mode 100644 src/components/Field.module.scss create mode 100644 src/components/Field.tsx create mode 100644 src/components/Home.module.scss create mode 100644 src/components/Home.tsx create mode 100644 src/components/Icon.tsx create mode 100644 src/components/Input.module.scss create mode 100644 src/components/Input.tsx create mode 100644 src/components/Loading.module.scss create mode 100644 src/components/Loading.tsx create mode 100644 src/components/Loading2.module.scss create mode 100644 src/components/Loading2.tsx create mode 100644 src/components/LogSearch.ts create mode 100644 src/components/Logs.module.scss create mode 100644 src/components/Logs.tsx create mode 100644 src/components/Modal.module.scss create mode 100644 src/components/Modal.tsx create mode 100644 src/components/ModalCloseAllConnections.module.scss create mode 100644 src/components/ModalCloseAllConnections.tsx create mode 100644 src/components/Rule.module.scss create mode 100644 src/components/Rule.tsx create mode 100644 src/components/Rules.module.scss create mode 100644 src/components/Rules.tsx create mode 100644 src/components/Search.module.scss create mode 100644 src/components/Search.tsx create mode 100644 src/components/Selection.module.scss create mode 100644 src/components/Selection.tsx create mode 100644 src/components/SideBar.module.scss create mode 100644 src/components/SideBar.tsx create mode 100644 src/components/StateProvider.tsx create mode 100644 src/components/StyleGuide.tsx create mode 100644 src/components/SvgGithub.tsx create mode 100644 src/components/SvgYacd.module.scss create mode 100644 src/components/SvgYacd.tsx create mode 100644 src/components/SwitchThemed.tsx create mode 100644 src/components/ToggleSwitch.module.scss create mode 100644 src/components/ToggleSwitch.tsx create mode 100644 src/components/TrafficChart.tsx create mode 100644 src/components/TrafficChartSample.tsx create mode 100644 src/components/TrafficNow.module.scss create mode 100644 src/components/TrafficNow.tsx create mode 100644 src/components/about/About.module.scss create mode 100644 src/components/about/About.tsx create mode 100644 src/components/proxies/ClosePrevConns.tsx create mode 100644 src/components/proxies/Proxies.module.scss create mode 100644 src/components/proxies/Proxies.tsx create mode 100644 src/components/proxies/Proxy.module.scss create mode 100644 src/components/proxies/Proxy.tsx create mode 100644 src/components/proxies/ProxyGroup.module.scss create mode 100644 src/components/proxies/ProxyGroup.tsx create mode 100644 src/components/proxies/ProxyLatency.module.scss create mode 100644 src/components/proxies/ProxyLatency.tsx create mode 100644 src/components/proxies/ProxyList.module.scss create mode 100644 src/components/proxies/ProxyList.tsx create mode 100644 src/components/proxies/ProxyPageFab.tsx create mode 100644 src/components/proxies/ProxyProvider.module.scss create mode 100644 src/components/proxies/ProxyProvider.tsx create mode 100644 src/components/proxies/ProxyProviderList.tsx create mode 100644 src/components/proxies/Settings.module.scss create mode 100644 src/components/proxies/Settings.tsx create mode 100644 src/components/proxies/hooks.tsx create mode 100644 src/components/proxies/index.tsx create mode 100644 src/components/proxies/proxies.hooks.tsx create mode 100644 src/components/rules/RuleProviderItem.module.scss create mode 100644 src/components/rules/RuleProviderItem.tsx create mode 100644 src/components/rules/RulesPageFab.tsx create mode 100644 src/components/rules/rules.hooks.tsx create mode 100644 src/components/shared/BaseModal.module.scss create mode 100644 src/components/shared/BaseModal.tsx create mode 100644 src/components/shared/Basic.module.scss create mode 100644 src/components/shared/Basic.tsx create mode 100644 src/components/shared/Fab.module.scss create mode 100644 src/components/shared/Fab.tsx create mode 100644 src/components/shared/Head.tsx create mode 100644 src/components/shared/RotateIcon.module.scss create mode 100644 src/components/shared/RotateIcon.tsx create mode 100644 src/components/shared/Select.module.scss create mode 100644 src/components/shared/Select.tsx create mode 100644 src/components/shared/Styled.module.scss create mode 100644 src/components/shared/Styled.tsx create mode 100644 src/components/shared/TextFitler.module.scss create mode 100644 src/components/shared/TextFitler.tsx create mode 100644 src/components/shared/ThemeSwitcher.module.scss create mode 100644 src/components/shared/ThemeSwitcher.tsx create mode 100644 src/components/shared/rtf.css create mode 100644 src/components/svg/Equalizer.tsx create mode 100644 src/custom.d.ts create mode 100644 src/hooks/basic.ts create mode 100644 src/hooks/useLineChart.ts create mode 100644 src/hooks/useRemainingViewPortHeight.ts create mode 100644 src/hooks/useTextInput.ts create mode 100644 src/i18n/en.ts create mode 100644 src/i18n/zh.ts create mode 100644 src/main.tsx create mode 100644 src/misc/chart-lib.ts create mode 100644 src/misc/chart.ts create mode 100644 src/misc/createResource.ts create mode 100644 src/misc/errors.ts create mode 100644 src/misc/i18n.ts create mode 100644 src/misc/keycode.ts create mode 100644 src/misc/motion.ts create mode 100644 src/misc/pretty-bytes.ts create mode 100644 src/misc/query.ts create mode 100644 src/misc/request-helper.ts create mode 100644 src/misc/shallowEqual.ts create mode 100644 src/misc/storage.ts create mode 100644 src/misc/utils.ts create mode 100644 src/store/app.ts create mode 100644 src/store/configs.ts create mode 100644 src/store/index.ts create mode 100644 src/store/logs.ts create mode 100644 src/store/modals.ts create mode 100644 src/store/proxies.tsx create mode 100644 src/store/rules.ts create mode 100644 src/store/types.ts create mode 100644 src/styles/main.scss create mode 100644 src/styles/utils/custom-media.scss create mode 100644 src/sw.ts create mode 100644 src/swRegistration.ts create mode 100644 src/types.ts create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1503bea --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,419 @@ +# Changelog + +## [0.3.5](https://github.com/haishanh/yacd/compare/v0.3.4...v0.3.5) (2022-05-14) + +Added: + +- Added "Auto" theme option for theme to follow system theme preference +- Display rule payload if possible in rule column of connections table +- Allow override default backend url use environment variable with docker container +- Gzip and cache static assets in docker container +- Docker image is now published to ghcr too + +Changed: + +- Use Inter as app wide font + +## [0.3.4](https://github.com/haishanh/yacd/compare/v0.3.3...v0.3.4) (2021-11-14) + +Added: + +- Add float action button to pause/start log streaming + +## [0.3.3](https://github.com/haishanh/yacd/compare/v0.3.2...v0.3.3) (2021-07-19) + +Added: + +- Support switch theme on backend config page +- If / is api server, use it as default + +## [0.3.2](https://github.com/haishanh/yacd/compare/v0.3.1...v0.3.2) (2021-06-07) + +Changed: + +- Change web base to './' + +## [0.3.1](https://github.com/haishanh/yacd/compare/v0.3.0...v0.3.1) (2021-06-06) + +Fixed: + +- Fixed floating action button style + +## [0.3.0](https://github.com/haishanh/yacd/compare/v0.2.15...v0.3.0) (2021-06-05) + +Changed: + +- Switch the build system to use Vite. This should not change much about user experience. +- Style tweaks: + - The light theme now use a light gray background instead of a pure white + - Statistic blocks on Overview are now styled more like a card + - Log type badges are now ellipse shaped + - Config fields are more compact now + +Added: + +- Request logs with configured log level +- Reconnect logs web socket on log level config change + +## [0.2.15](https://github.com/haishanh/yacd/compare/v0.2.14...v0.2.15) (2021-02-28) + +Changed: + +- Display API backend info in title only when there are multiple backends +- Changed the function of floating action button from refresh to update all providers on rules page + +Added: + +- Action button to update all proxies providers on proxies page + +## [0.2.14](https://github.com/haishanh/yacd/compare/v0.2.13...v0.2.14) (2021-01-04) + +Added: + +- support set default Clash API baseURL with data attribute in HTML template (see [details](https://github.com/haishanh/yacd/pull/550)) +- add apple-touch-icon\*.png + +Fixed: + +- encode URI for latency test url + +## [0.2.13](https://github.com/haishanh/yacd/compare/v0.2.12...v0.2.13) (2020-12-06) + +Added: + +- Initial Chinese UI language support + +Fixed: + +- Fix weird scroll behavior on config page + +## [0.2.12](https://github.com/haishanh/yacd/compare/v0.2.11...v0.2.12) (2020-11-24) + +Changed: + +- Some minor accessibility improvements +- Changed log level display order to `debug warning info error silent` + +## [0.2.11](https://github.com/haishanh/yacd/compare/v0.2.10...v0.2.11) (2020-11-09) + +Changed: + +- Display proxy type "Shadowsocks" as "SS" to make proxy item tile more compact + +## [0.2.10](https://github.com/haishanh/yacd/compare/v0.2.9...v0.2.10) (2020-11-06) + +Added: + +- Precache assets with service worker. + +## [0.2.9](https://github.com/haishanh/yacd/compare/v0.2.8...v0.2.9) (2020-11-01) + +Added: + +- Display current backend host in title. + +Changed: + +- Change backend baseURL default port to 9090. + +## [0.2.8](https://github.com/haishanh/yacd/compare/v0.2.7...v0.2.8) (2020-10-12) + +Added: + +- Better error message for filling API base URL without providing a http protocol prefix. + +## [0.2.7](https://github.com/haishanh/yacd/compare/v0.2.6...v0.2.7) (2020-09-13) + +Added: + +- multi backends management (see "Switch backend" action the the bottom of Config page) + +## [0.2.6](https://github.com/haishanh/yacd/compare/v0.2.5...v0.2.6) (2020-09-08) + +Changed: + +- use API base URL instead of hostname and port for Clash backend config + +## [0.2.5](https://github.com/haishanh/yacd/compare/v0.2.4...v0.2.5) (2020-08-30) + +Added: + +- docker image arm and arm64 support + +## [0.2.4](https://github.com/haishanh/yacd/compare/v0.2.3...v0.2.4) (2020-08-11) + +Fixed: + +- fix cannot change mixed port + +## [0.2.3](https://github.com/haishanh/yacd/compare/v0.2.2...v0.2.3) (2020-08-06) + +Changed: + +- use desc sort first for columns with numeric value in connections table + +## [0.2.2](https://github.com/haishanh/yacd/compare/v0.2.1...v0.2.2) (2020-08-01) + +Added: + +- a simple about page + +Removed: + +- logo in sidebar + +## [0.2.1](https://github.com/haishanh/yacd/compare/v0.2.0...v0.2.1) (2020-07-13) + +Fixed: + +- uri-encode API secret for it to be used in url safely + +## [0.2.0](https://github.com/haishanh/yacd/compare/v0.1.25...v0.2.0) (2020-07-04) + +Added: + +- support rule provider + +## [0.1.25](https://github.com/haishanh/yacd/compare/v0.1.24...v0.1.25) (2020-07-01) + +Added: + +- support mixed-port + +## [0.1.24](https://github.com/haishanh/yacd/compare/v0.1.23...v0.1.24) (2020-06-22) + +Fixed: + +- fix can not type in Chinese in proxy text filter input + +## [0.1.23](https://github.com/haishanh/yacd/compare/v0.1.22...v0.1.23) (2020-06-20) + +Added: + +- add a simple filter for proxy names + +Fixed: + +- fix color display for unavailable proxy item + +## [0.1.22](https://github.com/haishanh/yacd/compare/v0.1.21...v0.1.22) (2020-06-18) + +Fixed: + +- fix mode switching +- fix broken "Hide unavailable proxies" setting + +Changed: + +- make proxy group lowest latency item when sorting by latency + +## [0.1.21](https://github.com/haishanh/yacd/compare/v0.1.20...v0.1.21) (2020-06-17) + +Fixed: + +- default to big latency for items with unavailable statistics when sorting + +Added: + +- a toggle to close old connections automatically when switching proxy +- use special color for non-proxy summary view dot item + +## [0.1.20](https://github.com/haishanh/yacd/compare/v0.1.19...v0.1.20) (2020-06-08) + +Changed: + +- switch to Open Sans and reduce emitted font files + +## [0.1.19](https://github.com/haishanh/yacd/compare/v0.1.18...v0.1.19) (2020-06-07) + +Added: + +- modal prompt to close previous connections when switch proxy + +Fixed: + +- mode not display correctly due to clash API change + +Changed: + +- switch primary font family from "Merriweather Sans" to "Inter", also starting to self hosting font files + +## [0.1.18](https://github.com/haishanh/yacd/compare/v0.1.17...v0.1.18) (2020-06-04) + +Added: + +- test latency button for each proxy group + +## [0.1.17](https://github.com/haishanh/yacd/compare/v0.1.16...v0.1.17) (2020-06-03) + +Changed: + +- reduce connections table visual width + +## [0.1.16](https://github.com/haishanh/yacd/compare/v0.1.15...v0.1.16) (2020-05-31) + +Added: + +- filtering connections + +## [0.1.15](https://github.com/haishanh/yacd/compare/v0.1.14...v0.1.15) (2020-05-25) + +Added: + +- add loading status to test latency button + +## [0.1.14](https://github.com/haishanh/yacd/compare/v0.1.13...v0.1.14) (2020-05-17) + +Added: + +- button to pause connection refresh + +Fixed: + +- sorting option accessibility issue due to incorrect background in dark mode + +## [0.1.13](https://github.com/haishanh/yacd/compare/v0.1.12...v0.1.13) (2020-05-01) + +Changed: + +- use color icons in sidebar (experimental) + +## [0.1.12](https://github.com/haishanh/yacd/compare/v0.1.11...v0.1.12) (2020-04-26) + +Features: + +- allow change proxies sorting in group + +## [0.1.11](https://github.com/haishanh/yacd/compare/v0.1.10...v0.1.11) (2020-03-21) + +Features: + +- remembers group collapse state + +## [0.1.10](https://github.com/haishanh/yacd/compare/v0.1.9...v0.1.10) (2020-03-14) + +Fixes: + +- fix broken allow-lan switch + +Features: + +- support set theme with querystring `?theme=dark` or `?theme=light` + +## [0.1.9](https://github.com/haishanh/yacd/compare/v0.1.8...v0.1.9) (2020-03-01) + +Fixes: + +- allow request latency for non-original clash proxy types + +## [0.1.8](https://github.com/haishanh/yacd/compare/v0.1.7...v0.1.8) (2020-03-01) + +Features: + +- support overwrite API hostname in querystring with `?hostname=` +- show current download/upload speed of connections + +## [0.1.7](https://github.com/haishanh/yacd/compare/v0.1.6...v0.1.7) (2020-02-11) + +Refactor: + +- proxies page UI improvement + +Fixes: + +- use destination ip as host if host is an empty string + +## [0.1.6](https://github.com/haishanh/yacd/compare/v0.1.5...v0.1.6) (2020-01-07) + +Features: + +- keep up to 100 closed connections in another tab + +## [0.1.5](https://github.com/haishanh/yacd/compare/v0.1.4...v0.1.5) (2020-01-04) + +Features: + +- support change latency test url #286 + +## [0.1.4](https://github.com/haishanh/yacd/compare/v0.1.3...v0.1.4) (2020-01-03) + +Features: + +- refresh providers and proxies on window regain focus + +Fixes: + +- optimize test latency action when there are providers +- do not show provider section when is no provider + +## [0.1.3](https://github.com/haishanh/yacd/compare/v0.1.2...v0.1.3) (2019-12-27) + +Features: + +- can healthcheck a provider + +## [0.1.2](https://github.com/haishanh/yacd/compare/v0.1.1...v0.1.2) (2019-12-22) + +Fixes: + +- typo in connections table header + +## [0.1.1](https://github.com/haishanh/yacd/compare/v0.1.0...v0.1.1) (2019-12-21) + +Fixes: + +- connections table header data miss alignment + +## [0.1.0](https://github.com/haishanh/yacd/compare/v0.0.10...v0.1.0) (2019-12-20) + +Features: + +- support proxy provider + +## [0.0.10](https://github.com/haishanh/yacd/compare/v0.0.9...v0.0.10) (2019-12-04) + +Features: + +- add upload/download total and connectors number on overview + +## [0.0.9](https://github.com/haishanh/yacd/compare/v0.0.8...v0.0.9) (2019-12-02) + +Fix: + +- specify fab group z-index + +## [0.0.8](https://github.com/haishanh/yacd/compare/v0.0.7...v0.0.8) (2019-12-01) + +Features: + +- support close all connections + +## [0.0.7](https://github.com/haishanh/yacd/compare/v0.0.6...v0.0.7) (2019-11-20) + +Features: + +- use history latency data + +## [0.0.6](https://github.com/haishanh/yacd/compare/v0.0.5...v0.0.6) (2019-11-17) + +Improvements: + +- improve UI for small screens +- connections: update connections table sorting indicator icon +- connections: add place holder when there is no connections data + +## [0.0.5](https://github.com/haishanh/yacd/compare/v0.0.4...v0.0.5) (2019-11-09) + +Features: + +- connections inspection + +## [0.0.4](https://github.com/haishanh/yacd/compare/v0.0.3...v0.0.4) (2019-10-14) + +Features: + +- probing the API server with the given url and auto fill hostname and port + +Internal: + +- upgrade dependencies diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6c6cb4f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM --platform=$BUILDPLATFORM node:alpine AS builder +WORKDIR /app + +RUN npm i -g pnpm +COPY pnpm-lock.yaml package.json . +RUN pnpm i + +COPY . . +RUN pnpm build \ + # remove source maps - people like small image + && rm public/*.map || true + +FROM --platform=$TARGETPLATFORM nginx:alpine +COPY docker/nginx-default.conf /etc/nginx/conf.d/default.conf +RUN rm -rf /usr/share/nginx/html/* +COPY --from=builder /app/public /usr/share/nginx/html +ENV YACD_DEFAULT_BACKEND "http://127.0.0.1:9090" +ADD docker-entrypoint.sh / +CMD ["/docker-entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..b2159f5 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +

+ yacd +

+ +> Yet Another [Clash](https://github.com/yaling888/clash) [Dashboard](https://github.com/yaling888/clash-dashboard) + +## Usage + +Install [twemoji](https://github.com/mozilla/twemoji-colr/releases) to display emoji better on Windows system. + + +The site http://yacd.metacubex.one is served with HTTP not HTTPS is because many browsers block requests to HTTP resources from a HTTPS website. If you think it's not safe, you could just download the [zip of the gh-pages](https://github.com/yaling888/yacd/archive/gh-pages.zip), unzip and serve those static files with a web server(like Nginx). + +**Supported URL query params** + +| Param | Description | +| -------- | ---------------------------------------------------------------------------------- | +| hostname | Hostname of the clash backend API (usually the host part of `external-controller`) | +| port | Port of the clash backend API (usually the port part of `external-controller`) | +| secret | Clash API secret (`secret` in your config.yaml) | +| theme | UI color scheme (dark, light, auto) | + +## Development + +```sh +# install dependencies +# you may install pnpm with `npm i -g pnpm` +pnpm i + +# start the dev server +# then go to http://127.0.0.1:3000 +pnpm start + + +# build optimized assets +# ready to deploy assets will be in the directory `public` +pnpm build +``` diff --git a/assets/CNAME b/assets/CNAME new file mode 100644 index 0000000..8f3b90f --- /dev/null +++ b/assets/CNAME @@ -0,0 +1 @@ +yacd.metacubex.one diff --git a/assets/_headers b/assets/_headers new file mode 100644 index 0000000..877d928 --- /dev/null +++ b/assets/_headers @@ -0,0 +1,12 @@ +# for netlify hosting +# https://docs.netlify.com/routing/headers/#syntax-for-the-headers-file + +/* + X-Frame-Options: DENY + X-XSS-Protection: 1; mode=block + X-Content-Type-Options: nosniff + Referrer-Policy: same-origin +/*.css + Cache-Control: public, max-age=31536000, immutable +/*.js + Cache-Control: public, max-age=31536000, immutable diff --git a/assets/apple-touch-icon-precomposed.png b/assets/apple-touch-icon-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..cbb3fcbf293ab72a7776270f285c82be6c993caf GIT binary patch literal 48291 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%0D`5#VY!PqZcCiXSE0Nl+GPQ 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 literal 0 HcmV?d00001 diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1f6323dad3ba9c5d32060d61c498a12f371e8fd5 GIT binary patch literal 81167 zcmc$_WmFx_wkW!AcPF^}!rk41TX0)QaM$4OPH+gW3wI3=+%32T*Wk|O+h_0d-j6fx z81IcI{iCaD_VlXi?%8v8q>7RZ3L+sQ002Odla*8h03biQkN|ktkLJd6{^_G3aFx<= zRd=v(^)PV;0mRH5OhIIFb|#h}HIRw9m(vJH5CDL3vewXX)%mQ*Z{}dfV)73Ti>ICA z2Q>g7DB|g8VrBz!B{KzCTH6azTy*qMkXf4xQD}30X8r6a0kX1|^>zlSdn;*}dE1!r znNx@elL>nAe=x8Extfr9+S%H>@OuhT{EILDNB-AD6Td_6#u1^&Sw=e2?u8o z85avTvl$yFI~flj3mZ2pA3G-#89OT*50I4y$i~6U%Er&i&CkI{_V0t@Lz=U>1;3i4 z^uJ|&jD#qxTwNXcfj|!r4;Bv&76)fbAR8YaACQ$D$j;9Efx+zJW$$X@$!zaJ`5z9F zAQv-dYe!dW2Ya%AIGUI`xVZ{Zd}#V#CfGTC{`}vJ?Op!us1KI`Jxv^eY%HumJG+1E z`WLo~s~YJ4P~(5ZcG2*11Oe4RE)H(aW*_rmLHQrz58wUo1^t8gp$)&Xv-QWMnAl1> zn7P@3>|Ny~g(yC*u$Wt$^KAwCE3{6q$I?}q}h2n*tuCHcsZqbIr;uWD`)TGYGQ8&`j2eu z583~wmH6M%@=G{_Ok5qDH5?pl|Fa5ItQ=e&T&x@%$s{Dm=(Mfv%^f^k=>M6a|1ww- z_R3t+{kQ+uJBqJ~-M29X=p=0m}+WTQn#f%?XF&7AFN?Z%m zCr-==xuVKA8>Al5lu}8DKn7uIoc%VJaU4^9=BmrWP`wft0rhaMe9w2#R&}!R%$I&I zw0Ylhe{tWr>GEyTW!c9-*rs}l0$?4(_6y(ad>_m2oV&ep_?zf^qa(JBOt7>bs!_ z5dN3<3R{1$t%z>(1;gsQ)7ntIL$*&bSvCh!S!8FMQdnLzCQXJe(zWJ zd$dw{xeaGrvuc%?KIekv{(6tkc_}^qb)8Q`V|R?72fdn-1+E)Bvw1?R60GRo=fN+e zbTrMNAVcw={LV9Y zdnvwJ2i^(YKlx>>^ zc3t&?x9Mk9g)!0d4h)41UiEEg`|&-aP7!Y&KWW@6<4R4up6=9(fPK&W>A=3QQc=0{ zlPT;%6o?yvpna!aw`!=fMKp{REF}=;NDSu z%9&Yzo&*`3ai@RVzHXc8q=#|*`{Um2Qo0P-!S_BrgRS-t^-EVhv2)kko`u00nEH~$ zL*Tyo)4d7k`DF0Q`xVjd9K&~E6P^=A*PHtCjXnn|oOnl1M74PexVqVy2J3(N!!sUA zIh~mK?DZviT7mg=-3RD=mX`vUnT8+2y75p7dJf(Tz3|_$X=OX_LcZhzJs*`& zyC*J%+NEuY|Aw{vG(E+D=~9~7wG?qU(&4GL@xGm@A5<)}xsZF4 zyVKQ^)V}$V3Ja|48Vu zOsG8lEHZ?(AGM}_6~9Z>sqwxsm1}|}gu1#%0Db|NsWLgoz1j$VKPZ>Pgp9(wv6zZxZd`kFH=ak1deJk`VHU=udLH|i6w z>evS&+#MZ#cQVpw#I7kkJ-b#`#_Hn8X;uH3hf#&Y&vxOsk#S&N*b+piT=phsYfAO8X-b$H07sR*s`>{Dv zmQ@#@y#zsAw*Ue72rVc5nolsvSY2ZzIF-}@(Eb6i=YXC|=(m{h_^726mYczm!V$MQ&agy&x&}{SP7=&^qu$DPysDR3*zu zp$%?*Q6f%zN zY;qx@`R2#?UO>&3*VtP){40P^2c zq+Y@Z`08uMDaX$C@ZIEP_LeC07M`4=ZI7m)HeK}ebepS+Wb5NGY9tFxatVlCDMXkB z(~ZXwCZek;d-g8a3?C*bR%E z<7|_C*BtB72%Y(WsFWhhMA;Olf`&5|oN;^;uZE-%L+`980l0`;O1crhll?EUA5eVC zb9m(6?i~*7NJp*w*e9T|TG+qW6#qF|^El$~c`p)NbMY%F*0Vu)*H+)^+Ka_2dNW!e z^IA!LLt#OkNreu4Ij*!g__I5R29ap>S#yf#HVZ3+f(1r->bCE~~x_kQd?9g5XM zwBc+Tc%?}IC?xfG*ohGo8)T@h6*|$uaX}t!^)-j~pFu0nU+%woyFVV-fu7^rV>fN! zp!RV__~S+<$U_M?$50@mt#PwT?W*Llf`)y`ShomG#e> zgPHC$&Lq&DFoAUM*W{rajicY`S@sT|c`9e{vl=eg9-l0UYKc|;ACmX35GwU8O{3yAxen> zX1wLfMJrLzWF*ap^VpOsTopY3co{8to_Ak5DNcH6t4KguzDzk5qh^?%ppuYE2K+x;;LJ&_W*Q{Q#4nPu+r-3KeQ z3{o=4xQEqc?ESp$b~Bg_;I7|Wtl!TCX-q3#)&WCZ{Hjql-I=q_gsk#%M$K>l+~5=Gy_v>?0^I*y;KZ}z?<#+`p$?oe z`}*aeWAX@V>~7B5UUY^*x3%8!Py-#0;TBGR_x-oKB>9`SMLs0u#yPp*dcl zDhFN@ZH6LFs+vpy(2LnNtm<7dy-l|8^7c*u@jYdCwHrDe*RB~tQhi~+vWeG-8t{dj zd8gFp_b)d+_uw9|^t^fpt`82!qs?K(eRAGdsHB*3)4}HF36Gko5Dv+3d?3^2H<@K& z@I<)(erzS^d~V~ys;s#unbb9>NJsC}9`GwxT2BTX)|OoY0Gg);VI-Rov{NtY+9m2{ z)7&s4S$aP;G&Xvt4tgf;04t+0IDW(qR9hhe4cLCKj34k12yE2ZHRKnb%4m66KuEKE&=$&xDX!4FbOLVB)L-*HX30ihg4LTngfsA5g+m zhMm?56Q0QsAozNkSn*lzvtPvsdxGuOkOHM*FtNZJ}K|Z**&~B*M1&tt>ER?*CDp@zxW5M z$w|-m`P*M#-j(sKJ!`!HJfk-)OGTU4mK*O7$0D3JkF)1ezq63GhGigajO`b>2b&%@ zx?M`YJ7NoX^O{e)Tm=1ekev*4u|f}nAmcm~1jXmz)e=CBUC)2da?O!Kp2E-XR);qd z6`>2TIedD6H}YVIoDJvZf?~Oyx8Br4t3{apyt-nT6`DxWFVu<-RAu;{9>cKb(rcRol$7oNR?-9sX5DB7@`F=!0Qok!B!C>^yys2Dnd{)_%<#J zf=^qk6jneZv*}S~53!d(%iheOJttTX10eG_CxusYA^>K3@2s>X_21~?Gjfl0`Ycf5 zQsP>Og*FA~V7z!Q=_qzdc~_XDKfRZ$n_JM?R1(G{bb;?$314`mTp%R0g^L_M%#=-f zXgt0T{@wFfm38LNPh$TflES_y-~fwV6;R6nfaL3ChQanqE6~SjpLfG!NXU*$Ghpps zCI}Aa{wboh@oeDX1Rmm*5ZmIe^`$ORF1+3}>+|0B!dO3TA42mpUiNFYC0%a0Lmw?m zxW&~n{2?8cylciPNM<9Kr|ry|d|^(CGh7C*@i64F1wrPVEsjGX@CTg;VBPK2eas4A zQ9-r>#lcGVZcqAX^sIdy$0O1fLMS-DJoi#M%5HsU(MsFva~Zn}20gzDt;6LZ3i$=s zSDlCYgXo=bK)y)wChe7auHUMCEp`j9Q~gVAS5n@?Cnov~KLK@gfcWXv*9*iDHMGo& zr{Zd57iqh-g2LTGFz%n-+tJxG{PZ)I*;;iGLRy-j@=Ra>Tq$(?Ux;15=dZ1g(^zeg z7p+7F-YPCP!~_~7JoC{vn_7_W5BRH-yt554^@P5)MkTc-xqf@;c~ucS)Fa)OkidNC z@>xUhHwb&EKo==^;S0GpbV@wv(FOq@)$PZ2|CqxZ=Yc^7Q_!Mgw$9)RW@4;9fq_60tc5L zw>JE0i1J6`^#vbJ1;XtI0YwvJ-9Z)in;skefJ1Ib04a*-*e*Dh&$!S`!&0LS8aEOY>34H4B|egBbT-H%)A^WeR62 zgr^StJ>xiu5-rBld@L~l4aIZhz&4RjfR zyZ9<-k`Q}z{e3OmVc5r=_gin<^)pi4zlS6d$& z&DSN0aLO6*>0_Y{>ATjlUx_W4#QUWi8%KyaG9>oe({y;$>|whW<1-THYUdJE$L4(s zoKd&JBM;`=#0lTyo@d)GH+V$LtN(JrBM}?rxhh1J@i2UkfJR29mxJ!RW*vk7&^G2o zxK62}E(ZC5uS>U2x#yBbZx@S4qqJ29f_>g006}M%5}z<2vvf@!RT8{!=k@5rG?L>5 zm`5_(LfOm9V_bFU=7+pgltid0(m5~Q{XNJWa>4BWbMF^QY}JQq{$f+)g7-Y5*FauN zp@IYV%X<3i7die819B*49_vWxfe{xQBRnU4$E-*505_rR#L#h(d?kr=2?i&HQ;|UY zd`yuxdgen82ngOe^Z>K794__~wh2!dkUpI<16W)A} z9hPRxJ?1Yk7fSsi zZ_lQ$S$=zhJ}snR37hnEp7e%5Kjb$J9|Q=z00- zMWUjfLiXt->9fN4+joDoA&g%&)>=>^5Ka4x!qeVoG{@baZG4RgP)un1m{8#K`{_Ty z_M!p{o+oK~QoGWrymPZ?SWA;}Mym#Wx0ysq*IeHi1k@kz+Z?A@Rz1?s8120U(d02i z2+%rK{v0EC_F0B+kd&6rTQS`|r1*br2x1%V@~k4&rn)C5zt=2~7$EoN)O|XhPbL`8sTDZHJ?d=VIfJI&WRg*AO9fJoz_3)=$vi?k_2z#ef9^^8ZwUh(zv#3or z7N`p2m{F>`_paSeZ~8rC6vc`Hq7HjukMae7{SE4X5Y{Jzug10d{^CM!?5=cnE3$)h z2bdiRINhGfABvD&`zgGI@H2koGC<3iPvylBDxrTHb3>!(PC4bGYuLs8=j^Vpe2iYo z?c(dA`$BLj#(~X%m$ow*Sw8x5Qw~2QIQu<@VjJS(kT&w+n`#q-8||FPUrF(mn)2UG zLZyN(*s{B_x0sinaI?7l1hBn)biE`~Mf*~f-+pL&YN5$DWsaj3|1m|cLJCu^U}U^P zRf-zxdOvGTd`FhM8@2xt-K1A~#v(6?7FVugFBtVs*U8>JiL6Kv&07s;{0K;#+ zo*nVZfHKEJ7j`(G5sgBm6gBTGcoLU?aeNV%hMq@-cFLlu87L#Y0;}u-dFNLn^d`F8 z4L;rXY7IKL|GjG;zY5>FbD^1PKlWYtQ_bel>-~7>&>)OsHE#FD(^%zxZ5cY-U>ljh!(2MO{i>++|GTwxdq>J8b40fVjhDc0_;QTFYe7NA1<|(}`Re69F<+!HZlm~hlbp0&8 zgK9()1FE_q_bvZaMF}>;v#e5}um)OU<@m!7NYVu|m<9PFY0_~}+Li?ILhGg>+l=LCM z1G|@NdE152o~6-edj#BH}Tj*LF-D(tY;QciH5Q9qRt}XGXuMGBHMe1cm zcP98U%!;-TeUH8^L@5+vB|0^VZ;mvJO%coHrP;M}qbqHuA@|KP@O}eqmPaBRomMBN zgz8zVONVz*;-Pt1v;t%$;%(fY7-h-43S#HD_1&**?h;IJ1;g5V z4k^!UF?YdxGk8rY#jz5*owwbK(~Nt0b4s&n8Y~U2nTqZrb_es6>_7ZOtPy|#zEkT0 za1>K!>bRdpReFg8c8t1QxVPZcVaRY5SL9Wl5$n&rV6Bzpu$!Q0U)BRI=Qa_fss^+)BC9@spVHOptNtWgNz-H_%MM;7TTW=K zKKvG9?(`rqNX>?w8DP=&^B9^>u-96t34;4}b#X9$)5<+CoCqdfzyF?lxzFFqHvM&( zLap;0@HW0f@29Rkj=Yqo2RxQb0q zPL{-(o3oEuRo0eBr{6~sEpTg@@LzksR3p2fybcNewM+^@urb>1+g4_>S76-i-yXeXV znD^u9fkc>=n?}AH>N{RO4)hCHU(Py_>rzc@zn(z4@rk zF14cTRshMCTYwqs&*-He>>gTRyc&#r9FcY*Q@GW8!b|uE{5-?+se-~yg-npcZ}MR0 zPdRlZo!q0UuU@Q{;q!bQfs^v<9NZo&6NCEq8C^+d#dXS81g{ALuW8rtdK@jt7WjSj z&w))5mgz#4Xp1w@X#IfJX%@$-htyGZ7DEjtKB}I~-cFi!1d59lmVEx|;7mRc|vR`hw@C(VUsz0&Vb5*reB-#tWZj zCA6XuX4cGe+SNn&*r%zcdlb!LeYAL(^8Q}k_@P)p&uHW)xnpk%#wUYc1L+ie462CV zpFMs9iL+ijOXo6wUR^l^8d0Ue(foi-*nZ<<6Jzv~Q;0FQM6)fs3FJk)H-MF8%O1+J z2@xI03ObIhzH5$>ok%7w4N39!a|-~b5JN`kogC1b6Y%D}^dI44_PW?Rsi7glw94-V zf~YzOAsuN+dY1et_iG&{%J~=1)S?bsJD7NtOV(MUg$QTs<`|7sn=j-_FLhW+Yqc7k z)L|J#Y86rmH$5q2%3XpZ^>>HUU@#@r(Dh5oYH|+@nL1&r*1f~P%P`Bzm<#$^FG!BT^1R7|N#7h4Vm|yJObu7wCrz(- zAFaAk4k7xPN|f<>8j1CcIiqfx+_NvnfGx{eCP>a@=!gN?PW1t}@~W}?^TI#}Rp;^P zg6ZPT{PB6Vl1r>T^!lxlZfVGs5HA&yg=-@{+o%DD7K;fvNxFuqf^5;@G?*_pyA9J2 z!6(iHd_m{mlev@y95FX0d57e;&uzvQ(=8QyTs*O162tC}-5H}sWi_{dNpMVwdDwN} zT}o@^$O~>h7ELj#PHEsKM* z$$A+4b@Vv$2Y~(zb?)Z=`_Bx#S%!5B_AL~Y9Kj_q7fx{`mGyH?N_?GEk;Ry2gAL*0 zH(yNFy%Zu!k%EecSIMX81oG)o^j0&=T($^8URZDlw$=s{U zfP8wcVQpI=5H5=bVMZZIq!gM04wMo#sZG)!R`LhA_+ zKE7fE%6I-2V1HHG;D_IbhseJo zFc;}N-g#aq9B?IYjHS2wj32V96E-)A`2G6_!@JSqg*tlw<7)Vp%IpRql9>@k(i zj(|p@EjHb|2GT|-UP3yaT0X}iW}l(~skhhTb6poRN+e5A%sPzL2uh8 z2>NhJRF@$J@1XIkN=tqtrV+M?3{>aTqAT(Y0j|7zntXf#{1;kLImo9!%eQU)+m{?y zMtqF#Jnh1Aht^A-j?Nw$@#%Bjw*}wF6WkchRw=#{!dumlmG02tEY!#)boO` z65#WNN&q>q0@ILe*R1N{uOToGwQwduA$_x{)Bg>kS-MSQ8otMhA({9rKUL&M7~7E> zNBym|vIyB0RNC|Bk&9S8xn_enS|8$=`KHSq)bW<#Dh z?ZB77rAV}W;j71{kj#+Z(^q=WpDD%@TF!42VoDd=976z;sV-G<>IQ$f>R>D0dO*c_ z!Fb83m zDa0TPCakqd_|{bS&fe#ERQhPo4o+l>i0-||&BbG7za4p-pmu=-FsM1Z*`S}nE4@Ri z`7EguQmpr}u_vD4{mu6Anb2ClH*jX54(Slz?d`3z7y*>itKGqwi#FhgC6;yTZKhGh zb+^iCy5~%uS%j*KdkS{ZIgL+u6&NV0Yt&E#uN4GQT7J3ORb6gSVfOr;7H%t6L+t3V zD=Y!nnii3xgKw|Kny60>nJyf`3>n^mWY69#^-5Qcr;T#6+i6A1nI_(m79|~r4Wpfr zdhkZP9KBv`J66y2Hg{Y>=oUziq%Z4N_LEsQG&FoJ+5M)3SQ*W7o#Zw~Pny02+ zSI{{9Iez{sc~tcr;#M=qP_;BP4o{|gD)xN|4B9$9ILLFDB9TP6jdX1-!D1^yb*}++ zaU>TQgo`T95~PH78q6uPtfHm7_OvwG&6xBnfD{l_OR&QyV3>&Y*%4oo_I%ow;BSOm z4!dMzPc1kTE4b7R@zHV{LW*MPotzr4rcQZvhQ;-vl5Ltb6#uCAm-6XLR*?oCO^_*d zPilWu;Tl8}_nlJjeg=M-j-p4Tw5f}2!b0J1x1YvrfXx0q&NL^6sidK&dfk8BRS?xn z#%jUDQJLvRdx(S$!*pjkOChlLTk&DNReRd;Aw5$7^7Zghq13(p9C4c#+c8UDU_cgk z7OL7tzv`sp)@|HotufTkqTgO}-ED%;=L7J5O6)(@iRchY2hwr7{iH>Ijx1qPC&nmJ zbs7G6AfnebYA-<58^>uS4J_@dhIr$H3j{4-UA>SSh9e5V-#BIn2HgP0ZD<#zl(d>J zx!QU2MTx?H%0jN~f{NYEV)L=mXHv;}WE}Hf>hd8D(Pfcgbau?`6N z!%Xr+y}04r>)3i@0c!Hu*SY9+aKkv+TK1C1B%}8|owh*6`>X1`3-GneK~T`JcJJD6 zJ!f9ju-+N6?~|-?^YLC$nMe_`#YD(txkKe(vFai;3_FL9)M=?LIRByWfz}uY{xQfm zOO{>A;n%oUq5Sogxhvi6JjIGOf@c= zUW$C893#bdjoKaH}ta-<v@;#PYhjd4;Yxalt(TH zt#!fd0&UDTOa@G~5#&9wMxpug%bsNqO{ta5X&m*JWx7a%x>H;H1$`9se%cPu=v zAaF#ylmxLhg2b^$eAZi2doHsm4>Tys9t5?7*P1wey>8aA!fv|)+>}wic-X@KdQ&Zc zyNIm5q+ii1kszLN1o ziX{81uo*owvA`)>ZjF}I*RXTD%kw|ZOUs{ zaya_CR|g{r?FRgK-qC7?%XioUTTgy;N&EW(^$5|d(5OQ>TvueMRt1>j(vJ?Lv_8n# z_=WnpmeT6b)B=+0KT7Fw_u^Zj$nxerR*<)pTmXWd*}jmZdwk0wiC?bGy1!t#4}e_s|~B;#fexMzCruC~n!Pt$~n{NV*_JelBjnm7S4XDBi6BNyGO(DHKTd9JGA z&}1D+Ds&{P71I@`^0GkaLt!MLY3nP8zT1>`#qTG-`%cDC{p_Wo-@0e6*%69X;Q_w- zyr;NwmP%&w@o+fEe(D00HZv&6w+e^jRAy4GY>$y93YwBNRFjcj zXaz(QXyYRTHiy%3AL$9S)D~gY9|o)4c>5B$Q-KUot~A%AkHrz$VEeWUKF;2+UY}5( zV0W`#>nkN*8SwuLuP5d)-q@aN9SF{Cre+W zgX$b~Oxngxnb{Zn5?Sb?OZRkGAtFd4<}AX9_5C~Bj=(FE48T%$gk$|0DaGH@6|Ws! zfU#v1rJZ_a0P<1izriRYgm_J#&lTSb%B>u5ip}AbrqM)gOO{3AI*yD3!XDWpsE!Ma z9+^bc)%+wv;&eXwViuNuF&dn#5no^^@o}{+Rs$n^qC3;5+E=y{`IXAvU`N7`_F<*K%nsdI zjQ*I+=f;DdtKsf5c?ZD6FM?6o$F>oP^nWmks4?Ksur62`Mb=LY*Ep<)!3~9lyIXAC zJ>zXv-V(L-an!WCuGMZMrZt?r# z!}i3V3|)o>%UI(G(c~K(h86n}nWTj|OK}|)Zx+}g`9JlxR@SOB=K7%V3tP4i_Knyp z;T#eiwSk@suKq;Zg75yMbGQ+GYMkC5r7D)L)bZ)*zs86H*f`Gy%1R~tIMU4W_)S}j zkT^iLs`+qCHK8jGs*H70N?oJnlhdN<@QoU(NvA4}Lo`0EekX-8C7 z6T)HpuaX>NCwMXE?I$6S=U|?v%~Om z4=xzK(QnHpXH*pRX=YGdK44$KXn6db5LRIdSjjihIAKibsee-alJ2EPnSeVOD2dt? zyD1HyPaf=bDmcnafu?6JtAz8cWRlS>2EmR5WkpFAq(`sSs6(U9Kgc*IPUh+v%e{U2 z_bp)XsYJAlhx`^>%nT20elfptHIB>wO0A3jQPSEYl!e8dkw)02q$+3k0;@PERnrXdN$>OlTz zU&zKJ!R!uEwH{sW1A z5=g6p(A+CM{zY^M%6*o zr0BL&_X#hQYQ^bRz?G&3EMy?;MYA^6^uE3~wK{r`OR4TlrkY5oESGPqxY)(P!{ByR%{%Js85E4h{o{(2|qWubIs_FHk>MM^w>|RL+ySzSa4YoTosfUWkES(p zyfSC(TZ@vX`!(mAOOEALeJ9{w=6ei8#A1;N)0U!-upzqTqg~1>HOAYy&1ORQlJYXr zPwc2tg>!U_!Zp&#U_ymnvCbbW1cCb^iO3X!a*Kck$pO7mmM9`h`R$44)j6p(m~uoZ zM1cSIM?QXMONNMZKpgOe@r3tL+7pyn)0g-%ET^mNZE1(#EyhpH?@+G_S{{I zebF)(e|L3FBD{Z6IP^`R^sgz{g*X44i~~qxV4j^&`wj6=sZNt1Uc_e z9#)JDpO?((tjg2x1s}-{bM7&Sp+Y5`@?+)MxMdnQ28*?D zA>O~r_pM>{;N9q)4gEq*TCY2@-+axmd(>xiT>Q_kUUAii}(hRy+IflU0s6*-z*FQ7qXjMt@GNNYo5lr)(dp zt}a?q&lLD5pqFY9#M!fD$X(#!7Yid?<35prjR5AH2jIw1U{r!F1spTgSBfdA#LNZ$ z`{H>zh;a*+)>^X7&&`|@`}`rc5mn`AJ+Nh$lr9WTsbdOYHr`HIqrDh~VKLWLnljv^njM--HE=kH}JHK8scpS|jND_`ZABkUyBL%kwWW zdr8g@5Pl?p;h3?xzK)mlNq8Q&(pctW`-i5Emg{dL#L#~QMB?Y_jFCYd46#H3UI}4) zNzUT^piB&rE17UeU{ijZNdp%A4DWqW;Z0=spD?r!Gmd=K5bOf$kGLTp*b;YDe-t#- zfw{ZK;159$yNC;wMj|G!ObVnXhEliQIln#~)K@Fhuf8)#+*G`BXm;Ai!FoA14*pbUwIzCip~V1abTWT_ zY!`E_X=nTLStsOhcz8V#{{AY#MP=-40Xz7FDa);VjO;>+F&&0b0Et_5c;k>J1f-fPA;`xhL(G5Fv)*h`{u(xzGrOQvzYtr{fuw z9E$C4!XIV3{g;@25&R^oGK}lGN!nrJbo`-BbI8(|ivdfZ%k-ed38Eh(eFk&O#%nkO4| zVn!`t1182_zfGxO53W5m9F*L^CaRl?d&M7=d_71Z-62v3#spKE_~AT66Th_2nDc8}6IddPwUX3Nx;>!2J|LrpfQ%1hjL^6yOMtP>CQ;Gn*1T zs|Fc1`EdmJE(kk|cP+h|)MF8Zj$-_cJVwkeBrz|dL)h!qfL3II`Jo$OkGw%cb`{;| zxvlc$u^w{FP$kcvSP%KTXc7rmt@LsQ8ozu#B7?O1o?6A!p2?Z)S_4)r zTdcpk+Y`#ZB^7jhR@UgrKTgEkxwwE{wgf)b{)NPTMAuHAIWSZ8YP&{2qK-UJUl?U| z1uxcs=rS6MC3XRt4!trj$_NIeA1{!U#Jp6k>j-5VqA^{pnTe@H+*VQxF7f$`X0p;) zJ$Ok0H6aGZBsEY2N5G%tzcqT&<>8l_j4;(?K2cLnqv&zh_4aZ)?5JU-p%WSu1Ry zpdDeO{}%vLK&-#tTa6 z5i&x1xwM@FoDh%+IkFu=&x`GMpIx@URzC24frms=C~& z=Z7%_G<%x791_Ys$o0t~5YjDqj~oU};qwwZQ*M`oavX*dOl#R@EtCMimA0`MeNDtG zZXzo)%qBpxaBoVVP@err`TK&zr!=&|P%G}YPnYYlu!oAPmm^fjW}~k6Zoa6*<}|3W zwouXLkQwbh9Pi`}I8CRZa}Ib810k40UdRXa>kI4oZP+`zGP0n zNrB*Qcu>0J3!1>Hrz9{^&M^E1pHu$4t!&Q~D2)YEr@8>3Hihk8v$2b(Mdha5*C?kgC+q zQFsGz%XZu<1s72fT?4c519J^28wNnf5M@`?u)ZrvTG}v(uo&~6>PN|g`;;Vqy(h3K zi3M>K3X_eK3sk*Ri3s8j+QKEoxvt3y5Dur;8lI)MGm(7;z zl7;|OJb#S_AwYc=*_?9#8(X5dty2?QlUbJ?DEes4PXfu^Y0}2raMmyYE(-%x>u(zR zqA3VdqfASZ?wC4hV^*{0vxR#w0;ttj-fJ{1g8a&`6!gTghm2IK*KH#dv74PzwI-LM zI6#22yFcutsV@tk6y+%Ak6r5AX5@oRdDKxreo1-y;_|t-l;^*;et(jgy{j>hD<0ZB zA*Q9ou5nGlkto+QN&8CajHjYKDR#Xkaud;xbLvrc5GwL}90bDJbk9@>jwv_Pv01Na zi+E2Wa4^+$@L}rH_?oi)=c%gP7{!Bbck99L@GSPFGo1WBP03b=w90GUYh783E+aJz zxf!+&JIdZfrC&%R1Y#6BwseC`Te5T7!WyVG4`TP+O|Hv1SQ}s^ss3q*UL0=71Fk28 zHFpAj-v&*MIuL*zW9ns*r@&fgE{RDpWp}bwqwVdS+A&_cFljRa$PqMCrFQ@+@7d9v z>wG1r!O*hULs(Xs>#ll}830MxywU2ad7`LD4c3Np;tQGOEU<(ha)Dzl_+|DsSx4gY z=$HgXpIx5)f7&J_F3hN{d~>3v8Pg3hpM#p^=!dbAWKEA`u1IdI0qY?-*PAJ8%Ph#0 zN>&}+YDRb99Igp^g8an;08B9ITg&$4ypd5vPVWLF9fmbGw_yys%3ptv z=PChpLmLv|um(Nracbo2FaUNAteyv477l8EH?deb&!Q%rVU_7FU0b$0dA_ao>On>! zE#EM;={NLy)Cx z&lMXwcfj(3aS~41rpeHTl;2L17I=L7s$Hwrp}t}2WLjsdFtDBMf!*&r%iC{BwdzDC zcLL~;6=xN1sXD!&{1fDR>8?03)XT^0X| zs&S$cM!+Kj`$m!0?ILMt5T$nRNs`?xHCd6p8Zz9e!P=!ms=Qfr?ItPD1OotS^0YAi zmV|a7%H#;Ly~oGNG$>FOUUTxpKhI(iCbPzu4s(9+TB=~th+u7u!xUzcC4XRzZ|oTn zGggtJOe3D`q7z;yRT$GCS-qrX+^<11Ek+YNYM$*m(N>>5DY(T!Iku9o9Pj9)Qto$*H^`Nl0WM3f6K+O_l>ZO0%K2-aEwvmn$)v96WXvd<4_GpM{~paBHkp za#ZLgE+|2+d5W#I48P%uPwD!+^3V5|?b8hPt#Hs~fBNodqeqLIywCu}ItjW&*5QMI zO=OGji4CiOSmi;6U*^O;T`$S7l1C&Rv)QxfH$TJqEY$sAs3RnDCE)%VR!hroS6WQZ za+{p@kRo82tg(^c`fBy?=r90w8Uo3mIHo=wqRk@_yrq|1jYd7*9NLTDz)De3QaypuB@@5E#(ox8E<|co|rq1{l zzp-o@nf(fRfQ$5_%ERo2X|i?F47vl`iy&eNv}nHMf-nT452p(7{+R$x2*6OHaaf-= zP@Q~s&T0)>qTLN|ELP-XkVkUaX)=>l*%OIl(zUNaK7we#=2RUl-!W{4I?NF(cMpkK zpgy7oLlT%&%GQ59z^5f;fhb%jhb=oWuGBloG5)re9f%A-9)q;89 z#2^O?fDW)ET}iUVmD#QIT<`GogQ5n>7}PpjN5UXliCM3L~5 zV5!n13byuN$Neo(;`~NLDzuU&u}SGP%jz=RhXGJg{>Gy+chx}$v2m4?rvBZEcW7a& z<77Z!jB8Pg*42WR{1)y6G)Z`pvq0o3PSOKkCpod$lgruebT{M@WLeBJS2;~&v#PlO z6pK|O5ngZ_o||LI#I>S@B4_f95;G$dVK269TYecQwhK7D%NHZfL+ER{<3ABvaq;e(5RXC>4 z0VTicN7=l9H2pL8Y{*F)aoe0*<5!Sbd6e9mbZKGPbS9FCu!)07Zlj&`u!M!TWf>rrnL{m|3frEgBwKG?#L72e3Sm2f1c zTvu;3}RdfhO%|GQzR@RCb;ExP4epUjO>GPBNCh0J#u5#PVNEE<(LK4A#v<` z^N}Zj{z_Ggu8=CNZKwI%lD!Kcg)XPDrLcp$|1kR`QXX*?c=D2)NV;T@I~?+A4q!&Q zK*|GlJ^Rh$i22z~S&A@N4COVsM=)6}k|;?UT<*0H|hV5sV)p{_L|Hxyo>E!{!mJia$G{ z%@piEHBbZnebW)qOM+~+dz5?$RH@$RrG6d;fCKiQIZ(`^$XIeZ zX^r1!kc$%KV9hQ6PA;0E1rj+HO>*Mhb3zO?TDUO{D1svkWKI?6m?W%4jzA}M;yT}P zIqpogmbIGnhp#5*T(WZ4nNVK5%gj%1A?pCe63gQ#m$2Vq8hv|te&C7!lQsMu^LazS z$~?TV*1$QQr?m~Eu#Qhs=0QZPGo}`RtTa_#lKJ>~MM8#?9B5;`V9HZ6W2!ZpXT`b& z_LagXVT@)q|HI_R6CCuW@|o`~Po8@+khZ2WqQU@P)fYoP!hQs`n73i^R)$lX7{*0o zpuG4hZ3hg%!PUOlr;#Hb3ZpLr+rL|tvxP!PqYJY!1!zY{QY%4)WDu3)d97qlf_pY58S-wc0PoWPSnks_HRLvVme?k>;lPc00c{LvN<~D^%fsm!- zn-!{5%SkA=tBb7Xt^4m(6p%e6$WpguVR~zyyf&g1)2P|U@L+GRyWi2vB$EK;Q@+7K zlAC1`To^?Xury`zj2@9+G}W8{d_#GDpbq|uG8dT6!P;0VLNpeHq7m?Pgj=L5?Syy({WzpEv#Z=NkI%!o86jh$w~VGB;pbG4oGfW zKyWyXI7{@##ZNOt36)Q@^+vFE6|oqOzFx+-t#I|bJvP8u`;tTTi(sBxSj_;pI?R#C zRAr?YH7TNWe5-e^ya6cC(`ZS3MA09n#D=#t@(SX|xUBb?1ECD;V= zTF)Za2>*{yzN~ETSLVPMmcPF)pntcA07N@k^TU+pV`QP3ytIMZ4X}&|kgUPvqdaDu6Ekdcp;K0e9zABAAeM8Use8mvkCX10?WJD zwc~YCkAdL#UZ_<)z*AbPB+ggr2)r6Nh6Y)$T2-o6o8ItqQr2B&vWe&1U=3ep;h2fQ z61MU`s6^O}bcmfpu4lg@!_VRelJONOf^K~nZY}lWwkRQPij>;da~J?k6o3i2Gz%0l z-x;?(Nv~sCI_NnHgnL*}pQ%GN*fMq_ygYOfNQTiu`vJnCAVF50{Dw4@`gT)?&le~! zRb)+HaEe(}lgL`;tPe&fmk9@1b{f=xh!2}md@LjhmU!vZ0&UYgKejv9XzfY@p?P!p z=SAh|=amJM`@XbTa6w4tucOBs=wy2nea>%(`Jrc@%@qkC3BhErtTULCWy^N&KK zNzys95Um#q3+4ZPkGnJgcxLm_(wu6_h~3=GbRl(UCX<+B!tH^OssxEB#f?zNYVfR& z+2#CE<#{Su^&sSECBO*`Sq+(>l7O`s?$cJv<A5NoRyg@t#Nyr1PGC|6T5omgik5^duMs!Gs`~y@8fqKvEFZ#thL7J`KDxz zFYeJ!&ct<<<_zt4>w|m+eS~5c4~v$|#^BAI!uuo^&m;I{iFA5TFas}8xVt`-ksBfm zmXWSJImoZ?I70u*8%Nbw?|9YKVkuKgQ(CkM6R4uA{?@fv@q414#!Auu3J z=q)ge)^(FNs9&$+z`)btR_`>u%zpqK4DQT=&5ip;3@)7)!z$wlj=#qUhtfIhvcmxI z*FxTe@mdO(gPRLjRBQ_**k%nLN3(;@R_j@7mI&g|KsI%-B-gNqQeqR*fy%;KoXu!S$46k8Wjk}8J>MJ#Key3PinC-)f3#a@Osd5OPXwn;VIW-Ly{l)c%-R?s&0hu3H<~9~Ms&=obeNRIOAa678 zoCJzZ`8UjOCr2%5Xualr?(z(DhZ%5kzqMtsXH-D*^XrBKkgb0`MMREACD_&S3I4ZC zT+7;sV&uJ-V52wPRIeg>Ic63^GUkDGu+z(y)kF)WPi)vw?Zb`P+T3fvtFD}o1q`daANrcQaU2&b0-;Ll=2cw?j zHA5p`Aitv?vcFEavdVCcbg{mLK6IOLG-TD5XtRc*7?GO0h8BY%XG7r)FOPs59$Don zy15x76X{`FuKEsMi~W!kDumc*N|rU&PKk;mNU7F4eHZ{|g#@~JxxF<13bP&L-IDT> zQs{0QLGGYu-t$`NUD^_Yh@1(9p#L!Uepuk%l)ibKC(FxOG$W9ntBEJ7cnOEBIlG

#Xq#g>2g=46qA=He0wY6W+^~7_6+3c^nvhmr37*(BIo?|~#)Diu zb1#cmmsj7Ojzm8e9cTD(0OvE~nIsp-n(PIb=8BV&C2*4zwLJ0KZwC1$nuKP34!5;8 z2{p)VRWK8ktQ^r$Jp4pz*JjH)Hwb>nN_*V8JC#@72d{?!+nE!x02(0}hj_>}tb=Hb z(D!JBej8p8?i4M!TONS@Za-9t=N=~=*822JIzi7BpacpMGzfK)&1oq}0w!{Z!c@W^ zDpf)og(&&C1)ht?)l~*-$6MDUdcm*U0RahF^S)FV0jp~-R~}cWUNvdXX8+jIM}kEY z%PTJ|{~Rc1-+b~+t*s|>KY3#xo837jNV&PDE0B|kooq9r5P`~8%4ODpE=i&*0sH3G zO_TWg#y!9p4>i4TG_N>ukc^b;W%1actX-A%mT9EZni~n zEUn4%t2smTe9!a#`F~4Y_wxG59+ELqtpTR3M%9U}PXIJ4tDy`R-R z59m<^vSf8kp7(9q0*CBY-fYRq%S=7q7tia;bLb(*ir-5Jn~&>b%J#1E#{18$1m}yI zjiTS~qnf*%HkdI95})(@+Q9D>CU=e5zmu;>D4$p!6Z2@roK(`lbwjt%i|nij=N>AH zTqUa6`1w2;<~4t+a&sVdct$pxdpX&j+sAc~edQgJVpXbEYT*XG4j2cDsBQs*v;jED zhZMF-7RQyH(88T}2fF_dz>e;GOHDuJBx_S0l5`HE@pv=U!m!L!FfsPI3<2a=h-C49 zh!__6_4{-CO}LbXDzlfg#@tH%!ajRWnK2Cd!U-^D&sA~VyGF2Ex27zl@$x1=Vc>T^6_j>Db$&hojJmM4G4W=*S5N0fY) zJA{pL>=zOvVBrv;tf2y|@Y`vYY$ zJl6|_EXGt0A=j-fc2*v0UbDNAyp*B!+Vb#RB_~riht#E-a;-%1YjUVYNroK|fG`w< z*O)hN!xwgEH5THe%kH3>j)`)fIj^8xMC2T>e5!C!Xr$B(h`N3tV&_%)sF6ydd?m1~ z`E|>13nqpEuv_s*fq$obO?774;48i_#@d!_`^i<&PXUrjwj*aE#w55T#;kGEEL(I2 zF?B0-$aJ2f9L&@d!&lHsg+a+OpXwC%b(zSbdT-LrTSz*g>ewbAf&6_fa3BwP=%0(? z%X0)pvf!J({o$Ut-Yme-&Njv zwqBFGswOK1N`ibz@harxH^p+Tem`=uJIZJlDtu^AtS{!8I5|u1L9Gmta6*y+oEmuv zSvyzcQxMQROB50zoGg>WRPh#|xcxsF1#vm{^L~DWy1i7 zR}Lxf5Dpc1fFvcSH7p1wPG&gH`J}JhYu9klO;Jqw2`p^q)#a;{1D<(3rQ{^dZkfRn ztzv{YD`67JUg+y7lafCbo^S^_&<90xU4Nd1k*+S|V1?|>PCXMtEZU8w%O+}WBq&kW zl-X~YlNOd`f8vjyk58c+D{sSmjdVBP!3Kn?GbMuW=Fk{O!hSzgD2n!_MPPAf9 zA3VTmNtkggaZ(heOEVln8|w%ds0F=5PHC-A#@3$M+yJ>hf`&WE6)4;iUud0^CNhE` z)pa~5erpvkgMgXWFMLti(@V>f-&5ZD)vRN;1V7m^bL!L$1%a2<3=R2`;ePT%5D)?@ zBUuj}fuiItRhB3lx6pOj)S6_slpAQLjkn{->6^-vugSu*-4sZ6glf)?d+H(`QESl- z<*(akdtI`%(ho`+NzN77sk4>N#3wH5Rys5z-(uwRSu8rKCbMr5)dno*NVC459K!`N zTvAo$+gw8j=At6AdtsXGsKFUv>!F91{WJ`K-C=+r2E}Snk#{6n)JkM)<m(ekt!lFpCfplS3(b`0rN(T`R8h=}eMKksyTuco$Z`ajFEYio zGCC#MoiK}DS;8+O;hoForIg^agK1dCBS%?5m`xdNh)t?DMo~QG(Im0S~^w$l|5 zvTg}{f(M>e{`vN@`#-R8H`H2Q!wLtOe#o8Pd#;Fb#LC$z&-9hP+;RBp>%-k@kBkwR~kp4SVb6?(4L z`r9|}I0A5|On}aHhEt*e?1b&murN%_NKx=sOgo-eur_2Nuh|L7+WncAmAEin5e@QT zC)bJbta4wTnZhL9q(vmYZGvh`gd$(iBx2dVl-4vy$k0OVZUL6n1)lmPiu>2(sHp>F ze*vD%;qp7EAj|^UYh#1e%L~E1Su-D7_Vun~GFwi+kSN8}$RZR%HnVtAO5Nj=n9mc5 zDbI!axRz;MvwFeH$E0GTYK!7zJJlsWuLC(B*!|vC9(}f~bJXy~WVHw9R-Q<P21o-r&40rFz`E06U|r;jiz#565GpW84C%Qm;W7c!*Esf%?4yn>$g@*M zj8%_Z4wIIf3_}Az#N}s{jK{7CsLy2w>UMz#$&ht^yu6;2y3&z`0T5nlK_^LTnOTqS zU*GQOU`M=#DA>AcB_mGBCikTdMyO4|!*%Nv%SP57J7Wf$OY$aGyl)U=UUN(i2eO-l zq;eP+dR_>>Vb+g6yeD2Ehp^bRGF@P1-JyxLg13ewig^O-YgSfnE%c%Ci998I4`jPF82%$!y>XM0hiKJPyD-nP#y z4M35@rkLp9ec#Xw+q&xV=)k3LVE6m@H9RD8<+w$dt3vm9jnZZa8v1C8;KiUdFp*pn z;$w}BbPC+vP#!rNpBi3u=v=EF9!uW~eV@S_k2%Ue$6e9@kLLisG2|`zh|DCBdwOoi zJ%vP|3CcUSWWFC%r8q|eOn@J$!9W1cLI7fKx8dSe_X@XU=GY-lm+Z7#1Uid$&xvkI zjQ0*F5l^tNBsduiUlcS`sS+7PGPJne{Dni*@4l)B_41wGPw1_Q%DO}z43<%)f zEi9rF0a-%-8pc>;*%TQA#1Rh?4kdq`vj|Hav~dwkTu85;H(p)-c~^OS2nYP#?R>S+ z_H{^J31(RC2c3*D)S8dyD96$xUr{hyW?lRkI>oEJ$mRN{6p*%W``tL!Us+y0u={-| zk7mHD0@2JR1Se#HO~N6?Lu)e=~e(cqwW zXvP}CWZtTE7t~+6l&h+Z2|E`}V8>G)G6zBtL3*+o2p1-KK|*X+ zdr5iv&hqzj%l3{*#dN(;PIf$aOnGZ2rQHqZ@{&$Y3wx&^@p|c{G?J34x=22w@b;TN zLz+XX_PS!T9@za}BOJL%NpPydX?wmceI#-~eR5J6GU8guNz6Td*(#y7XnJ>b79_#P zpG1sZ$r$QT{;+VpS1F?r^A$H()?AK}5qL7kH~~^lqIFRqNQxAOP~M=gjaF!GsCk>MS`q9Y_g1i5$TKZYr)o2OEEvnm>XlE024? zwb&rfJ0O-kHPM{?OB3 z&yr;#6FLwQ-J?f99g>w9-yBJD+Ntn5Ne>QpOT*TuA5|Xz=)owGA4QXx=-8R?k&PO0 zR7QAq^8{JuKPN;IoI|v|mqjD2W%cUZfS}`CsNkZqJKA!G7zEChvRkk3{){S1;Ha8t z1I_Yl1Rqk+L~RMFXxZD)wpb7dS0kzl5q|svT?*ps8c{TPVdSEaays=Siv*P;I!^t- zx&l881b}6bPcGoj8{()O0d&S0Jc5N~>M^eCtz>^6VVXcmw zlJ%h1t*vBr;An}#++AnSxf?u2-C&Ts@0DL0kKC-m1B zqjf7y5+GE?2V^(Fj17Unb(!a-&oG`5rUS>VUL5=;I$polnOW)9Ea@% zGVjS$ko@cN@2`~Cf4$t#UtJR$BYTuX;~6`=pyQKIF5CB)T|Xb1S3No58YQHsq|*wP zB%x`2olj$MV+Qclqc zx%E2m?q3Owrao|OHb5C?3O+VX%D^CRQb|7`lXc96hlCxIs%0jN7LgJNUeFjWHoPU` zapR2_Flc-nI-Ic3`=a$dC&`Z2TM6Jpo*RlqGtvvl#<>5a|No_eF{{G{#{Q}$mNjNjs zUh0QL)%51_?7Pd;XA4M}lw&QTIuHrD6D_$I(sRs=P+%o?g2yAF!$%rnN^$;z`Czi7 zSa1wey8rVU;Z^8Hcqnj7~ba#1c?;-@O|FcZ&cxR4l;-MXcm&!6LWr+OhW0<#;R4$nlE2 zJi+XBnNo>wM1BlEd1YD7L?kb}KN+PZuxfU#^6ZhLVTYKvsB-<6@}TOq^h?D%Bg(&r4ETdW{mJsuKPcP3D3704 zKK1Hy)E`hDzou-5zt1;8Pe>zh(=Qzq$_m~+5iqSQ@IA}l_be~JPkHl$pvpm=oA>Jn zL!f-_U<~}j<9X2GFa0m&L;rjE+25F^^kwC}Z%YedElvuWDugWykGrsMRTvP)_#Wa2!%{d5faqco*|LtslAEk$tlbTQ zH@QBVs z2pf@9Si@Xe(G;vGkBA)Bc++29U`S?g!IWV`H5XFH9#mveq99+OLU`byTl0gLm+!nK zHRAO(g??lVqz;AeLH9T{DPFSCm&aQOr_T0PKKq>V>mO9UU5thF?`-<#__;&G{^yGm z_!@7Lo;oMOxt`buU`39kZRf=9U_hNKJaW`?d>f%>q4aaAdW>ro3H!{n8V6+K-num~ zU-J{W`5DkgtkPnn9VYQk4%(@s2OSS@;8uFwqUWC00?qz{|8MI2#w_j$3N>v8b8DK4H;9x<$!{2$585 znN+4KJi1y`=Q@dua@jF3IZcw>;~^=;NZ0J@RWR{bwl2MjLOEFoD^g98JP1m&*C)Q{QnE(pgrFNo3!tAAGc!fV{-M0_4i3X$mas3=i_lYrTl?odEAr3miwYcw1x zft2DLqvRp+5H>Wo5vH`{?$}@62z}VM&Gof83rH5>-~BKE?2RUYAR%rW=g@V+V*k@cVt~55j%u~H3l@C z#F5v0qDWPZ)JSjxoS=yLCr0AVMX~i{_7uJg{m!BL*{phf@J?#~}bckx_mB zB!Jc|qae|{4~hp;MCrWk1z5dtejrOi5~+UTa2P--#XJ>DT{&sNCTt**N#e6WZcaX` zT#_6}G-{X1t;swqZVCw(X6boyzH{&ndn#nUk+#h-%bdh#ph|IMyb{gm2yqliQ4Xxh zaE1$EYd1>*u<+;Df+o;Zi}c`%i)SIGjbB6tPY#w%ugR7d9?3Yvlj9Wic>?{ zPdcnXDXgyPDmP0_{1vIKu_duhgiQEla3`^jMP;`frg%&01FaXZe`W1sL$2H$OOK>FgIXcR_&#Y`MlkUJ4tRd8N2!br-6qh9G zWFx@Oc22sVz~*`Lq#r-I7Z%A0WUn}vEE51j;kPQrJd?oS<12b0$9dmmqig2-FRYb}9hy;NC50Nb{}TxV>G+Od~i4JoG7 zV*GK%2bto;vihr4Gv4v(#43G5DOlJ*GCd@ScZ8)iIl9)L0WDV7;GS%r0oq@`XYSvJ zU;u!7=j6+nH4`fb&~_Em+>HG-=BZZ|C=^s-mpWZCM9K2ndxmVP5bJrcKH5czvi3QJ zaeZWGwL)b~d&eF$j9ILH2;_k5{YxrgsOnTfctJ2_R7?;!2|_KWb(5Jg+yaH|5mCSc z6S-O&Y`TU#g8uQ`;5e4WF`|;=J|4~4{iNg|P?w#F<;3RX#6?N6=FLjd=QhtV9z|$$ z8dPLOEUrx*z=knwh4+V3uG!WUg6)|sO66+hrOa;YACb~h0;@a4d21PUG%ZM63p+5< zMv$Y;719QkM-l9ZEr-HSdCE?fBGr=zz&R%1G#5h!rBm<{;2?^LTn3=EVt{@26n#XX z#Ct+WsZ!qIYy5D}EMb@K*ciC$W<9Sb7tK>#OP-XjK5DgCM@K%`Eo#Z1X@CS0!h7B2&-W1gfp!@VQ8 zEyARtSu&V-TUe^Da{mZ6=^&R`WcQoo^+Ud>?#%k;vylmiI8MqhE}h zrFAQ7&kDs9ciKl5VGpkKSN{~wdgMthsNubfLgPr8Q$iM`Qp+42*uo$FIYMf?rXI-- z3sa>XC2dq$k6}A+r>BU3;q!K_pbTeylePFU`93-UcWLy%);sw|92~28kqO2ugz9pc zI}|HVGI0~U)yJ{nF0xzbxix-0b^^BF+_}qP0Gw+9cw@3UOJtxUg;uuJA3?pSSN|s- zQu7>Yy?q3E52^m;B-!ucNg7b}lJ~1{8i^?7?+^yTG~rQUktJb?qoOMANsd>sl=hHe zsb$-?UbJjNE^=M*rf zPQH0X1BfUj#WDyAsZue`#>jgoAS-sl6UwmNe=^~((6*xh6&JT-BSOMr^iW_;LOJem zV(Lh~$Bl~N6|Rl8C`v7Gs--;m+Rn+(L?az)fzaJ)L6T4jiLnS}h}IcLh4*}*t=c6; zZF`-T!bBz@5;sW=GUO`#i3TFx~E_5FaY+%2h^pdR_upC z{geXOE^!a0EhJ<@mC{AOk(-s<$h6c?xP%tP zt5B6I-)j)y{>uPUkJ;TJ3A8lvAT-fM#J_`l!qq1G$vN|ie>=ks;i+pba|kGwCTd?Y zZ$`3iz^Axz1GaYv2jn7DN|u~;_zq33Ik(H_*0~Z)g~euZk*;CaK-*g zU={@PB#9&}j=-_wnboJzQ4YGuDNqKmhFF@DM|mF$p4gHSql{G&o+r)a)*P!LY5cmA zvyQe9SW@=H(rP!Stszw1ZtX~}s~HNNt+~Cby4`ZC3VSELV4MYswfERkHn=qe+U~yz z67nhybRZPuEDUD#Bh!k`5qbWL;=@oSBTH_8NG62!{NeQNaziOeqa%ScMpWrjy%;#O zL;pBoz0NMO_YVKxF#-T(EeqGAq8o#(WN+^}j1Uo)VADU7o^U-RV@q9pwFumAq(gwO zcs)%PvHmdXWFHyXLMK!~;silTHQ`dTm66k4)P@zLl>lE@YMuaIb~q`|*+ECUWcSiv ze&S&TmTbhX7iQ&W^bL~btmpX=xdnNW)C-DlLH3{_+w257O^K82ke`ijT%_&Vul4K3 zn+=5fYO{gq8LnVtc75({;oBurA6ajElB`XnA#mWBb8J00BE zO%8HH!Nd`f4-W4y2Ar~%SvzTA*LZNfSDCUHF{?oif%l!5 zDaZR;jWfbF8-w+*B#O=Ac<`9|B!?O@VyB8K30>sGaVJ=qPs93LX?g;k@eR>A@U3vh zoREvk0{~AxOCBX{GTq)*va0CjkwQjPUwDzRpCm{9HkG2viuuW!6iEVAh`dGO;R(;8 zLg4CXkcc%YIwpWbY}K6<`EcbjYk475Tu=dCQ#_3Qcb4vn+sQX$@ys*OI zYkRgiBu9I7&@ce%4lx+x4U~t4Jr}vkR7EC>d4r~80vk_@A_plVKqcQJ_Uct9P42OY zWyy&*NM}2{YtDDB#fNw)9b+|gU@l6@HXo@P%dqA=l+i^VbeJ{|bwN!;`(7?ArC{Uy zIVL}l0?&^eg_)JBqm`(e#i=}WWA<+X9+b_sBLw-UE|$1KQDGM|L6+pDgOlQahvUF! zyKkohAQp%i6hsVoB4gw&n+6#5Y636Wjv9u6mlvjCYyJq8-$+BO@zk=Q8k86U4EVpwSvSYVx<_zT~1GTPUqokB=_ks6Iz_gk-r4 z0Une+aF+(aO0|pZUb$RZK;6ARyuHEZ>6s`sVm3>kO%Og01~+6xO*e~SPg<*QtTIar zRbzykto5bcs^fi=mqDyr_Exi~y$S^Q3o1&mF*ykylM(FoWT*mZU74AX&!~3*3tH=j zibF^)QU(GmJ>3A7-^%KgU%O+xsr=EqJ0^D@FiNs9O#p@@PD0`wvt`IIEvQK|n%Kjth-EUI z?FT;_Ps*+#)%9y@D?G=xm*hc*`;{lmkbw0#HsY}Zrht4VRg;ufbbVIb8F9B=Pnn!_ zFr~0bN~%+PcswynH@0bknO$QgGvq*(6~bmJ3zQ#Q_CKFJ{FZH*^1OlqTjspVInW&* zt<6TR200`rPV;@tiaOiPE8uZz!-oXP9T3Hh`0qr7S*bC9Qp2{XK>AUuXKvhV=R=OC z=#&blfXE22@-lh-Pf`b!a*cna zRuW0Q$DY!j64Hkd4Y=zvz$K1O)KdPfs|+8?M3l>d&O3-U=eeG2HoveQf=Z6jyygTi zV+szH^OnIUL|o`IbB^3yqvm6w1#1vd@_tk?k4a(5>5<7JJ>lhd!W=mzTS8kQhJ4Mo zRt=Z6YQUJX&wsvpFq3DcBtdyBWb{P7l2|+O@r1+qZ%#4?!7{k8ssRVFT<#hxk0^;RSuIv)|{1~7G6ACC%HZ|JhIfj&`OHD|314xc=dT_`n(C#pl$_*WtbXiRDKyH zC$9PcUH%7w0H{78&E^f2zPE7UUNkAyyY6pp$9sS}gt#e&MO=$QeFv^gKDRbG6JIBk zMHAm#j0ytc=KJJ0)*e~i{I@urqaY$;kXb-mX&OLE33$aoj=-uo!@_yL~<_X#cDi$?fId> ztA38_vl8+tmcI9RrIUNHf1S>BXT`)(70nlRzM6J~tq&PEE z6zK-dBzf+wqV9<0)Z#rHQJD01w1(9D*IM}^h28YD!+lhg6vXsH#N=1YzyGpqFDTo4 zRwpZJ7(D+iY8z+9%cYGSEd_9C)cq8ikvlmAGyxoV%#%P|7ahRXq`W~>qP2F6^vba0 zYX|RcGAC$_)%E3x>dq%Oq=+TBPSTii2pf-~BTWh&C9f>@9`R&Cz>0R$ASF0g&6?tT zted92W)RRG{5XanG+8H6WsXN3Dao^ws|-3y)uIAlEs8(l2R`oSQF;8&PdWha6J9H%q4qt z!0rg3KSbm*=|l~yDgxl}_nUj3A-$hk0_;o-bBr73wEUB{_FMr@$wPL$iH81qQje?n zH3Jh)m+^0ve}8Y;UQxF9D%;D-_Pnyap=|$g+5VxwNIhCM^*ZZZmwHGu*6(Hs-*F~J zzJHIcacQ){{u(wlY~d0tB}MEy0xCyC-y%+}%74P6saxy(!I^JYI39B&Bdk?<#P|iy zM4TvqnK`dT-a=L2*DIg?E_oveT|ue*HxvU(kx}f3)!CRrIKL@2DcHPg6B?l@#pD18 zO$8CcLnSu_?Jz}6`BMdYCXZnY;CvpUjhO0*Y1xWEuH?|nUGp-OHCAz`5}XW z0%2h|FTt}N+9NXk?oD_HAuEM7Koz-3V*^1SB+yMA@Yca^BLNc}+yWHGK0PZfyP%6& zZEa%?0-iFo?fSkL1fROH_LHGAc7q%t$YoT~bHs?_WP_hMGUK zfBXCQZ~yK6ho8AW{<|M@7@NG-Sh#8*apessC5Nu`j4^-xC%^^xHUoesgwEi}&3Gmk zA|Em2jU$lSyzp6OqI19X%X&B0I{&BXVRS9;iBDm+kU(r!~kF@7-15S9# z{KAkGxqJ3}$+sJQE^kP|?e80ptl2*7?-KXUfi&1@6Q&%)YckNs2wX6L2y5%UW^wO_ zFtDhF{}~Xla2#&k(%u*|db;`NLw2{0;Tl%sIcz7&B`5vv@d5=)92zG-nuWq_{iN#X zBaW%#m&Z8RDwCPn|M=qg4POFMUgG!mS>D`kwrCUE|K-B&89jg5{`J@HzxWXw5W9T$ zyqS$KIRMx) z6)+v0q_2-ghQ8dDtkA{=rk0)OjRnBn;e=)pKCsY-IZqZ2f5j-h{`-CVBOKS}?Qg>=(4)qy7vVhsSXd|2wXtBCUDFY5=W`g5x&;wiyZ-3Whal>6KPCWQK%l?d zG|I334PpXVUjxy^bu@@iI=cM?{*vAC6v$$ zgA-|b7&c>Np2B+GblJ8^he5J;jS_(MI@a zhOC?%M$xSJ1N)D^V1Mqnc&F>d#LmE8QUU)*`*r$b+7K~mtyREcpYSM(&Tw8-4LLcC zVPn#B2X!u$AR>t+>Ja72yYqS5m4G)L0HlC1)GBT56fAaVu-I-UUS-(gUcx$lGlX+C z`b~_24M^e|;eoCiDqxOH*xxZk);mN}^!meZ-oO5^GG^SY!5QLBj!*re{qe>73;qXP zJ`ht2?x2f^`Tn^Zb7{nuiI0Z0VVeAgW1u_jQINJh)`Usr4?g;FtN$Zs;jk&<-GSZ$ zf$j8)2qkTw?BPUBc%mcc65agui|x|WUQwn@W!uic7GXVGcs>!IZDvgqHHUPpW*NES z7>9sh*!C?cMsniJWzI1)?1vlrx%Klmai0Ys*&kZabcCpZ@}A0Gct|I)0wh z77)QiEP0Ki=*92bKj0a``>vw|dJlj_c8WSXeztJG-aF#FIF}*+GBZYg9)dAQ^$kf> zJh?gQw=sY~jT$s!2~?$;@z^qY4*=rAWJX+QpxmUV9uU^eG{!)tQbpjgF)a=hDjXb5 z!<&MFNA8h2&V}BQozXyCeB0q5U0^WAU)xXmze*R3XIAM1LAKE5?)Ud!*^SA+u>btE zw!2*gB&j|dVZ}1@uVD?ujK1pH?~sMz?H5OEe7oK2XVl?#Ef9hUH|@Z4b{R+4FHNaq z^OFE}{ic9v6FnUC&5#ytISzWet$^*Nf8j~Q7VaF)eSZlSKDXV-pXh4I?l?qO+c{~9 z^YaKl1v0ZP8*7NXQ*=seYt_Ii2CN#=W}8no<$*0beVg%bH$-Z4Df6pM!L1>ce$3)n zp!Xnjb4kZ-%^gwq%k#f|zehiJ|K`sqrN+%AF{pJXPI&)++W-GOc`^dm9GeK>Te@Zr zUkgNi3ooXV3GSyr1SqpmubP+#CHSe7{@->0;G4ol^Hdy>XAz_w+1cq-S0_^}wJJl0 zFRHfWqLV20(6}X6P6%4F9Syaw$GYz8SEuy9>_7a!_IJ+zvWWVv=DB4Ft1oi~zKM+oW;7&nAf%oLEG-x|O^%A$%xMkX^vlnBW>eseh*E@_X&s%{DtIk# zh%z-#c!q3@re*GNi1zKXZW;MDC@VG30m~C!M-VX}Xik}j+@U=#BNDW!wG_Jez&@F( znh|3_b~!a4b>P`1i4}Q&5pX_LYbR!%W**d{H7~53wt6 zM1hz0Jxp zV`l%O;I}BsEGoLZN7_*ATMfNs-FFb)Wisbk^XJ6Kye7-XEdU`jsb9gI@?B0J0I0`a zOFzc|XTE&;b0_g%+`seM4)s@Y($MDRxxXi_VWoJQ zo2SJ^%~A)G`$2sv5$T$#mYty-XR$#iiACjK+?D)vDS_W;01z_d7&bbg8PDu@H>jJ* zOcx0FP+(e(PS@ZPMsLdW-i#1l}kS0 zl;1L*8;k~j$0$VzxWpz%6tm3scr}feCt6hg78%~^NC}TqzUd;|mDgUK?Pjv9SEKq2 z$>Oe|V8kjcw2Fd=4FL*|nhxh$whr`lR4ipvF2Fre77$_W7>@Z{fWsys%7j_DyE*h9 zI$nXyG>u7we{slLFtbhriq6?kxh$i0SJr-4bwfhpj=ULQ0O*5fl73`^DM5Jo`M2)> z`*r){b2x%qZ_5sHY_6TZlk6V+Ax|qjg46Fx0xlC#C!deUHKxMXo>qYUNH;Fl%#zdY zsSGF4<$DR>L;Sxe&og9rRRho2_33*>%zStJxXl~L3TmXLlBOV=1sYpR zmeF8w7-qaEkn5z93PtUA6Fj?Q=-__&?!Vl>{%iZ=ua*KwH<*xHF%W>fPkjXh!LFbz z`=+tZf|H;%%CHD~FmyL+UxH4C$?^rHY~jA%Vjl^!OuV}Yw+RTxc4;Tv660NH_@fxl zgD;?-!cQZUEEUG><#yhX4;@(1upIJm`nD>TDr9IpfTVdHUM7RZ&(_Id?u@;|JJI*; z5O`GV@Kl7As7GjyVR29BeS(Z#xNw8x@>-DqWLbf5i{(=*{J(Vsz#~K$iZ1eH zOe|tj2;KxWjAR3b1YuGy2Ak=Sp(DFctScodV^-vp)S5+kuMxuZH#i7!$flNIeffey z5$CD%H|FW$l1Pw3I4J7RC@yU8?JWD-0h0?YgFX8SRuLV}m!_1K>xd#OMm(U{n>Vv1=A# zC8kl|)Qtv~E7jOS*iWrgMac@7b-7c4Ve@o5Tkx(Z3~oVy4RnEOO=8^|sXcK7RCJe@l75)39Fl5PA?u_GZkV!B_&BkX2j=W1 zhh!}t)~167Ug5tJC|8Kl-qQjg)wluS)`D7y2*LgC8B4>H8ndy+Co%kW*XRNgo+@HPVg z&e)-Fbmu>fCX!B$WY(dpp+4^f0_aehc+28-0sWER^AZGb{DJ+4pOLeWh!iRdvfVzrxb2$jR|h!F#Fvdga8+VDS3p_f4lJlovBpWXlWh5IkQ&6W^X88NwGAi>!~ zjOJuC#g@Y3#bl&N93uz<8AeBr2YPu-wtJtc-_GlL)XT}6CP8fvbb~6+u~BmlG=xpG zh!6|5a#+xpy56el67Cw~)+2(9uu()F3mKSS)|19iS4lHtZtj9WbyTf_P;&PApb#knH)19hT=5` z@?{+ryPPo02Qdxj8&S%962U*fsr=O{Mhv>*KKOj@AJ_~{G)ASP9#Zbp8y zur7z{VSNcYj0~_0Mvrt*(a!lG7HWLYNf1M1*;&`u3a|M6f(8wQBCikkB7UA&>n>7a zy{<$Y{F*7#OF%|DvMEoT9UCj{Bs*m35C8l2-#)YZeP`yl$P~tBjF;_Y+$#{JuujUB zR|pwW8IZ17yNww!sp*8!;cOm7V+T0ul&p6_Sn(%fExqM2!M7U#98|Hx3C1wWs%~BB zpjbakeBQ6@TiYm<1ryw8w+2(^dKwB4tDU0=mP>ZQLRz4XscOA@2#+ny-Oy0fO#QoxdaOvJ)#rUN8i>{ z9Q}*yW3!k4g_GcJu<4-D!`aYYGdeUIw~+yE^vF%Rpb#>QW^52C6+WBJUaa`$r%6U2 zk_ycZFiwAYjjpi346eb!qq+F;BW@0#sCFQT9wwzj z{BFh8Mv_uM5S2RCXkx&QNK3DIkLGWjW#LEb@|6V8C|sIFa`2l-Kd$YAEyki-cpOsQ z2vr0i5)I42@m7O?x7h<=bj%OldRx!tJkmTPc=jV7P75>`|CCu*AjHiHK8?enY+KVD za`Y2yu1V(JAV!V=iO&_LN}EUc20D4&P~ykOrFnwsk7RJxrUZ`h+5PdQ`>%g+ypAW8 zQFCfFpri8$+s)QnVMKMe=Y=}oW(`~c@>_wPVMu&{q5DsQir#>v zBz4M#slOlt%*UX^Q=CUE>IdnbS>hp6*g(}U5*k^k_q94Omnn27f@uC#0Gi}7#an0fNB_uej7pTs;U!P!VOB^`MQ}8&AKZjs+AE5We3v<|MmMD{Gw;)AMfHeN@n0O5=VjR zGSEoMDxl~Bctb{o$x?}>9Bn?-C5~DIg*e&dpgoSjJemw76lNq~teR|TfUGwf2fW=9 zfbW9oxx0&ybu*)Mq;H<`j!o6(srPtrM5Cn*4hBx8z5$-n#s;0@ZPU=TK%1(%=F8e# zs0XWHg*K2HziI#W-!V8&V+~J-jC3NFK+YJZj=iseuioF|m+gP~tdD~X_9eV5EdiR% z(vjV>6}~w&Pkdg6dS27#7Y4cGfy6!ckNcPI#4_ZoMPQP&Ut#Wv~hoCc4qw!s5XQv*EE$FvZWB zjQW25uQOGC>qa33O9=|+G~q*;dl>aQ_iz5v{{4Tm|L$*Hy6xj6I@%nPXYUW^_^)UN z^^M68O;U^3(_++!(0mhdS^NK_c~W3dh@-50%YdJNeD?PdZFh2AjYw;38nL>^Ge2cu?uHNq%udIQeQN1~;65xM^`Q1HZ&0|U|8u9G=Tcfh^ zoceSF6f0e#5apbrv?4FyeI9vJ{A_1dhA`bx&`lY*xmlZ3J9XdTh6$#@NR{ z-P7C1O%bF+kCM*v8}W1Ya&}9m7^N>Xr-i`6$0^e|+Uh zTb=`PPibx&Gfj{?hDZ?jm>CwR5>3;Owl7+D1gd$Oe$Ck_f$8XW!arC$U1RIpvG6J> zS?V5#P72>>1n_nPfOZaDWML{Il%8gD1~wV+qkA33VA}TH;ExU2iyX&O$Fg-9KtUC( z!cnX?JxA^2O+$!I^LQj?)`Q<&OhZDzd||JD>;BxIzd!!MF!p!GS~&N9c7H?ewcrpXu=xam>9{}sg9&is_C6o1qs>)d?)ACP zlH0#@fBbge7^)L^OsYGP0En5VAVZy)$At^eb3{w4m#Hd;QGY$31KfnxM zCnSQsk7$#%#j%pI8jSH)|Gn`Z0M;7KMOJ#$s5zz_)O4jZ(E|XnaH{!TE=bSV(W24J z<2SC)<=eaqv?ys}hU*uytA*I=o?%x+UeV?~XZ{;K<62ny-@SkC7wu2^-W40!L4YXf z{zg{fo9yq^PF+r~-TfMGLv?;0<9nWs$iFE}jMmUt!#Mc+l*<-hW`c}F^tRd2fl4cS zD?NbYv}E;RfMSwea!*aw~WGjKlW+;55%)Nr$Ic*?hv*~a)bH~qkeajct!2NgM)=dMUygsMV z&Xa0U;b3)tDp96bayV_Ox=u-CkrpC8mER-_pK$PQrmBMVgF{a55z0A`UPASltod|v1DT5vP5D$J&hLRr)0J3q?Hh2&|b+E-~?9t1= zAKbrtW%nCJf>X8olXchq5aY8W>_-aeW?2Far3MVa%M|%i^xqN!pls)Wp$$hi@_5{Z zw21@MoeOIdv(ghY=^Ec|7vP(f15S&cTN|b^c(RJEO7_jMiWit*)>>h(nQf`+o^gYc zY3q*A>n@>TckJ-Sck82a>0_t@6o0%mM-J0<7Lva|w14^H{hs~7HMLe~XI-s@aUp>m zH8)tA2@{Cqtm5N;zlk$ilaWQ4FY7k#=UVmV$e2R6zvWOLC?JzzvOO5Y;l#`&)`OVk zswC=GIN%xZo-TR2q57}nN%!9cY$5!Y83vDcqhE|i>>t>dmZ@ju)CK$OF}&{f(cicK z_{#1#f%M%yal{X5ec000ZQN4PA7IF!z&;1D4p87_QcECAjMR;anVN@7O^!tz%lb0% zQW9pNt_kE~MU8@t@mv1)#t{I^Eb$cPD6)*X*e|dlW;{Equr$?kIoFvR3 zU|~~&FS{0eW0W1~tsu%u`M@+S0;Z|13+L{4w{wcQq+6bX~M$>bXbhwlq2=h^ZnzJO5me)Y8w# zz9{2?WkNOVYmSjDM8T^$XZ7s&ZpKxUE>uifj8dRZy6wn9pBtaP^ce=-fA{5f2Ls`K zfjWwJ*JA-DO!I}2_R!#*jtPuIbJDMakgu14q6}`-CUFK}60%gPe6EodCvtRqzfIgE z$Aw1S^6dZv7ZxDfEgzt#ZFWhxm3e zlR4Ur1Zq|t?6ua6miFJ*SsO?n4_<#8U7IFCTf1e&62jn_DR@y|8!4W(fPc;Y({G4y z1p>SV3El@$oa3#TSsm}^u@#-$s%G%QH(u8tuU^{3Mw@z_Hif~ad;8koWng_vOK{vL zGfr626N@~IO_RvTUE*Nl$YbM7Ea^hAPAP2qf>*`_J&4fQreOd~?lrB zhVeQQ`y(YgX{{6#zz#p4+0-D`u2CS*#G!JDbs@m^L)b^M6Jv{*hlOK88pyV_`^Ch- zJ%^LM%#3`pD{;IB0E@2YY^8(@vw35O}yl)v4WrUYGdC!5zr%E$#%K2 z4_l#OZ#iGTsa2EVJ4c3BR$9@&QW1s!PWB3G+AGkLyX#PBE9WMvA^J)lqJ;&K`YRn61xyg9_!eRVrb#@cZ`=F*$?4 zN(Biz0EXYVKfYwQZ=dn1WpzCc^q>w_cN>aK!T#Hd2EbLh*#$%}4Y<&Z3>J(y;CAx^ zlpH6xq_{?XQM)q1Fv!3rvTW%zR4_$>>8?C7T+4?T*95u8?VOnAe#3+dYoV;`%dSp0IHIP7b%Z93zR)7Wna!4*&y8!^Ou!yON)D<+nb*;W<%H*a5ipC`^^JHt{w>^LKBfRps=R*ss zW(fjjEy|OIck49joO?b|4d?P)?R!QLP#p*6hN0_@MZ)#IWk0%Kuz&pl?+9}mWB>p0 z+HTI0O&a^W;$*OHknhm(Fo{%7pkw8C3)zaPdYWVR-1SCqiOjOsRZoYYxX`ziy0$*s z=j6rIie*WFWbuBiqCbD^p8g=shi?kS8Db8erV_YY%9KBG#u?smBR+L*{Ted17uyi>L!@vFym*z^qWPC&T8vbRW9O_#Q_5pq5xW{? z=}5uPt{iWr1CDWEkJ{J)5<2N&-r4=WUh6MRP64BCMuQ~SS_njWEiku^x_jeNpkl0z zWvJnr=9o^0kABTZ)JXz9bn*~gv_2gpA0kr?*B z{{7G0zx#GQq&=Lp??(v<$l^YkOkxv_Z1I|^tQshTg+yCw5)-6YkKU^r+G@6T-8Q3+ zLhZ83=)KV#cItxJzS#yOK z;uL2JS^wI_;WM$%GjjDEOPRjRIC%jaz4h;4tdk(1LJzSJ#bXY{*jl(WE2y`{$V|{g zKw~a1n0{Zvk^m(rUm#}CsEoQGmwJ-k1AyY+HuPpK;8m(@`0fg$A}bVB7#vE|CCdsP zwT+Bt=$+|Pb^j7!t1RNeXqQ79r3Z({q^;q+5i8~ z@1OR&YwEU-fwWN=DZ$4ZEmVczOiuP0jz8ns(9-}rb6+D(+*DjycY{%`S&X9V*6f?J z&jo?Gk6iKO(8zI0+{J%n@i#x+csvL6Q$w+i+%f`kegEXf#P58j_T9hxUXG%?FpI1T zGON1Egmd+9;qoULz;zZrR=fq>%TNVwOz+*O_b#ljf*Nql$EnL0A^H{5%k>lG-`frV zw&wRUWw)Zn2Njv#@9I;BMGe`7%O>GM1)DkRZJV-89p3VWZ$@w=&0L}1@odJO*mWUa zDPBznmMc8V|q{LMAckKQf+Se~uqS zlgM)xsF&hgGsI_d=o`m!{Zw5rtK`=-R~Fm%4A`n>?q){+$OTI0tP&CG5|>yHBs)(c zZsnTP^QRCed@?0~b>!I^nIsnAU$lk(sjXr3iy#(Rh8b@Yz0A7z|JCK4ym)$yb8i+lPp(;!C zgnS$b!c0%M$AL&7y)T}|0y)iUa9ak|Ru_k54yEjs*c!-k?UP{0E)f@BDi$r`YWk9sr($^OJpfp}m`@P}SW{Ty3N7_4 zV=Ld-)32u5yi43D>;5FylTq}`@Wt5TX_9?j2uoKW`zsCETnOR}m-i949Rx|zp8UuA z<5xVd4y+{M;{vLySlm9euK+^}!pMW!bnm1Pc(B=alz7$WOml|pjaOviG3wF?y(KJ1 z$yDG;9auYRd+0gC=K%dFL_6$nF1Oi4!vfd9JyUR^Gn1^$}-@k{on|7icTRT#EC=nDZ4AG{rB=l_dX&_KAhs)K!k{C0UHsz`{P%RacB2a z>)A@@<-L6>>6Pslq9y(U0v9F5S4eCUIbnue=|qEq;BL`?ENlFU&ZoEtc+nA2TP;iKmd`uFz7SJXlOeB$M?4F!GiOE$j-2nc}z8{U2A+{&dFo&C9|&?x*- zaYrDE{>kzZJKL5hw)|XKEFKcJD|6+m3S$@cEzR-EtVw_Lx9pD>*1(7M z7+BPYaXqyzvNTL$F$&?t>Sq6;sQfuw z<^lbKK-NU$$viBD+of8oHQzMtHp7@!H1SmLhX){|6ir*`lClMCVf5GwBh3(sCEoC= zWRN&!*EZ(#u|7vHkoKl$zK9v#uKd+43hr@4$X3%VMhwmC$mhU)A9vmTV{Sx z(Cn-Y3SC%QUw6}Ro5X82_KrE?vG?Z#qnHcSwR>K?=dWL%k)~fXUdB-|yz*tQs8=y8 z&o|Me6nBAdALCRk)N7>x;;Fbwf?GArrBpJA;^B-GhK~gF|Cp3=Wj>9ve<=YzB^KICrGw69x&sEA*V*p zL{wINMM8puE5*IxBxGl&0-g2GC%hKws!I{XI*sOyVDHcD-@dX2N;|<~j0ltL!!CkJ zPkXF?XygzIF|;dD0xBp#wwJ( z$#MtBNfyBzP#+G$JznK9xdeis0alt4-tBzuNf1?k4zoSPI~DK)2tbxmruii=vK6J-knCiib(9yHN-{X?y8yW}@=MmR*x(gIc} z47Amlw2nNEv_8-Ti{@bEeY#L%eT0#Z+=EMg;r{j8VWu2!aTH`@ge!7zkEhIq5eZ1i;2N?(D{-o$ zbGEfuk~o{Q`^*PYk>+O6>oRmWwnr**iX zP{PH!b315@eM{DzoBohhrtigw-Rkw#pbQS`=gn4lcW#%bv#bwsAeF zDlcdhhl-^Q)Y!^<0PvxKKnbMJ;*7?rQ=O)n2TT0ufxn+)z3bzH*vayn$>W`7 z-n9O^hb^nXChDaRF_@l4yBLmrOjNLI`si{neN_0ZY9!|CJi^vG7LL6E1|EaDV(jT;}Bj(A24O%t{6KO#gTs9~So5p| zfR~o%L#h05v1~|je+%TmOK01TGc1G2+z`*KSA2`X2z^i4Tgs0^mTmcN<1AyfafL;B0 z)?PZ9Ew7+(1{iLEVepi1Y3l6Vc-w=4zya%WmXSqR_S_^~L0TA_UlyfAON(rdBsL8- zj*(P>iOgW0$y&Z_IEuZ=T;57EMN5%;G4@$<@=B0* zLZBdf9I$la3%`5Z!ny>~x9|Lp{bPRVcqW-*qqjANnwwkO!)#Cv*2ckyK9&x;ljN?T zilVQDF)3hOlfT0Gk(y3w+gE9%GNOthw&1j+dm&)y(4pAbn{o_{H;@0n)d0W;+Gv6@ z1~98j+b+~f7sVcIMk*?@qo&#X*w-uSqh-f!Cv#aI=b8QD@*O*6i~H+e5rh^9BbD!< z7~bg6iSgU_ufKHv^=IdT0Q&wrx!)uUs57EfdjPPI zU>)7H7sG~AkRh^M^if`Hnwy}!F51hn_*D|)#}+Sojy4Bxc@2Yb#V_*d#`yrY9q&>> zZ6xk^E&v7s1Z|Os*U$Ne{r9h|fy+c6NTH^OuP5zmj|wWr2Gyz*aD`@cQ4)0tnwYX6 zq70TvCa1i`axT>a`u8TFa9RA;@HOdke`WW>_>HY|_!#@PjCi^-T8CO8a7Uc5KU?Gh zK3kPrwrO+-O?&)^S&r0U8(r%sA9KBpjgfVK1m95dxO^I#!EZ7Ea3e)e-9|(0mE!Dr zH*2pXMeTyyf>Bq?6Tq}f#H%Xi(hY*uGHj|UjRl#{^Xt7GntrMqf6{UDsiLLX8- zm5l}a&n)L-N+*>Osv@d9+@lLF*lZ(yw zxWv*|#bKE4fj)C9o`3#)WA_`sZHf2jYOW_K0NDq~vjAEKsTzd9G$>?-u-OO26ofc~ znD#z3 zSUT4`?SmFL>|e-fiwEp_2ivY6{%7|0|3&-bcTZcuhf+SADDjPX0RIr|C+#J3k}rOi zrM1$gAbbi_$%&RG9i!|;&bS>zGpHt)VnX|hU|G)Jn(NXCt1+-dG7+mFUpq@m_wjI{ z_W*#_V9f|cj(TDwU!_Q*nIgVJyF5YnJf%bzHzH6V46|LvknuVA4N^$xQu0t(&+=^@ zeJX0(%STGev!EWiDU0bt%54YY$~2+bg!}zvuoHb~^?FpF%|NMiBrOM_0_zz1+y{w$L^=^7oq6sF9-x&)LQOlx%6;bQ3bD z)f=y{wrDf}VR&%eIF>LKbTc3pEikUwFuII7&*S6D$`G4*QF-nB%)hulz8KG}ft;Um z;xl(}XbAam@tVz^J0(cD;0TMq9kEi>9S&HK zhZBfmq92!?`wZQVGZa9;Y14blF;VilE~e*#Jv3!O(X&GzFqEc>b^o9X0-}v5n<$y| zA6(DV%6>?yMT=!;+caLG%{YKXV zfv|R>Em&3Z!^KUw;P~Zq0q2grJyaB`lPZwE66jKz?s73q%_F_x!3XZd(3*wjno&4; zNo|nG(ca#_zvb;Z_?As%xUTcW4-XT0ZHEPvb}KnGlcC->gXj%AK0?(wWmb%S#VeUt zEM#<7o3a9keg|v8DvPem02JT_t{hV=aa4VF?y@zwuB*)jPGd12fBSc14IE#!KmS)n zZc$5?b7#vtYUM?^(E25Q~gf2+A@F-Fx@eh4xZ^tgFZH_RVo`8hHJKGp@k zb^qpH+CTqCywkA#LUH{Fnp#}Ak(^A}bmcM@0jO*ahDY(r9voqd$nYBG%1?7|tJ{Vl zbS3XwF_t_ZgE0?V$uQWkBxqTou~m3#dsx(nvNbWlwczVL0JviR7QEmsGrxD|AFl6; z{C1Jna#rKB1_&w$=r&Irvza)(v`FjhP^iv#!-GR9e^tq5If+--Gh_tEL5rh_MOK+yp(0Qyj@l6Qgm)yh#Z^LEDK}rncX+|M<)IpZ=P1$Y8vsOpewA zNQ?Ixjovh|;G_a-#>sxYz;j{)TYr!A8cK&6<-MU}A0`CRJAbc;Ibp|?44b_DiEI0c z^`79BLO#Xo?3#Y#;{b0n0H|0nx3zVB>eioMXQ)C;JYhEl`Iuq95_GK3BIOM@798(V z^xj;vrsLYOeR|k<7FpYXfDVaCd)~fz?2jO|^H+`}BMo1JRwr{^OtDfBokt zPV1-am*hDh_?i2M{3H97!PdWXv)Sc(gzjF@|zU&nV zVe4c4sk4opW{P{)(M=J-KU(T2t{)TOC5!(r#1;!ZC#2Xv)RQxqE%3wu_!|6aPy{-O zNx!OQp0x5KWHOau0A8{E?*TxyVsc`+-Q`_xn_K#$XK7x%X8l`WPg6dD!dqEi;we&9 zbKXJ%J;{CDo}@NN5x_s4TH+KaRQ|HR>*S?(2!g2m^^7)eBv zb|3VI@WcBv_Xoe7+1~t&{r5k6|N3+Gi}!P0zP^+hhJb^&9IY8N=XK?5Y2w58hrFzl z-?V@88@eU!veZU9Y;{|vAVMy4jGoLO+KFym&-XM#u*YyreGdy>jhjC-k@xs%P4H9SA+g5aQIDGqRDt_x88FwP%2d=*jj34^XVHMZ`Sw++%o zH4Ec^<*ah(RvtCvaKCG~t(&{kPnrDr?Kg}UAsBwsvvW$pPIHW?Il!JX`#-ur{>T0C z$M?tgj28kLOpuuIpnkxRrQXtCaBXeza$C9k_cvaUjn~J2YmV$^>^J5g-@pBN`}aS8 zfBdZ13+aZfL+priOjXE#-=OX1=-}7wPx#NKhsqk=T`BjM652L%UP=iYbbz9LUi2%! zUJ~ZoTp_r~rBd~Uehrvx-k=OH47=#HB{F(?Utn)5BnwycoWsxkRv zH*Nn!4**UCvtSXU$7AkneY`C)w?|yiM#Ygm2l=HcN_}LllFaM_fcmH6Q zsUR4t+s}XM_8#AQbNc`1@>;vXio}mUxc3R^HJuE<4^Bj_Q&{LH-r6m zkJm2!=YZgOPJa&$s);35OaHIzd*t8RKk1uf6W)cA+@XI=99#O)yb0O$k7nQdkHG zfHgYJ*o;^iJb|dxjxt6vVo+H%0k)`j2w0RH;-TmWVc4mW=kwop?|=K*`)i-!^}(i*Pw z!~5gwZja}GKkJ4J{A2qoe%kJQ{`&sfAJ{+X+xA!g_v3X!!uiOP${B5D`aveEEGg7= z770%9!aZX<4A^wEhs?dLVbtr?GjSIj4+ju=r<%UiRjl13BpK7o9ee&8xb8$5`P+SR zkjD}O6eA3e4{Yw$DMh9+G!?@;0&vkTnoJPRcr(w1!#8-~>2)N?_4BBDeX5U|I+LMv zJ73DlE*+UX<=ByM3os;Cfl#I$gkNd|ulL4U7?eIhHP(+|`Ysx71Jx>BU8kiD1K+4q zWVWthh)gyi_EJSeH8hn!XZZj1>mx%xAGE)D<=jmaI7LW`_vet=C&M-H&S8{LZ}L*1 zCghsEWZw++O#!QMzCW@5?@tsGGIEQ~N*9+y=?ptAhLrgRJNg8Z8OInxOJ3#oTpNE^ zi@!n+CwW5?CnP3!j?_fjar|>!BRThzqNU@wr06a%KWu|{#`J3G5{vIUMxrJ? zczKfDNBVw_aEK;M!=+DNrJdxcTkO}oIRzCfFPrBN!En2CprLx`MUvRE*3U{T)V4BF z?y_8ij(US-C~=y*zZtMMP$0I38>2R>@PbZC1Ae5i?1x~V7wPx)EsBBRyj z1&+~`EE4ZWmo2Y~Dk$3Gw2+mHlzX}EIA`;@`fgw)O?T)VWwxw>b{8X+=)4&RYrazQ3C1wA;CWRCY9fDih&oi^aL9^fQE}-t^0adhfVCF>*CVhk4}f3^WI`&`5i+1B%BV6n&2(wk zw9}XKbbbcXENgxE>%wr&Jd@!?6yOpg>Ss)%EifmBQ*J6B>3&)Xpl_MIUK2DOh>+K^+=E6$G zgmvghsxX2E$C!`|U5$}=IYwH_0%yXuvb?5;yAM$!L{+r?LB{@PsNb*90;1ea*)g zT$z+D^w*TvXb~k6UGI`!nEm~5(%0RxMP3qAr`%9$aP)E_^YcVrkFhRaWb!n&fTAcm zk0E&hVGwLW0nM7Xq#9Vj@p7;hU%nb_Vk@-$=ML4{=tQ|3%xt~UVugeYQOWX^$Mv#|pU%Ox3rkMH zrt&1<(Jtr96pSA_{~SL)AGl^L${_CNngy_n7nb_st?5z8Q5gWMNY+k{G1%W|)`Z{L z8VC_AgAU#U9rDfg0(?SK09>&ac`A%F94a_&3J-(F^!&oM-4?^9u{a7CuU+l4$W@#- z&^iMLMwv3kJ-P-aknmWyan6`=aU&~CV`2q-*=8n%%F%tA8Vgl|$ftbtaM}${3<^Ka zOMeEFT+(&2?NZfzdCpuinxuPD%IOP;MS+>KZa$9}z?WH1j4;x1g!H3WuvK4RN@H?D zkAm$s1{aTLec1@Obo?F<(mkipV8P0y(yFtp$`7o1hiu~>Cnosjz&FtZL6cE6YxuQI z?P0O7_W)pO-6+Py07;?i4HI)lG7N<75<5S;jHjpIWD3$BdDGdaa0{CQCM&J*x>JUo z5n?nd6|)qNwiK()ALJfFF{tP%ov9@woz-()Cm^?n+kO4eED|giThT^C)UM zeyjv&oF_;UrKs$xK!w@V`n$dkt|2~ec=GR42mpMYyo}Bi&R)_mvQ8FVh8?)=M-a9- zn&hCoYPLq`q1EYTqcX|jTri}n?p&8MN|@ZhU5F7Gr9}#G)CV znT|R@(CIpplG%Gzx8? zzYhxC0@f)7#c8heF55ssAL?Tp+aaxQcp~5vXaXEE)r`jG9=%xycmxhuz;9B6IRn`Q z&Uy}K(tRtN3E7EG7arCi$Bktut~vWPn;8+hbZMG$Qh*Wyml9*6tE<~AUnVW_asstc zo7MJKi8O;T~CO*97yv=>6~tM>Idqx`}0iFkXNaBu*LDj(x8RQaL$Y#xT=r z!PXa)Y#Njv3L?@nfXxgo)^= z$VqSr7u^-3ypT~7E(2>$pb}FNJg<<C8nJn0&l@n{%O3NuQTSXYTT?IQb?ENzZ&iX%1y$@y#;eK=AFGEPx^tiO+))m*Zd zn4$m`d|g7+f|4{JFr68|CF?RCrxJDR1lM2sVA|qG(>V`Z`5`b(f&CU^wC$Q)P*!|I zl400uktTXig*iutMOA{SR0IvGx4;<&DcDJ8pU8j`0%IxwIpTV2nsKU$1sAT_M2t=1 zmyse~u#aoYt&Rjq!%_bd2t*~vH`Fj({Cl${0DE6HhXiqbBDaK&3dJ(>V5{8I&wh|z z399P3E1OMVmNjdOd=7D8%s|6K5o@M3&gf)MSoY9^GkEyJgtz2P#Ob2*SG#uA`Kx+j zkh$ep%M|3uTvfZKb&6OIlCD${(#4xe4MNaan@jS*jXle59C(PVAWYm`&CJM$F6RZP zVbmR6MZ>aC@I0NrEhSb|!dYvNp;QnZAVc%qE4ycQkjI)gB|{)*`nEHIv4?4!O%sfI zDtG9%ftnZyR%Bal1tp8OO%h6a_I!g48G+;x&rl;e{IX>fc#eVjGp9Z2po#KxKaw+ot@~e)RPr zl-5y6UyDDh<(Qus+UncVRcOGg$ibYZ$l1K4V*s2zPAu%(LiT%R`8_0l@PJ;krpWX%Xr82i%X0;iiROW4=hbD~V%MtwgjWP%OzsX<*< z%m^OgczF*1F52_3i>4^B%3hFRN7dnvaZVYan<#K41Re|m?1jhs&F$t%S-_Be(-bht zd<(8$S}2*84f|e(Va;_UKc|R@?*SIv{Nk%bDP}wRBSn{}Ogn`xgm}lL?BjgboKt-$ zzpuI`$N@^xV^U_1m_bHd4AZJ$)6jQ+P$V`f;m9MnJH>7O{x0Kf8XBoUMtDbKJes1p zJumatAQYh?j+q~rV`#R{hHZQuRq_(*tK)Mly|PaP4o6z_5%Q7p7{?;)1Om@+sJQGdX06FV_| zQ_rpENUD*i&7xJV?pXnBmAe!-gZ@yPMIJ#{sAIZQFXq>ldu}*dd11?`9Q>N-#zCjo zvuTcV(L)q2!32FN$_P;?U;;qZ&s*ViVB%M!yxhLjNr7O*i;|n`SdjLJ>)#!?6INQi z$*v>NU9b<|(eVPR#8wa@b-*@s?eSnE79%&|2A5-jn9l|SPlm+-= zpId^!`;g+Q(4W@tMY5A2&vaW9>8l=zQ--GdB$mK%ZR68Q^v*2)GIio$f(4+{sCX8~e)HJS@0#XYQ(?{aq z@kbqeQ0x}QNT~SWuJnTFlp>KA>Scm#%n z62g$Nz@nAm1$y8iHiWB2M<6V8wE3Tk-P6!tbs^(kM-_C3*F!;oA{uJh7q57{3+3yz zxyaEM$`^x)5*E2=7~3Ff=zTIq-}FSzOn#YBwoY`!+I6ovpR>fraM~k-O{8S@bTRL4 zbg&ska8SjC3q2&yq9Z^UzHb3?W#e_~03-J|pbrYyZxLmv z>tkJZF(HB1n{7b^*bc@I5&gz?GoGVQx9x$& zx@HX09ex~f(FmJinw3#gkw}DZY3@E|>?rBvDu!j9ZW9H%nFX3!6_sQhV-SFPLZm<& zESU`~$r2kEz7!qM@gdX)vRd0fan;$3;TI7W9}Igii9g5>+xKb$RLS5@-w!_Woq-3a zNytVQ@K^jFT)eZ+#x(sr5Er9zOt*bt*E5+TZ^;P}MocL(`CKHT2y{Ng!LRxVW)I8> zdWQ+B1)n^sKrQpsyj?ipjRpXV?fzS=6j4raa42Y(OZEuvB^6)35IVty_U6bXUdg|j zjN^_>pkffjXd8SiA`Zqt0Y#cJ)}(0z8YA}?fb>kPGM6p~XC2rjqE?{_n4VMu z5HMdaRb1raCo}pWa*Myz~XZXddDg9#10NI>1Hue zaV7w^{PT_gJQe~}LgmmNo^PYW}_vzfT>l%FD#0VDcduU z#C*(qx}+W^8I9hnV);tAU_wP+n=FNGVV`x+oSv$?RLoTV1#`FS@Hai+IiM&)fwh;KyFBwCB9Y}*p4O}EHbtbh={vME}T8y_~!n-X(qr#KmrqHT6#cLY;rZJFm6&sy{h})&EPK*w!pxv zGyZdUqwEw2LoHvv6cgn)8M4EP``EXU5xkPW9gAAx)KcH1noU}e{GFhzL%ib{qu}J$ z(y5NWesZ&CLUdfpd{*1B3n8RSHEg9&SIn7DYO(M@aeqoMW0h*3A862=8Hg5S!%cGg zkl77oJfb)^6?BGFb~|4L6uP(c`}JhZgU|pd)?IO5sxX#hAMzgKg`T@lUq$J;N&v)Q?qROGWHDRhhFI=aEl`pR)rlU9TO$&Z z2Hxs)T(GoL!yTu*IEp5)sCLBg5|Fi2HWTApuvk>AYU;_l?WQ}VrTR#@Se>??7wyeB!$RhWd8K^`e91Ztnv68+dUMvSuV z3LQHPLue$=rYUh$eTPZojRvk9VXv*MC7Mj2iJNj96;uS_oj;>*D^c@vP|vA`E-{wU zj2C0k$@R4YlI=$=2N!PaZ+2lJgNf3m$ZJzvFvK2}_a1-`iUv-@m(wlTDo{Y|^%~4` zxFBZ)e5HPPTShIQqC=WeqMZk3aE}NYFsV3WVUIpMx2&;#by>1)MS^x2r~_#4y&G-Sd;ppC z$=t++g#pu0FK5I}$GfMuh|N?JL@ovp5QH>aUBg4QpPL|o24yP)Ruuka6i_`VO3m=- z(}>;wJl6TW+0OR z2~~0OnP>y(_W)q&?!lt&OS~ftF!e0obX}|t-#)|SEHlg-7l1f0R}*A0(_HhbCY8^m zAjtIGsVe~um{eXG3yZ!-XhBWRAt`s{tpgEq{a zyE9C+Vx5r;PzZB!s!N)>ysDgkY;Nj(u_HNowfn}@gUTYIt%J5ao1gEVv3|3BEj{w2?dC+# zfF^)dj{jH|(aEq3Dm*z|qcq4I2t%%wz&la)=}a6y>nQ?-2GkvgI7@a%k5c#u#pWs5 z04ql^%QnZ6khs88aQPoKf8h}8`!w;NCgh(g2Kcw z*=ISZ4&HR207aJ?-YzwWn}#xulpz4fmkMLTCdeS82T9&GhA8`V_a?0=bGu}&%mt2Q zy`EBMJD4a`M=&Y&sTjFl+m#Z$1Ld^h(%$#5i0Uo|*8UaZk`Ii!uOPJWab$EN^v&cw zvW+RB636KTXXK0VcyP{{!>oClU`AHE$T|>(9YdrE!n#;i)CS2p2^Firt8xA#!&B$< zK-`bK#sd%qk2>SSGl5BVvg5m=O^T2&2(N4iTgGC&W~yNKjm7|<2m+u{x3UF;J%TiE zD5VyFz(QP5eK2P#H!F&RqfK) zZ}&bcCAARrvx4>>u=BIVO`EyjAcwNNCPoXHGV|-l%SsH0EFFUD279|aKyP#kVAd#Z zjmWm_)g>}?WEmI|Izqb`y5B%uR0_hHllM)oR)Sm&HJfLe+Y(|#?ZiuIQ?v=W&wNMi%m8iN;-?s22cYLoFKCL-0QCl5 zBBCicgnQ0xC)B3XT(-C=6DvbOdeo#glWY!S8Rst1AdDHwI8vCx#peEzz5(4ibcxec19}J5oz=NP?f;2OCKEP?>8Z5%$*%=md90L=c98kYsHyO_m%B?DyWZVK>eTF^K%U6kx2F4<2iqn3rQ zF&Owbm&q8#TLYbeK>;Mh!*U96_~`r`Ev)MG=y7<_Y#C8RR9fY!$s;n$oTE_^?TK}f zs6rSmm^qJW3&54}K}>vveEwo^!7GM1Ja4Q1RCVGvc0XySBL&_EsY`6Pu|ZFvt1jcU zr0U6e;3cjRE$;xDfK4(UR!W6FFnN&(x9^EOIg*$8Svo^h|K?e?N~M7@3WUHnRd4YsULuh~e1x&V^gGr_U1`jYfah)3|KD%`AhI`MrQ|>=Q=VO&Ul~0fS01 zH|M*I&RmPF84c_{kFMWpA@g2nCY0A~;d!>bokf~Qq0$%~k_{v;1ckPitXcFTaP^Zi)(}suASJ4%WYVLZ>3H16jqf-wmGDtxe?Wmn+ zEKFnAF-l9ErA{KT0kCLZlXYtIO61?W5h^Y;P$#pi%6wVhfiXBmj_~h}i3(C&Rc;Ka zwYxP;D$+UU3OFM@Tj1~`%gaF47C!)I4@sBgO?k#- zBh;DU1COBxs!>)USZ}xs@Y84lgrFCBaMXztv;Zw^%enDx4vrUg16(HN^jCFx@o9{9 zUT$TUy=cUu*BWz_rW({^YG9mQy1su((ZjJf070}Qy_Ac6qqYORivJ?@Yk96siNs|- zMYkSDJslt=RC9(HfeYJOi6YqXM$EPDEm~vK4Nc4Mzpx%50?1LV&B*rWXDZLWFlv;s zxqlSs1g$b(rCK*z-Hs|(H^d#fe@x3V^DT3{bow*k*uO|u+lP}hn=Ki^N zM^EJ79@h-VeU-ALKj#7!V6obn--cDQ;oI&3{8SKt51~>pbgGD%fsW!JlCNpD#)+Yq z4I}p=EM(19+ImcW4*Al!?<*J{0ghb%y|IF6^s&n>Jq@kx?uF|d;All%I=Jm%NzRe= zIWHeL2V9pi1cZl4FanvK6|E)n3W6dSyjqH>f};w?G}&S7TVjCW{e?z)GP@oXu5=$Z zP!l_*G|DVk?GHct2#qW$M63{sQpXk%?KBmH4l$T`FXYNeTOJhrRz&?eR{IBTC%eT6 z4%Zxf>}`Z=BS@get^RM>JW|Drftv#bQbvtfXkwlZ$m$i;Ps6I1lF7BK=A8-fAsAq) zojT@33ny*uhXoQMb)rBA5`Waxi|ns;CJb4cSq7{U3kLrT(DX8btA_e_wb7F9W}kS2f2zG8X`9wLr% z$}%=&U#~ofaZ-TB0)X$vG%4RERV@ndtz%9-a_g%N%E2Lz!Y!D31O%G$I>4WCSAWOM z@k0i>+F_u6>+KA=ot?oj)aC4t@&2h+);#u1*q(&~iBYI`u3%XLGmJPIm`D*=1Y}!H zlRSi&(q&;jhQ01$?v(fSWiH`A47oX9X7oqOr}l2-hw=6p%&HtK^uF2-OyPUAFG4yB?VtH`nIWJVkG>wKzef{YL+1QXya-eU22MIbBC zt&ibJsY*1xIKZe%R&^SOA~SfG1AZ`MTjhCImf%i)Gm($w1tV%o2~d2ittDCSM(+|K zP7riCez+{G$1tUaGD#_eiV1vu;c^K@!%P?O+9*sfAy9tOy|99#u7?tKZH(C{w0zqJ z(tAk2CALdRSI>*ns9Z|_Qs02bFU*y>8Ric4pycWfC5+J+cf*S>RSqkY0E&R42(Vc5 z$7={GMi@nGQm_S)5Zf?IC(DJ=xR~|&5^{L55p`6qhrrW2F8W)ZuWuT{a2eup_ED0 zqgSJ7?lZ?1ke?X(Y1wRa*ztv26ymB;NGIdrxP9sj*~PQxHLTP%ovn!|LlmDVxExZ3 zzwtswa3RaLR~8672pa850S5|XX}X`L4Iu9Uz#~{djnyk$`EVIKi@5Bn(!)f4k8Bhym)Wp2JH4L2x0ecbbNkxXZFoS&v6(Lp@ z*;0L;!GI3PpaP}DG+1OO4l!uAy?U`8+jX} z?Sn9~pDw(pBr;3+%$^KGa>F;-27_vth566^g#x_^Vkh_UJA~s|who}l>g*>sVMdrW zR?VWyG-%uq0s-$D?_$@Zl<2axV5~xXDkM*n$$S)8ddO0ldR0HDl5BcB72$aDpJa-AASXHj0ePqXRA#}DGI$b>wNzKpk*3b4^>`gf27%)O% zTL*Z8jV}fPtI&LuyB&8@lj%E!+M-~Dm9`G!fRl3&FbXb)RDmEr}rpi>SdnBnHJ z5X=U+n1zC-l%q&UUMK!ii47skB-;hSIH7M#VX-9TKhKaQJ5<3Pw?HoLeD4r@TKC38 zpD~ver^`ge2;%*?qHJdo^mEy_2lmM@{ut3!Z>OGnt}xH|Cs0H#b5?jK3Z!V^jmK=B zpAFg(xg16rXnqJG(dR7!z_^jN%8LixQG0g zG9Iyv(pqqhlZ6Jm05XnYOhPUrcjV%4kZ}DdWTl5&4@^Udw#hGU8EQD1GXbn{l<<`8 z))o7HnGC8)qoJDT0$ygym4s9A1+^?V>9&O;?{z{LD3Xc!FWbkjD$Cv zfPtfRPATdO!KmAo?xnX?yq%~jx7UP;=*k|f#mOe zXuaUFHco=uim|kRUD4s%&7{e+Z2_~Uq`TBFEB4B{B>Z{H@jn;fcG?}GL`Jh-!h&O@ebBT06+c^2HFMFG;Lkn^6-4R3G2;!s#jpv!PBk zaGK{8o!oI!L)ABfOIyS!Y6?w&tgH)Y>n7 zNI{0y?m32|h#VOdbN}oRmzSifm<*bXzcV0>uczk4h-PJwZVa`8_-n3y^yP_8%#CBL zM$-HQIsrcoF`#MmHbxpFQbx~ajfWiM7>a7Mgnm{GNbz=39vGQPkjXbOmlfjHVnFW7 zU`3$Dyw~`>)uwO&Oqq#@%FvE5`tOTzmOrEpsFsKDy zk@NL|WpTTlVrC^JJVBNOBPM5@GiKj9vB8a{fS6}IHlw+N)7+z4e>_H^S9nuaVn8&( z!WeD;6Gaf6_FWF>=wYnVPT)DHC zpv=8Mi7JfuN%T@MkXB7*3Id1CZUXer0P{&dTa*$|JAE1C6bQ?T>R+EpTjnrxSyT3j zIvIp8SS*U8N~2wkykap?HlGI-2vlzaG-_%TUEW;Cd=yf^NlYJ_tV}t$N22 z{6A)z%vS8U&cdXFAF}x&-+~$~SZ+Ujqj10*Edi|A==0V!gJGSl?ZIX;WTzl1o4YX1 z+a+o%S_X_00*hDerKxeT!&c&3tZ0Op`dW_29?=T=yP;U{DlL`VAqQb%Fh*fNBQ_bG z0b*BHR}}SKiQ{M*#ccGUCq_x*fJ*=1L&u0Xr_gF4@UkO6_L_ALvzKUPIRWW7o&!md z;O!UUHM?D70F(bdZ3cKcJg(J&+GRD1%T4xy# z^D#5N4oq-=B~(+EAC$weFt#)e6<(2kp1^~(}MfKZg zu%DybjUz)qF@49psBo!k*ll3cozWN#`5SZRwGpdv*^*-+oQ*7w3`aK5n9VLJX)ock zXc?5S5Dv0Y1O=&*r`tUUbY7|w2=_i@C5Vk*78#;Hu2j5KBVS&|V8-w_Z7LpN@k+tz z1-5wxPS{n4#99f)!NJ0d98N@g;w+yr<*_`MtvX#XYBi!NK zKtd!TUNQ$PsG7Ew%8#dkpAxUDKAkR?dM^PyfC6kHP$m-V+OXQuWm6v?A(x-pQHa+- zLibuN?=X6maZJLYn0GZ-3KX2z<_`Y$lnwi@2r?OwpFMZx2ZOH=7=$Jqa~yEJ0}y+W z682|Bvl~a-Yz6})#D)S+ZlS^|(A>ske6atu&15~`0?m@Ss1N(n#L1p+`nbEy$C6hE1~UzQWKBBBn0Q`s7eW89sxsXLC?UWmHZw}g(jKBt?{7JhHdG+&Nhg!8dj!RMpMR$ z5PuafenO)FZ+r?ssC5Ylomac#IX;A?GTrRE0XTH0)h5S~N@c`oShKu-z1GEUnrxc& z3s7e7KE!5Wu>*2q$fKKEmSSLoiU@NSOk7S6zCa%BuQ-O(H=71ZP5HqF7R5|@ zt;{p(10R&At&{O#9-DOHOX(CDjBe*>ORfHL*43mc&=zy`$#!DHy%+33R;#nX_g68HU_ zd9G8D&FvA^Bf6z6!-!a9Uf%WxniY?4S5lLJ{8++eKrfA)DDX=bC07+ z!5=y0#L+m!^@7C4EITJ%vUV~A5xvGIO|2>k9!-MJN(MEzKp-VpVLbXqkDI)r#hKl1+v#AaI-2jLP|+vscx;VFEwxIaz3* zYxdjDZ)5-oI{b?<V+zi%h>G01syW7vTAd4NyJLj{~i|J*1sxS}06S zf!3gUgI+2GHMwW>%r)~Nz$U>o?0zv`r$7Z*@$gY_4hZQnlTOLR*zu#}O>Cuxk&5zk z#g}ZbI?is7I8;x|G6tN+na(f|7L!5~0-}P&itUJ#s9BI&=nbJ^ReU~8P<2=IgINz# z1Ba2NpYQjPNJZciNh@L%gc1Z|*S!xakm6Kb$D_)~U8#VDE`(qjRIG?Wz$Z7k_QTJ< zx5j@q62ztWG)#F$lqhEH1U@!kEuHH)iW?KoO=dt$Wjc?#aniL|W@u{eqn!tYU^r6-70bzA&@?f$y_jw=r^PLEKsZo_+|f?2(c4XK^E}pw1||G0(-V$wBG4?Abw( z3&&jD=#&NV(iKQq@?>NsptWM8$OjW8oNLGAkh4O?qvIOBN`BICZJ)~OMZi1ggOS^8 zcNJheHeFI0SXX+G1})cmDi&8v?qbfiAyF4;0gG|0VYKNfC>LFY=0(|U#NMeAjp8yr zYh|EgtT$`uioq&%>7umGey^vA_-ap=dns9pP$y&@kO?I}Fl)Q1tdNzBoODTsr7%n6OMyS2slNjJGk+`43dY4E_>QcY1j8T4nDwbY1M@BCHN z6tLTOCcvu!0EQGbPb5B*f($j}<)4NHBjXn(m#yMxH^3A*on_hC%+*c@!GTjaGea73 z5{E#;&VdmvZVXt`lf)*26Z+iXNl2*fOK~f1P6do~o~IRqfI3-0taiygXUI?Suu&Q- znnJ`%pV3sr)f%s>n?V6;?Sjj$hl&@30T zYC>fOa%fgFSCXhIdBdniaY)vz%(K!%!Eexww7v%bQ};KD5-4XVtHXY-P z#*WLd(t1$QoqtoaPw-sGa1iK87c{qRpkZscl0a#ArFy&5<(S>Tbgwft-i`~jk!q*cy0sPS1d@^52LT7#|QQiXTCpcm;B!|rO za+EpPokWO+^&1Hl^MYZE(yOLtBiRJz)u}J42?{Vm?~Ov#ifp_Ad`oQ$S|f2G9)1r1 zR^fDs6AwyH;U2 ztTBV{$%>Icp4vXIx?=~l?f|0?2%-&!#Z^~C8nPkM&7wt}f; zF=P!J#d&okDlMNa#%UE8GACJ=xBV@B#_j6mraW+VtZ#i751p~4tGZDz@D;wZbMKwL zb+jjOD^e55S52T~BKY?ZK4V!^G_Mvx4~N~?qtRtBlv{^Ls3{?+bD~;1b8dj)yBa15 zA^NnAb>Puv;Zw%-kPHc~ma@#h9#y^v0CEQ+FP0vb32$>Z0vPMFrk9(XkeZhMfA+ov z*t)DLZ?A_mAcJ6-2SElw2(t{W1RDVpBoR<(B2>tLRiT2Wl1h+Bl_`T(Qi7o>(GZdt z(@B`eW}ak-VQNYnEJSFap%cQ?G}6#OGyP{}?|Y`T)?RC$bKiS^|M$NC`>M`=-~Zly z_uhBT*?WC!`c_q}#?}pFv*3l)PoT0zGMQnkd87&DHBpa97E^vU{danr@XXE#VhW-s z+#XOrD*iFCquwml%-ElM%qA!6%yuWo0x(f{`zi4qr>%#UHn|`?T%Rjmd9Mj==0>Y> zDcWnbA%z>FnFL2uc%<%O47(A6;1Nf$WRivO+$2iPQ>8Rt#K$- zaz7qSU05lt5H?#G42_=5>_>~2Z3jE|FeiWf54UwNXloT|5P;ZAiz5KC;7wiNgF!xW zy{^OR@#|6ecf89~E0=8931-Jr5Eo@X2;z?>bc@B<7xNFMTt%C%U)-esHbs0q4TVJY z#Y%o!V)pnr@X7))1v~$it5`zSuDNW)eZ6w`_rg3l#lZ`wNYV3r=b9IGqaM}m(c0}i zA)Z93R;#q6klUf{$#ZomsIwc+-3XCESSa30rq;!AAiVh;am2=}lQ0FFVYJSZc}{we zmU=qXLwLj$VOQINtC;~Zbx=p8rN9s?Qk^&!60@OvPTr8SuG$?{5uzMWWFkA9IE?CV zWhywHxXIl1+d?gWXMF_|m6z=kV;IokBLK@H&9(hl)AAODnHJm&4(Akd?Qz<7kYQC% zMYY))x3Y5}9B$-HsIpN_auz!;J7Bi8YxLkNKV>92l(r~BV`Vg$Y{W!_&^N+MjVVFN zPEwOm4O_XK7C&bt&AWmi5--bF`H>qoB6?m|hrLj|a=EoGGS{iI21{ml_cQMmwT3Qv zV{JR@L>tl~anL^_!x`mT)`o6%(J<>C`JRW zS~C|oP~I_fH_E&cqfpo^rd*VGX)yvXl0)s;5l&ZFYB*EOZQkjBZVrQ-yIcma`#J!r z={zhLeD*!i1qKmvVrM)lhokwN8!I_EJFnlExC-?xZZec=c{FRp9L2D<%zXU=Zl*-BUQ(2KMC)(;&`>YO{60W{;6Bp zGeWdVy^KANwHjqhq1m5Fp^V2Xe5$tW zRxpl-Yh^x;iniqwJNBg`y|K-!wmoh-pwT@906a6Dd@5co>qB~G6dV!*5BgB=hTj1kl7?{=#o=#A3I*S7y1t_E3=hBrsP$WyVq6i z*0vbbFVag!6Tg~5H!KNCQ5AljOQ+-s5pl8&=S`<#b@Y-K`sX=?t>oU`(K&S>>Y6+E zN$kx`x%rd~u?R&ctfOMX-W;zTiepYn#na~51xcAw93;wgsg7P&VSTD20abvH53#=+ z4#*)f+|>$zU7iN$6go2p1=t)h2oAkdcSZ7|9?1I84#zURlLb?PEFAlb4Wm*|67&~u zB_(P$dUrMmZMiT)4}#XODXUdbuP)`aNud*RFTs3rsER6TaTGnxu+>XkyB@RcUJiLu z6e1;3QxIc8q99z{o=CDljydM9;~z(kfe2D8u19TVPek|jWay++u=I9~T3@?1h8Nas zUE@+M20J3xxv0INI#7dm7B&dCxkgJgYjGq}My?((w$3HxTD@DYD$-;)mepmqr83b$ z<2GZL+|3HAbFpptMyH4r`Kb_Y+|LmaTgm0z_X!#e+QuI`07oDKTsy*^J~&$siMO&t zuH(Gb%=Lw(&eV*wve&-XxJ%Vob5m*0hRkeq!?>Y!-7d~w4>w#*y2rn9YIS|tirnz% zHxR{KqIoLWlndC}1#hkaS0QEhUafXm@(5tp z9`jdS^20Jt`=1T(tJx1GL>^XjIVz53nxxBcSx=G(U)LemT+K0{SVb;bL#Lx!BrZsp z%cc}guB-%WXbyH(3Wd}AL}B*i&tQu-(@3hBD7B=Sn_{n?^TfQ`mb$5?!#Fe^*I^yY zjiUl|$W0UkV1W!YN7Icigdah-#ph0O5_@3>FNC~g2!r7xRePYb<*Um5kci9$KTEgq z?EQ0Hcwbc}FNO8%Y-2P{R_&R>`=j;zVKJ20x+Y8%D*Hx!D^ZKhr+SPrIW0pfvLo8( z>~ND++PdTummpy|MKYq;CW(M+#EO?bTeDq{P4|V!NCyVIO3gZ-i<`P2T+h=9qu1m{ z!a`)pJj0rw(u>|V)x(A&wV5jL&veK|Bn+E1E)%F$<9 z6UO3oVwhEol!Fkx{0$-QGc9GVjW0WXUNcI^#yw7IuufVLJ-1UliJVD|wm6A2`Db3} zabs_iXtEz*`e0oeH7UA@kn+?469n->70B{x2adg}#m*#`-!2qNtDY6^zb0D2+l2Am zp-xW7*B!6Isl6*lUVlnEU;e+_1fVq&y*ag86o@2$EUvo8sH%Xk@(flXEg*%QoT*-B z^N}P#PPl93nye@9w>@!9P8x(=%}6)9sM;5KAsWNJF;O1PsPa}7jA;QAl`?SV8#E0x zH*Sqqm{J-yL86G3$3*keNp`#jii=iaspyneM4zbcv1Uz-IZ?Yqp;?5_!}u8%mF&H} zRYP1&ur@k4!7V^=*C4^&-6cRExVr{-cMA|)fR1HRK2 zYc9I0tLo{V?y6p^t0oHd&M%jmVSg+9`C%WYM0#P3i-Ov2KmFSih zVJ(1@>!N(2i4nG!KYRbU@MJpDbt$1n%45rha_LanN=(Y|F&BOje=Q09zVkix7edI= z3KrVB`)e&;8Qy7}r2Z?7*7AzRp`52^ zre9js+QnL6<)(tp46&&RmO$>zFK=-}lxf+1x|n*wXQ1LIk|I<5SrMZzd6Sm5DkvYLd)V%0Rl7A)BP@b!s$K;g4!&6j_sa)1A^ z%|#{3x7pq0{s_L9n}=yGI8a4ERZjD6c5hxhsp9+f*G!OwYN>N#WqQLF_p7B7QCL|) zYQHz_U$cm>F~7ctSe&-F$Mw+8CKTqW8m2@iZG)2)` ze`n!gsOChwdBeuc_%;{ZM265R3?2uh@Jj#svkGqmqS{wF|9aF|)U)j^oNY(5ODaRG z&V5Y7&;2Ry59L=A)B_*(uSxADm)yuj##AyQY2XuAjc9hdkgiu_cAcax61>7ikpB;pps# z5q~N4!oysol;F2qAxxAW+Hri%xM>n&4v}&U8&e8F-JEQ?gq(+)lA4O^U8dXf=^#Hg z0<|l|znLkCd)IAA@zlPtBB-}%N3E+OJz)qme4^ zbYoZE{-c83A?*{+9w+?v@H)8Z=0;r2Z09f(Aw;Zd$W>GE$|-8b3^wu@RefmyWi5q< zyWpSkSUaY`6$3EBuT)<;nTxs$$h&#$_cw9BOZ%@H-BI-%+SbH%Cw3OzVRD4#oDASgZ0gs?h#&E>I3SRxt zU^drrfXBNg@39U|u@p;#W&Gr{iV>`6Pc_;}SQ=;0&2==uj3c?m>28Vhl~zq%Ajm3B zoc5ysoPd(!C7XLBnac>2@vF#1nQaQ6!UvmVDFw@7HjoRbE7fIL{hqn#oVKAV5Hie& zk5Uz=noMbZYlUpyx4B#3zNUQoqwRF4DP;8Ty^26kS!jg;`&L#u zu|9@H)6v4wt`Qu(m?6+4`H7SQm4fBdcfOYUd>%N)Fyoh7m>aB4h0{Xxl- z-a;kCjQZ)n@R7fuY@x)ln>L1VyLJiE!z(i*vpye)l%idn^0zfJ{i=9By~~YRgwXvC zdn$)If6IK#8#it9;q@?vXfR^P=cIXq-{=oJ21u=s3(>y|g^H!&L*?T;*|Alh5}pI- zgr8)5o+ob*NtSt>zoXhU6OWZz#l1eJrbucU6qKRplqD`L7HSv<7`Wqp--NAMD<Z z$#>njkqM2qd+SPWp-Zg(kX_V@h5xw`gCc1KwQD1+W0{rr!c7V>N{9)^QHjKFSN3%@ zQKOwPaSCYV@eSGeC=FngMIKlpZcLmVF|TKF(j?dx+>ai!!W&R=50m@&V*)luIb9RQ zwcy-|*B^|vc-eRr#CQMyT(HL*< z=l-fRy%fp-c@K)Hp2dWi>L;c}_X>@!cuW6*zns+VX=!V}?%|4gOu36@Y4S7L%0)t9(0P(v-4zzbhvLzAaMeTVq=r6_-Dwy^N%%%v^P($WDB zrjyb52jvK@=jW$NHG?C5_3K_o4W8eb&(UxZL{;FkRI>Fju#(gol`zN&knU&Fk%rHW z>8s=_dYneZtRnxh)^xRl%NlN-YlJ3^PqAbQ3(rua2|h2MN{;sUQSpZ~zI?^Ex^1%3 zU(W7=S>0GY_4w1hLi}9uw62sOPk2P|EFC^ZY@Afmvackn0Jde4*8zLnGbIub%l!8C z9fI^j?Tqg;pW*!mtp>)zg0Nu3@Och3{#j^zfzFGmVQymCMZ?W@&V25x+U>_D1rh&1 z7SV3TRqL;di4*E!ma7@er85Cu4ei+c#H=qJaK2Ers;fCaEu9~Qj?Ex)q6R+hVqZN@K=7b z`6hX3N8K*+Mp98`qmI7*Z$yDk!L34UHJ28KUkGw?Jx~8Sn%%`}t?VaF;oiAopQSEl zFXxX?zdhtYukmI%)hAG!P}a7?#0GN-BoP3Y87H(zJ zCWzDQMdJN*791Yfa7sBOQ*hmSE!$Kmb<27lI{q?sbfbK~^Fr+K4YAY!ab#P$UiDegE$SsE1&`(Wmb^lz1N)41U3! zP6WC%a#wsZOqz_3H#$a(RsOd<>18s=EI7b=_%GX<44A<_byTwp;FXd#?VGZu{uM5c z7a=D(BfKUgutbWd*yZVX#WwOKO74(ljrf-U_r{~iM*$jz`<>rh%cN>kcR2z8?-rrLgNd&u6R+^LI~pnA4%$>jYP6&^x~_ewBTFCANE_T^Y?!BFjZ2D|u1?;^F2L~G zMWH{B&Rym7Hr^<2`mL-2`(h=ss!@&ji4sTA6N@gXj4L5x22uNH)SxD1i@V-jZpX3< zbZe>Jnt;(y@>X%txBOqxa&S_6$bd|1#`^7! z6*WDRSQy?HVs|dbgR)=n&3ydxgcWPXt1LTQi^m?0niS`~bfB-er!tACjoYxFA%?b1 z!rH?7`*CFt<#b5lKg9o7YfV5;er=MSC!)$~Apm6i1$x_RArv=p(3+5Qy>nX8!RQ zfI!08G2r)iSG`4xIrd*0S>f87jT^@GX$0m%Hn#Q!+UY{6dAk3~4&7KyX^ zr663y9+FU7W!9qOEYYWGXpyNl&k=v}4;uOlGZWiXtqC-?U+e`ti(^=grXKIV(T%9){=(=%EPjm_nefK7 zCO$GLbN<06y?Avx`wA*S#uBD#YgyZdnrBPTP@$aM#m5aTs#M5(-#lczp{OvI<*MP_ zmU+h!Cx~{gRpQ3UYq%9u`|5ILN7HaMQ4BRqrAb6OtlckI0QY5<~C0#-aHeI9!CX=IYS!xk5lK!+MTpm-`76UhPyN4Z)?~egO zW#|DMy~NGmBT)$Ba*M$)3`HT?9` zW9aTelNxr1$&$%bLdzuEA7iW{)bb~dV0&PTMyKKN7LjjrMWgMAd8@O%jU{63@jth) zc5NjkG{Fb~NdWWu`0m6{O4;*>Y6tf^o7epUjzvzn%gKD>FCXnZDOOrL2-Kxd@53F# zLEmYXHm?56#hu>Qo(sR29`lmDOM^#@8tDtOV9wmkyD(V<>N~!p){!#;h#lqonsh2} zo9th_PMcpGE_HWa25l$cgJxKYp@Acud;IjRP7d|Q^%ki6@2Aj7^xJqy6ER6 zBDds}e+$x9V#*BBsr*1pTe3Kul^T$YjmcdY;S6iG9-Z3tKh(i^u^J&h0!YRR&Qse3W65=g5paIr0_ z4l0Yth^qXOtT8BGgr`RHOU?_A6DBHH=R5omz< z7RVf#&c+z>!hvZMs)PZ$b-a?P8yv0^JS%q_SbrSt z-jd>r^NX9YC`I6n)lQ~&!hnl(NUA_7>5!I>rKG#ymyfuLkD{&2%*_9}BhdAe#KLHf zF+v_7^PxVuHjl?&cjCiY5M1V+)RCW5yGzOb!&@evR^WShx(XLI&*u776teUqt?!le z#8$U~BFV^yRpsdxq(JXn0hhl8m#bE-T0C@AX}iC6e^{K2&M7tb@||i^3i4zPsu^?J zzfyyHj8x3hKeCm`A~G7{l3TGcPBWheWdQU>>Uki{`4^#@d_9n7Vw;cosG|h3ws>~Y zbXT1>+ZV_|EVkI*+>UX-mTWU8swJ9r*n7yQvQHmDfw#&-=%BLL(!EqoQvz)C!(Z{w|B})o!r)NRitPw}`CuDT039-F!N20W*VbMop9* zr7}rPn6rjHItfM=7_iz@DsY)3)cP3}83}GuCcl*am`V%r`(CQ#kn#21kM8jIhZWQL+H3MYItukF{`cT=vOIJ1ab5lM zigJx`8i(%%BsEgi!MJBUZ?k;rq=&6r!t!4VXsEG^9f9qnYCn;!j#Jf;Q^yo7g*PI8 zekP&M#i?_sKO|bjT^U}!oaD0?N5MJ6mPyWg=gA8gcv{~0xo+}Ss#(Wce$c$Eo|IRK zh)}=U`r|ba0ZcJJWISO@D*UPd(GHBDjJbJzy>hq(*8Ukyb2F+MZ(D)>sw3h)4{>Q7 zI`xACf98X#xj73=7sVnYqzpTC^cU7R=NpOuu+DfQNw3m!cy+(&WpQQD}-lp z2(Cz)Y%{|ig&AA5ShTsYF+g(^8o>NXnxP7->@#_{n41I^x6c|dh2gQf;s1)4&z9Je z4-Yh-<0E#(nLnK658z`$<}Jt% zL_7mC*B$yM7_(_hhu=%f+xsc2_-;=V0kBwxb?QqTU#rcauDnx>-riicIeo0rnva)c zO?EkLGMmv+%&TW7W#Aj)nb=Il7KPFVts{{VIL;12w48ED*^PxK!j+ zRE%WwKbheLNi{ccy!XGPFRp2*YhWl=M(y~q?C&FaUWT0yYKbd~c2X3{uLTK6j@tHwbUH;0 zE1<8l?ml8pTtoCMHdmPR_UKW*W`Frn*#*b;aZU+IDk2My5rZw-&}^%GYQTgyUK^p=*pOM6>4H;IIb2; z3pnNbDb~*-wtu?}q<5`TW&SY_JR6PchVZ=utLHD3nr4&RY7(Dg*I;mRsXj*xkGc`f zBp0@nrOy?%X>Hs{TwqPp5g(Y0FIdp3Ys{ew}-)p}W<{DsH^$p#=4Z+63FSGSuUO8Uk-AGhIb3^)cwNLyn5o*x^&gaZ- zd>c_``p)~+@^BO}6QipWbXQq#1t(dkgX;OsyexH}zWg3?E>SS!>SWfr$ULNK^R8s8 zkQf^4#iUl1FGeYi_LT^>{)=9bu2jP4+3OY-cSahUYIJp#i$|nY6SwoKdjtk>+WbSP z87y6io8RRz^i)VMs@P2!^pHVXPLb7ShtX(6ETt6IN|j;|B#UzVP(j2%t*)hr{ld-O z*UN4oM7pYs(SlkT6+biex@$7n5=#>|anDD=*}Z8<>`EU^uR|u^RQ9vRB^ou20Pl!t z%)*iQMHuUSH5)nT3QhAP5QrCsla4ZxUKOC_Js}v1NTrji)G?far|IN6Z zT?$Pr?plX8dY^zD5<2VGaD3shW;}BJS40wt&UR<0?^*YZ(Pigj{kY=Ig6l}>X(ySg zJWs6yucXbj(zo1f(BIUh122L(nE0k3F7nPHIXjOoC2(Z2ZrK3i$?3}+zOE})aC*Po z`v*IvJ}$=Sm8*l{Z7T^$^JkFm(Sps?FjE<&fFAKyH|Hry5|!UM8f;^lM6yMx?WT|V zz9j{9NmD5UHoS53y%Fa`Zn$K31IqkZ2lsk#yF)8~HKAsf?fO}G#syNH-Wrdgf=Nc| zf~CD%>m)NoC9|kJ95pNOY`2_js-e&|bl1H9_Xgee!=7A|5wVlITNL4nloioeHQ zCFx8k;9+9%fR-)<910HpO+j%pD#K%>2g<3=xUm&txtvG(lazIX3l(T`e>a=w;UZRK zqH`dTlLBD>N0W%4Wfz~rhp+2P{(B$cv;4S`csLmuEo{{?@eX%aDWA>D(DW!#-N-qI zx+AqOQUmjIYq38>Hp60@UmBTRJH%L^y?D6C_X-8YXeYH8+ka`5Gi*JlaNPYWfqcv$ zMPb|pd=pn9$@W~a+fk5+cnN7WsCXe4(u zOCdKynK7VMX>y)=tvi(PDgf2ceyKpkTz+les^fC};-fmz`$t}V7UjDG?c$@HaX`LX_?o3BI z{3Qjam`+ky{(7}C*+0ex+qCYt+L8|U@gkCPKrTEj~NlvtE|ds_wMqe@wy%#^jeMiAL&0@__e<7(z8@jBY`KI z5%w3&E8pTGkmbjyXYikT!|bZ{;wTWco`lsASXl)C4Sc-PE%~*cyE>Q{38f`rBm}L~=5la4{KjN;IQ)pOfJG`Qe z7;A~S{&7)%c2NzxYSzvwd#kXRS%t@pQ>TeaS8IfUTOyM8d5h3e&l}^h_xg$p=AX~< zMpbZygni#)#lxZv42$7V8o@8P+R!v>Ba+|vmt@Pj`e`?&hH)}0x5FFAjeldu!8xRC z5sD688rs|A>NOk3HO4WTs3hUi2V8=>O}zYR_tM`m2q%v=iCLvDOKHlr>C3jK?g^Vu zYyY7Vq9Bg^6OBjQ@OeA9kGT|S<}Cwn)cM}JaBoyNxm)NEXz?!m@l~>{w7sa|LVp;` z_l|LN7AqgyfCoLhe&6MwJ8!(6KYeLkQ{S8IFCJ_w_E=Pw9g`Y3sDWKo{`l`clC_%bVq z|LEJg3P}FZ_yrB#7`+FW@tcj+$nka1M)%K>u+wkWwAUQVuT#`0`hL5lb149?;4oZHUi+PMt++SP4y$Ewd zO#%(uJ{qz)POkE*d+gl$gZqMf+G2^v(&OkHl7{!7qka0^d~)*4Kxbdly=FvFe`ZlX zXbfJ~36*W7H~6X6Bda&I3Uxu9mqty48mBE4jQ8K#(8Z;;67c5^InlMEsIUt-KGQ(9;PY zF$#BjwfQ-lcgg(9KaJh&;Dr}=PaQ14#a|=uo;UZt2zzOd5|p(?jzqb2PYbD{@mz-` zGL`pc4Tl)+;}W^wHqvvM2k^99IH!KPi5IL?-3%`|^alra_V{_fhH2ZNptDGfr{{Pv;QU zC6+qYqkc1G)*TWX64P2Tmcm58(#<veb~C@5d7v?vAI=q_!- zmN_Za-@p41@dV~F5=(G9xZ?!xvTUfU7Kl*X~K`)Ox5##rydw%b`e$Ox^2D{8!k&~p?=IhD~7@(u)Z7c>lVk$ zBd-)jp^#QarDWs&`kjfmBQ_jGDir{@b~(Cb%Rq%Y5`G*8i;}CprH=0>ENY#wcx0J< zi?m+F^Fgr*>XbM9)$`Z)9lXeS#26Fg2HA%Ap3S?|1A3)$JwG6|eFoH}Z}?9a-;r(2 zgMchNkSjhL7&&~I+>xW$ZU~n=7?e7*y!ZWc97GK5GAaLMpvvG(On$t@r%J(M8N{_kAw^@TQwl*hG?0#hr7O zP#$`<6aeT*An#=a1ii%pGV~u48AIwCDzli=x|^b}JX6-$@;2`wlSXA7sx*aW^L;4L z_7ngBfQ0$4xMp6C#IQnGjQ?x}Shj`TJptpIPqDCZu4n!>z?ceKqBllRpBk`&M1cSR zyo>@AY7C~&c7If;z&Piprvtq@XlxPfO9D06cme~bktSz8#wRMPn*W&yfV)S;3t7bUY$+CE61n5qactMp>z)j;)wi7sb63Zjy;eQa{OpT z)~}*S2?Zjqs~o276yd}Jyn6#~^AvH6n`j|;QV|hJN#s2Q3iJ9A?e&jD)-0c;D*$q8 zMj;~ffxuP=UNLgoy3d8#7kAdznS+Ez6}bOCzyOFeQD!C}hU&N&KL8}a?#G?i>tnwS ze)8pkPphcEW%t7w}Ue*voS3vF0)zCoHH%7oK+#^J;oTG~#C4Hzzys z@xbnRp6{dV$jZEE`6C*lpPPOzZ)PCl!1LR!7s_s;sA%)QEs@7%p@^zbx#Ol3@S-(OQ0=x`F977siOx5gH0+C==94UpUL|fd-&2EIrEhN-%DGhFWso&y422{iA!*`FF#*v6=O7owMyZfDwwP72O0S^ zkPFCrISCJMGS=^Tv|s$eklH+7uvMs0&Wj5E`+<`ZnP}{9@gkEeqsK(hjR)Ajnv^}D zC5!>^AXG5SA_iCj+HSDX6K(f1^8I`x&jFubOm&BIr>dAYjj_g|C%Agx{16 z5ut9Lwe1V&u50j)*zIg*BY@8mX@S9bj45bw)NT*-dTp2!jT@WWWYeJl$jeV;cAm+R z6Cy6#u|9^bmLCW^uMH1RZu$_fDbkRwQNUfFQ%^)Iws}=(yCy_4?d>!=xmeA4?}$DBUmsQDEEhZqL<(9 zo)fpXU(eg6UJv~4QeFlJdlIBE0$ESU(ZRfbO;ZO``(}^-Jcurt1X?P=3GH`3w!B{Z z^5N3Q))IW@S>eJ8V!PwkvdC{e@mAFFzm5~aj?UDJ8xp2ko>$20cFs|k$~6t zxaVS7eg?qgT)fL3rDqhKNv+UnyHwUN0OH5c-cXzT?2} z@I{H4cny8{%Q`)5xHHbM(G%O^QCoVBPXC~=Vb-e~@5nwF+Nvs)vC+5Xxn!2ln>QEp zm5#HU4|2Tqz%OjFGXWA+-NFi|p+ewL!&(niW(oqX+>S54Q%%D=FX2MBps-ca{&yj- zr|fn>b`$`q$|Q6y#Jk7u)$jd&80oT2edgoH+aM%zT* z!-g6sy)Y^;fb;LjJ1ZGsJS$SWc-v$3^hb|+wb0(Fpc3cH9mh*p6llF&t|>| zM6nkj<*$TR{U_je;)i>%2Wei}&dc<2WHXQf{(nsc6?*J{d!3U-I&Ap^H8-O8N1H@G zZ--Dppft|<#yTO(#ETu_vyWQ^7L!vmgn6R>TT@yHBU|{-CMSVuPNNVAyXGR}${bS(Ts^9G0LoT2j3Ve_O(i#B9m^@yT-$-*mn0Tm1oGByR zb7syFQzqY{qlX4-^2YaA2Z{rYSCH{t*(ccR^ZyxSlK=j)DgkZoA}R;KTVB7lLu|e`G~@SZ z_l4Dl;N5Kd?&d)v>zj*Upph!lfDe=JJpsrEno9)*01G&uqtoIkH<}y)-rnr^<#4_p ze+OGRjV1PE^VU29m2we@)Z$!ueNLDI81L@V<$6J_I<9!en^`_$0Z&I@uOA{cqJA$O z;1}}I#M;S`KcK8R4Q8m|6X({uokKgyQjXI7$wS8N!ZpM)pJY9Qo6xsTf zn0^54?_BB*=8Q##PSai<;@Nx9!1m~hH|T|O!|Y_FLN!2A zgR2{QWox`nOjYqsFn$$0ZkM|uZeT*51%w$)IP60XFuWEH`H4o zbYo9YLhO#55A=YA-#O=eE*XF7^vlVAHto*N2~Kn&)sF@`Gy26&q>1(@FO&QB!QM)c z{6s#g4&MBZ8-6Tm!PlMj7&fQP=Nx$S)1@}Pxp1f_%0U7xsmfV`7(<) zOLb=)(Ay*v_*qonH9~Ya9f|51`G-sr?-(;7XdW3p)*yS72ZOFe{<)`vIY4MhWDbeTh#_AWP6^ zeMUg}k|Q?Y`JVLEI{#B4EZdCTqp3b4762<~bB*sZ?^&XI?_%3MQuNg7)+MnsT0i^` zB4AOV+a%!0TEww+fc*9+CDZj>XM$+VA4FK_J1|S0SV2sg9cT5r2F*XqnC!)ZJ zKS+SxzulezUcLgi?gDn#N0R0{wB81RC_0$%0Qj9dM+{M_xc9e*gYKD;GtkXlr@SAA z4m9cevUkNY_{~p;kL}D}p}@|?V=S4SRGMC3wt*SPOdQ?$M=DR}wd4QTftQ!4}*!r`-DCW5Mj zWHYNNiSLX38=AG`@2qkWu)Qi5%+h-=CUBn^pmF8S$7I=nu@gy!8fd6P7m;VEz!N_jH2RD{&rU=CumCHuZ>4BprW9dCX#5)XEo)Vg=T^|ob1+)x zmn+_FMCerMrRubFxi`L>pz_1DjDqWpb`cpD`60|l{-0oFR`qG@`iwiw{BQoK16}<0 z{O!1;5pY3`8EA1QBMqX$OczGa^+~~==XTH7@H_B0LBFw%D8XJDr{5nRDzJ`7E7K&xHmKfkY=J~_40$C~2-3Cq0wKYS+x z0Q$&0W4TmuH|en(IIOFR*^OHMP?=KzeB}V3khY^bLWL+uf^X9=QHHp8tNLabK;6NX zr=U0@S(_~R+kAy8c52rZ^?z!wZ#{V`Hom_nUd_fsl6QyMG&<8wQQ-hP84rVk=)R^d zVVCVt60`qEgl~ZVktp(djfHMnB|2U!Mi9SRSUn>m0d}e=;5>;R#`Y*K=Ap6i%DlD5 zxGyP!0q2A;qr4!8NaA+FcmJ#=9SQxCrvvE@yggVb2{jxo(e=Iw=4Kh*iSz)OPkf1- zIKU$aaPFNv!HlR130?7l9-DmOxDHydL&M_;qJrKz-J}3WW>4TE76lrv<@2Po#ee3$ z7p~1{LIU*G;08AYi<+-EO?3Ol3WJZ$vVW{P8M$mY%uxWADPRc0Sjn=Vg%(9V82D)s zzImD*V*miYN{BVwd8~u+Hh=WlmT51 zJ&pgPp-)27_jMi)uyLM#unZ5~Y_<2QNT~FQrJkt7o zb(MFL_gCp5e5*AZg98BCd|%@c%PwCjCF)2m za|4$I17=48<}?^Ur+znVBRGiALm_+)=i7zE?`#NLF9q8muwPF4MK8TL07D)Cl4je@ zr}A;zChh(wtzJ2*h##CcV^#qR0OV+MIG<56sU;X_JHM%kkY!x-KSD`l0q^1gPql(x zCTuGHl-r88LtSW!H~_#-TvG6QS$9goG1`U`lIWghWBijOR?q-;&||U4MkDG|?84Dq zto}ajH|XpE2udT48y9K_efv9b*-cG;*0pLV1P^bl2+JM@sa3FQp)FR5^O0YxZ=ZuU z7E3|faHD{u6>u)&d{S4i+d)?#0>B$Xvo8Y|CiV>HpU!tq(sSPPO&OseopXO`3p_nT zP%z(7LSy_Z-$JVs0$TBU3il)>>XdYcK&bu)Q$81|f|Z{dT;Bvf1biWH z{foHOvhwqcV3rr^9U}KS_le|@U;1Qi9ZrC~?sqOAF5P0Jzo3()S63V{rnFZwvRurD zt#j4J=Z|88L;HHfhx3B!P4~1CfN<652EFA%MXq>NKVAu2XceGv_y7|2C7k@ z^f@vd*OC=iR1AzE9KRn*E1=E|-+jfQ=v`@d$bbC<0Cl*0(4*7;%75pM&?5FfPXGWq zc>fisk^W!#zgzkLCoi%8(dYlw@Bgk||6g7dy$}Lpz=?>yY1%cg^gl7=rB$SAB#cA; EAL3)tdH?_b literal 0 HcmV?d00001 diff --git a/assets/yacd.ico b/assets/yacd.ico new file mode 100644 index 0000000000000000000000000000000000000000..0cc77ed82b6d5f6c1fa3e400909b7ee5b86f9c6e GIT binary patch literal 181508 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%0D`5#VY!PqZcCiXSE0Nl+GPQ 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 literal 0 HcmV?d00001 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000..68ae7b1 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh +sed -i "s|http://127.0.0.1:9090|$YACD_DEFAULT_BACKEND|" /usr/share/nginx/html/index.html +nginx -g "daemon off;" diff --git a/docker/nginx-default.conf b/docker/nginx-default.conf new file mode 100644 index 0000000..3896e25 --- /dev/null +++ b/docker/nginx-default.conf @@ -0,0 +1,31 @@ +server { + listen 80; + server_name localhost; + # access_log /var/log/nginx/host.access.log main; + gzip on; + gzip_vary on; + gzip_comp_level 4; + gzip_min_length 256; + gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + location ~ assets\/.*\.(?:css|js|woff2?|svg|gif|map)$ { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + add_header Cache-Control "max-age=31536000"; + # access_log off; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..8784bea --- /dev/null +++ b/index.html @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + yacd + + +

+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..a82d42d --- /dev/null +++ b/package.json @@ -0,0 +1,100 @@ +{ + "name": "yacd", + "version": "0.3.5", + "description": "Yet another Clash dashboard", + "author": "Haishan (https://haishan.me)", + "license": "MIT", + "private": true, + "keywords": [ + "react", + "clash" + ], + "scripts": { + "dev": "vite", + "start": "vite", + "build": "vite build", + "serve": "vite preview", + "prepare": "husky install" + }, + "dependencies": { + "@reach/tooltip": "0.18.0", + "@reach/visually-hidden": "0.18.0", + "clsx": "^1.2.1", + "history": "5.3.0", + "invariant": "^2.2.4", + "lodash-es": "^4.17.21", + "memoize-one": "6.0.0", + "modern-normalize": "1.1.0", + "prop-types": "15.8.1", + "react-feather": "^2.0.10", + "react-modal": "3.16.1", + "react-tabs": "6.0.0", + "react-tiny-fab": "4.0.4", + "react-window": "^1.8.8", + "regenerator-runtime": "0.13.11", + "tslib": "2.4.1", + "use-asset": "1.0.4" + }, + "devDependencies": { + "@babel/runtime": "7.20.13", + "@fontsource/inter": "4.5.15", + "@fontsource/roboto-mono": "4.5.10", + "@types/invariant": "2.2.35", + "@types/jest": "29.4.0", + "@types/lodash-es": "4.17.6", + "@types/react": "18.0.27", + "@types/react-dom": "18.0.10", + "@types/react-modal": "3.13.1", + "@types/react-window": "1.8.5", + "@typescript-eslint/eslint-plugin": "5.49.0", + "@typescript-eslint/parser": "5.49.0", + "@vitejs/plugin-react": "3.0.1", + "autoprefixer": "10.4.13", + "chart.js": "4.2.0", + "core-js": "3.27.2", + "cssnano": "5.1.14", + "date-fns": "2.29.3", + "eslint": "8.32.0", + "eslint-config-airbnb-base": "15.0.0", + "eslint-config-prettier": "8.6.0", + "eslint-config-react-app": "7.0.1", + "eslint-plugin-flowtype": "8.0.3", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-jest": "27.2.1", + "eslint-plugin-jsx-a11y": "6.7.1", + "eslint-plugin-react": "7.32.1", + "eslint-plugin-react-hooks": "4.6.0", + "eslint-plugin-simple-import-sort": "9.0.0", + "framer-motion": "8.5.3", + "husky": "^8.0.3", + "i18next": "22.4.9", + "i18next-browser-languagedetector": "7.0.1", + "i18next-http-backend": "2.1.1", + "immer": "9.0.18", + "lint-staged": "^13.1.0", + "postcss": "8.4.21", + "postcss-preset-env": "^8.0.0", + "prettier": "2.8.3", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-i18next": "12.1.4", + "react-icons": "4.7.1", + "react-query": "3.39.3", + "react-router": "6.8.0", + "react-router-dom": "6.8.0", + "react-switch": "7.0.0", + "react-table": "7.8.0", + "recoil": "0.7.6", + "reselect": "4.1.7", + "resize-observer-polyfill": "^1.5.1", + "sass": "1.57.1", + "typescript": "4.9.4", + "vite": "4.0.4", + "vite-plugin-pwa": "0.14.1", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..e253ade --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,7350 @@ +lockfileVersion: 5.4 + +specifiers: + '@babel/runtime': 7.20.13 + '@fontsource/inter': 4.5.15 + '@fontsource/roboto-mono': 4.5.10 + '@reach/tooltip': 0.18.0 + '@reach/visually-hidden': 0.18.0 + '@types/invariant': 2.2.35 + '@types/jest': 29.4.0 + '@types/lodash-es': 4.17.6 + '@types/react': 18.0.27 + '@types/react-dom': 18.0.10 + '@types/react-modal': 3.13.1 + '@types/react-window': 1.8.5 + '@typescript-eslint/eslint-plugin': 5.49.0 + '@typescript-eslint/parser': 5.49.0 + '@vitejs/plugin-react': 3.0.1 + autoprefixer: 10.4.13 + chart.js: 4.2.0 + clsx: ^1.2.1 + core-js: 3.27.2 + cssnano: 5.1.14 + date-fns: 2.29.3 + eslint: 8.32.0 + eslint-config-airbnb-base: 15.0.0 + eslint-config-prettier: 8.6.0 + eslint-config-react-app: 7.0.1 + eslint-plugin-flowtype: 8.0.3 + eslint-plugin-import: 2.27.5 + eslint-plugin-jest: 27.2.1 + eslint-plugin-jsx-a11y: 6.7.1 + eslint-plugin-react: 7.32.1 + eslint-plugin-react-hooks: 4.6.0 + eslint-plugin-simple-import-sort: 9.0.0 + framer-motion: 8.5.3 + history: 5.3.0 + husky: ^8.0.3 + i18next: 22.4.9 + i18next-browser-languagedetector: 7.0.1 + i18next-http-backend: 2.1.1 + immer: 9.0.18 + invariant: ^2.2.4 + lint-staged: ^13.1.0 + lodash-es: ^4.17.21 + memoize-one: 6.0.0 + modern-normalize: 1.1.0 + postcss: 8.4.21 + postcss-preset-env: ^8.0.0 + prettier: 2.8.3 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0 + react-feather: ^2.0.10 + react-i18next: 12.1.4 + react-icons: 4.7.1 + react-modal: 3.16.1 + react-query: 3.39.3 + react-router: 6.8.0 + react-router-dom: 6.8.0 + react-switch: 7.0.0 + react-table: 7.8.0 + react-tabs: 6.0.0 + react-tiny-fab: 4.0.4 + react-window: ^1.8.8 + recoil: 0.7.6 + regenerator-runtime: 0.13.11 + reselect: 4.1.7 + resize-observer-polyfill: ^1.5.1 + sass: 1.57.1 + tslib: 2.4.1 + typescript: 4.9.4 + use-asset: 1.0.4 + vite: 4.0.4 + vite-plugin-pwa: 0.14.1 + workbox-core: 6.5.4 + workbox-expiration: 6.5.4 + workbox-precaching: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + +dependencies: + '@reach/tooltip': 0.18.0_biqbaboplfbrettd7655fr4n2y + '@reach/visually-hidden': 0.18.0_biqbaboplfbrettd7655fr4n2y + clsx: 1.2.1 + history: 5.3.0 + invariant: 2.2.4 + lodash-es: 4.17.21 + memoize-one: 6.0.0 + modern-normalize: 1.1.0 + prop-types: 15.8.1 + react-feather: 2.0.10_react@18.2.0 + react-modal: 3.16.1_biqbaboplfbrettd7655fr4n2y + react-tabs: 6.0.0_react@18.2.0 + react-tiny-fab: 4.0.4_react@18.2.0 + react-window: 1.8.8_biqbaboplfbrettd7655fr4n2y + regenerator-runtime: 0.13.11 + tslib: 2.4.1 + use-asset: 1.0.4_react@18.2.0 + +devDependencies: + '@babel/runtime': 7.20.13 + '@fontsource/inter': 4.5.15 + '@fontsource/roboto-mono': 4.5.10 + '@types/invariant': 2.2.35 + '@types/jest': 29.4.0 + '@types/lodash-es': 4.17.6 + '@types/react': 18.0.27 + '@types/react-dom': 18.0.10 + '@types/react-modal': 3.13.1 + '@types/react-window': 1.8.5 + '@typescript-eslint/eslint-plugin': 5.49.0_iu322prlnwsygkcra5kbpy22si + '@typescript-eslint/parser': 5.49.0_7uibuqfxkfaozanbtbziikiqje + '@vitejs/plugin-react': 3.0.1_vite@4.0.4 + autoprefixer: 10.4.13_postcss@8.4.21 + chart.js: 4.2.0 + core-js: 3.27.2 + cssnano: 5.1.14_postcss@8.4.21 + date-fns: 2.29.3 + eslint: 8.32.0 + eslint-config-airbnb-base: 15.0.0_ps7hf4l2dvbuxvtusmrfhmzsba + eslint-config-prettier: 8.6.0_eslint@8.32.0 + eslint-config-react-app: 7.0.1_7uibuqfxkfaozanbtbziikiqje + eslint-plugin-flowtype: 8.0.3_eslint@8.32.0 + eslint-plugin-import: 2.27.5_6savw6y3b7jng6f64kgkyoij64 + eslint-plugin-jest: 27.2.1_sa4tfo476gi7rdzbz5wa2vwvhe + eslint-plugin-jsx-a11y: 6.7.1_eslint@8.32.0 + eslint-plugin-react: 7.32.1_eslint@8.32.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.32.0 + eslint-plugin-simple-import-sort: 9.0.0_eslint@8.32.0 + framer-motion: 8.5.3_biqbaboplfbrettd7655fr4n2y + husky: 8.0.3 + i18next: 22.4.9 + i18next-browser-languagedetector: 7.0.1 + i18next-http-backend: 2.1.1 + immer: 9.0.18 + lint-staged: 13.1.0 + postcss: 8.4.21 + postcss-preset-env: 8.0.0_postcss@8.4.21 + prettier: 2.8.3 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-i18next: 12.1.4_iakk3dtjhjpukdoa4oua5khgci + react-icons: 4.7.1_react@18.2.0 + react-query: 3.39.3_biqbaboplfbrettd7655fr4n2y + react-router: 6.8.0_react@18.2.0 + react-router-dom: 6.8.0_biqbaboplfbrettd7655fr4n2y + react-switch: 7.0.0_biqbaboplfbrettd7655fr4n2y + react-table: 7.8.0_react@18.2.0 + recoil: 0.7.6_biqbaboplfbrettd7655fr4n2y + reselect: 4.1.7 + resize-observer-polyfill: 1.5.1 + sass: 1.57.1 + typescript: 4.9.4 + vite: 4.0.4_sass@1.57.1 + vite-plugin-pwa: 0.14.1_vite@4.0.4 + workbox-core: 6.5.4 + workbox-expiration: 6.5.4 + workbox-precaching: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + +packages: + + /@ampproject/remapping/2.2.0: + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.1.1 + '@jridgewell/trace-mapping': 0.3.16 + dev: true + + /@apideck/better-ajv-errors/0.3.6_ajv@8.11.0: + resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} + engines: {node: '>=10'} + peerDependencies: + ajv: '>=8' + dependencies: + ajv: 8.11.0 + json-schema: 0.4.0 + jsonpointer: 5.0.1 + leven: 3.1.0 + dev: true + + /@babel/code-frame/7.18.6: + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + dev: true + + /@babel/compat-data/7.19.4: + resolution: {integrity: sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/compat-data/7.20.10: + resolution: {integrity: sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core/7.19.3: + resolution: {integrity: sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.4 + '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.3 + '@babel/helper-module-transforms': 7.19.0 + '@babel/helpers': 7.19.4 + '@babel/parser': 7.19.4 + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.4 + '@babel/types': 7.19.4 + convert-source-map: 1.8.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/core/7.20.12: + resolution: {integrity: sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.7 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helpers': 7.20.13 + '@babel/parser': 7.20.13 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 + convert-source-map: 1.8.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/eslint-parser/7.19.1_7zv64ewctsjhrlqbm3wep2xela: + resolution: {integrity: sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==} + engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} + peerDependencies: + '@babel/core': '>=7.11.0' + eslint: ^7.5.0 || ^8.0.0 + dependencies: + '@babel/core': 7.19.3 + '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 + eslint: 8.32.0 + eslint-visitor-keys: 2.1.0 + semver: 6.3.0 + dev: true + + /@babel/generator/7.19.4: + resolution: {integrity: sha512-5T2lY5vXqS+5UEit/5TwcIUeCnwgCljcF8IQRT6XRQPBrvLeq5V8W+URv+GvwoF3FP8tkhp++evVyDzkDGzNmA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + dev: true + + /@babel/generator/7.20.7: + resolution: {integrity: sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure/7.18.6: + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: + resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-explode-assignable-expression': 7.18.6 + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-compilation-targets/7.19.3_@babel+core@7.19.3: + resolution: {integrity: sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.19.4 + '@babel/core': 7.19.3 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + semver: 6.3.0 + dev: true + + /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12: + resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.20.10 + '@babel/core': 7.20.12 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + lru-cache: 5.1.1 + semver: 6.3.0 + dev: true + + /@babel/helper-create-class-features-plugin/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-member-expression-to-functions': 7.18.9 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-split-export-declaration': 7.18.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-create-regexp-features-plugin/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-annotate-as-pure': 7.18.6 + regexpu-core: 5.2.1 + dev: true + + /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.20.12: + resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} + peerDependencies: + '@babel/core': ^7.4.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor/7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-explode-assignable-expression/7.18.6: + resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-function-name/7.19.0: + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.20.7 + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-hoist-variables/7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-member-expression-to-functions/7.18.9: + resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-module-imports/7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-module-transforms/7.19.0: + resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.19.4 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-transforms/7.20.11: + resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.20.2 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-optimise-call-expression/7.18.6: + resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-plugin-utils/7.19.0: + resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-wrap-function': 7.19.0 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-replace-supers/7.19.1: + resolution: {integrity: sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-member-expression-to-functions': 7.18.9 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access/7.19.4: + resolution: {integrity: sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-simple-access/7.20.2: + resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers/7.18.9: + resolution: {integrity: sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-split-export-declaration/7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/helper-string-parser/7.19.4: + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option/7.18.6: + resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function/7.19.0: + resolution: {integrity: sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.19.0 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers/7.19.4: + resolution: {integrity: sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers/7.20.13: + resolution: {integrity: sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.13 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight/7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser/7.19.4: + resolution: {integrity: sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/parser/7.20.13: + resolution: {integrity: sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-async-generator-functions/7.19.1_@babel+core@7.20.12: + resolution: {integrity: sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-decorators/7.19.3_@babel+core@7.20.12: + resolution: {integrity: sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/plugin-syntax-decorators': 7.19.0_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-logical-assignment-operators/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-object-rest-spread/7.19.4_@babel+core@7.20.12: + resolution: {integrity: sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.10 + '@babel/core': 7.20.12 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-optional-chaining/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.12 + dev: true + + /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-private-property-in-object/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.12: + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.12: + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.12: + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-decorators/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.12: + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.12: + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-flow/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-import-assertions/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.12: + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.12: + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.12: + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.12: + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.12: + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.12: + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.12: + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.12: + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.12: + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-typescript/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-block-scoping/7.19.4_@babel+core@7.20.12: + resolution: {integrity: sha512-934S2VLLlt2hRJwPf4MczaOr4hYF0z+VKPwqTNxyKX7NthTiPfhuKFWQZHXRM0vh/wo/VyXB3s4bZUNA08l+tQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-classes/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-split-export-declaration': 7.18.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-computed-properties/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-destructuring/7.19.4_@babel+core@7.20.12: + resolution: {integrity: sha512-t0j0Hgidqf0aM86dF8U+vXYReUgJnlv4bZLsyoPnwZNrGY+7/38o8YjaELrvHeVfTZao15kjR0PVv0nju2iduA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-flow-strip-types/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-flow': 7.18.6_@babel+core@7.20.12 + dev: true + + /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.12: + resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-literals/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-modules-amd/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helper-plugin-utils': 7.19.0 + babel-plugin-dynamic-import-node: 2.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-simple-access': 7.20.2 + babel-plugin-dynamic-import-node: 2.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-systemjs/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-validator-identifier': 7.19.1 + babel-plugin-dynamic-import-node: 2.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helper-plugin-utils': 7.19.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex/7.19.1_@babel+core@7.20.12: + resolution: {integrity: sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-replace-supers': 7.19.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-parameters/7.18.8_@babel+core@7.20.12: + resolution: {integrity: sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.12 + dev: true + + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.12: + resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.12 + '@babel/types': 7.20.7 + dev: true + + /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-regenerator/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + regenerator-transform: 0.15.0 + dev: true + + /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-runtime/7.19.1_@babel+core@7.20.12: + resolution: {integrity: sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.19.0 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.12 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.12 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.12 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-spread/7.19.0_@babel+core@7.20.12: + resolution: {integrity: sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 + dev: true + + /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-typescript/7.19.3_@babel+core@7.20.12: + resolution: {integrity: sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.20.12: + resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/preset-env/7.19.4_@babel+core@7.20.12: + resolution: {integrity: sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.19.4 + '@babel/core': 7.20.12 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-validator-option': 7.18.6 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-proposal-async-generator-functions': 7.19.1_@babel+core@7.20.12 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-logical-assignment-operators': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-object-rest-spread': 7.19.4_@babel+core@7.20.12 + '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.12 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.12 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.12 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-syntax-import-assertions': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.12 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.12 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.12 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.12 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.12 + '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-block-scoping': 7.19.4_@babel+core@7.20.12 + '@babel/plugin-transform-classes': 7.19.0_@babel+core@7.20.12 + '@babel/plugin-transform-computed-properties': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-transform-destructuring': 7.19.4_@babel+core@7.20.12 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.12 + '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-modules-amd': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-modules-commonjs': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-modules-systemjs': 7.19.0_@babel+core@7.20.12 + '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-named-capturing-groups-regex': 7.19.1_@babel+core@7.20.12 + '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-parameters': 7.18.8_@babel+core@7.20.12 + '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-regenerator': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-spread': 7.19.0_@babel+core@7.20.12 + '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.20.12 + '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.12 + '@babel/preset-modules': 0.1.5_@babel+core@7.20.12 + '@babel/types': 7.20.7 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.12 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.12 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.12 + core-js-compat: 3.25.5 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules/0.1.5_@babel+core@7.20.12: + resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.12 + '@babel/types': 7.20.7 + esutils: 2.0.3 + dev: true + + /@babel/preset-react/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-validator-option': 7.18.6 + '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.12 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-react-pure-annotations': 7.18.6_@babel+core@7.20.12 + dev: true + + /@babel/preset-typescript/7.18.6_@babel+core@7.20.12: + resolution: {integrity: sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-validator-option': 7.18.6 + '@babel/plugin-transform-typescript': 7.19.3_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/runtime/7.20.13: + resolution: {integrity: sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + + /@babel/template/7.18.10: + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.20.13 + '@babel/types': 7.20.7 + dev: true + + /@babel/template/7.20.7: + resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.20.13 + '@babel/types': 7.20.7 + dev: true + + /@babel/traverse/7.19.4: + resolution: {integrity: sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.7 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.20.13 + '@babel/types': 7.20.7 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/traverse/7.20.13: + resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.7 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.20.13 + '@babel/types': 7.20.7 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types/7.19.4: + resolution: {integrity: sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + dev: true + + /@babel/types/7.20.7: + resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + dev: true + + /@csstools/cascade-layer-name-parser/1.0.0_jhntdqzgrqlkpxki6fy253alji: + resolution: {integrity: sha512-JxdLxJMDximX1vxCFJdwC7MD4aXNSFbOxBZuYKg2FEz4MLR0UFVmamPtzthzqzxAcU0K6ShvEFfMBrEEb16U+A==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-parser-algorithms': ^2.0.0 + '@csstools/css-tokenizer': ^2.0.0 + dependencies: + '@csstools/css-parser-algorithms': 2.0.0_wcbxa2wg3evugsqpd27xwuyb6a + '@csstools/css-tokenizer': 2.0.0 + dev: true + + /@csstools/css-parser-algorithms/1.0.0_yc2lywpo4a5sk4h3mmwqkmetvu: + resolution: {integrity: sha512-lPphY34yfV15tEXiz/SYaU8hwqAhbAwqiTExv5tOfc7QZxT70VVYrsiPBaX1osdWZFowrDEAhHe4H3JnyzbjhA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-tokenizer': ^1.0.0 + dependencies: + '@csstools/css-tokenizer': 1.0.0 + dev: true + + /@csstools/css-parser-algorithms/2.0.0_wcbxa2wg3evugsqpd27xwuyb6a: + resolution: {integrity: sha512-RbukP8OjQvuH85veuzOq8abPjsvqvleZaQC6W0GJFGpwLUh8XmFMQjvtuIM9bQ589YFx4lwwAcSwN4nfcvxIEw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-tokenizer': ^2.0.0 + dependencies: + '@csstools/css-tokenizer': 2.0.0 + dev: true + + /@csstools/css-tokenizer/1.0.0: + resolution: {integrity: sha512-xdFjdQ+zqqkOsmee+kYRieZD9Cqh4hr01YBQ2/8NtTkMMxbtRX18MC50LX6cMrtaLryqmIdZHN9e16/l0QqnQw==} + engines: {node: ^14 || ^16 || >=18} + dev: true + + /@csstools/css-tokenizer/2.0.0: + resolution: {integrity: sha512-IB6EFP0Hc/YEz1sJVD47oFqJP6TXMB+OW1jXSYnOk5g+6wpk2/zkuBa0gm5edIMM9nVUZ3hF0xCBnyFbK5OIyg==} + engines: {node: ^14 || ^16 || >=18} + dev: true + + /@csstools/media-query-list-parser/1.0.0_oycmb73qbeg4xspzoh5ywrqikm: + resolution: {integrity: sha512-HsTj5ejI8NKKZ4IEd6kK2kQZA/JmIVlUV8+XvO/YS9ntrlYPnbmFT3rkqtbxOVfEafblYCNOpeNw1c+fKGkAqw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-parser-algorithms': ^1.0.0 + '@csstools/css-tokenizer': ^1.0.0 + dependencies: + '@csstools/css-parser-algorithms': 1.0.0_yc2lywpo4a5sk4h3mmwqkmetvu + '@csstools/css-tokenizer': 1.0.0 + dev: true + + /@csstools/media-query-list-parser/2.0.0_jhntdqzgrqlkpxki6fy253alji: + resolution: {integrity: sha512-84kEbyJjh2T4Lnz8EkVQrwNANP+dtNb0SDkI3P7kqKnGorPknQUuq8Iqf2v5UsaH08XzPp3ouVJNsyPOdI2B/Q==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-parser-algorithms': ^2.0.0 + '@csstools/css-tokenizer': ^2.0.0 + dependencies: + '@csstools/css-parser-algorithms': 2.0.0_wcbxa2wg3evugsqpd27xwuyb6a + '@csstools/css-tokenizer': 2.0.0 + dev: true + + /@csstools/postcss-cascade-layers/3.0.0_postcss@8.4.21: + resolution: {integrity: sha512-CpjItl5zYoROgc3f7+ptPOXJr0sFDf+0CUEmwQMd/JOAmpP9scXtAWvoFwkFKIjBDE6swqbamjIMwmYVCBL6rg==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/selector-specificity': 2.1.0_jwkxkvlpbeeukrxssifiwvrjeq + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /@csstools/postcss-color-function/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-rB3Ur+Ns2aOEBMz3zFyjmU6uBBGko84yRD1G6Re/v2p1GRzjz8/o738syQLoxRb1TNcND0YsiKoUeaRuwfk9yw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/postcss-progressive-custom-properties': 2.0.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-font-format-keywords/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-/ew2ScjfoN4dBWhs3CQhVp47VPVO4MVzTdpjygiW9bXj3e2MyoMXuWoBksA1LdREMh5UhrEjBmtwFIx7R2oVIA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-hwb-function/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-1rXMiRapGL6tQJsGKzvEY78DSDc4lZXQzPkHwRBuwoJvRAdtXWQyR00Jk73TOFkmVtmo5bdbS6Rnm1f01lpmlg==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-ic-unit/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-R120sQLhdNFH1K3cBpTLAwqu41L9r9BF5K+6tWMMbCpSiUXhNcYCJWbghf2546No9HBiWGL8YLZabsuaHKAEKg==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/postcss-progressive-custom-properties': 2.0.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-is-pseudo-class/3.0.0_postcss@8.4.21: + resolution: {integrity: sha512-rz3Ch3gxMeOdMDppuikEmlI3jhnkQd/OM/xAmSjPeCfhYPy37BlNTgsxpaPVizkhkMOfibH/eMkzeXNbXdBBXw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/selector-specificity': 2.1.0_jwkxkvlpbeeukrxssifiwvrjeq + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /@csstools/postcss-logical-float-and-clear/1.0.0_postcss@8.4.21: + resolution: {integrity: sha512-duwyZx5NHEi3DYtk8vTnZ/QwxXYIm7OaXPEfDflbwEIlpB1wNbY9m7TnLT4vZRPv6yAxHEDoHJXS/Zj36mC7uw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + dev: true + + /@csstools/postcss-logical-resize/1.0.0_postcss@8.4.21: + resolution: {integrity: sha512-gsySHNBxhHI76I0MmoHz+OJ+EWlEl7TQFKdpRmKG0bfdYZVZaAexAHXLulJL3Tp3ifcD0ev9fSsIPYGeKTx2qA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-logical-viewport-units/1.0.1_postcss@8.4.21: + resolution: {integrity: sha512-KAZyurROvdd0oFsD33LBXQYq15r25MOpPnpSsZvnPnPIFM0I9XL0EDPILgKiRRQbdjx0SvCWRtxtT4BiOkxpig==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/css-tokenizer': 2.0.0 + postcss: 8.4.21 + dev: true + + /@csstools/postcss-media-queries-aspect-ratio-number-values/1.0.0_postcss@8.4.21: + resolution: {integrity: sha512-gC5RQSI/42TbaOdPZoObcL4lhLYggBzTp/PTypcmLMp8JLPQdlJq2Ys0t8pxfDw98GvsHZahUbhPxJaebbCT1w==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/css-parser-algorithms': 1.0.0_yc2lywpo4a5sk4h3mmwqkmetvu + '@csstools/css-tokenizer': 1.0.0 + '@csstools/media-query-list-parser': 1.0.0_oycmb73qbeg4xspzoh5ywrqikm + postcss: 8.4.21 + dev: true + + /@csstools/postcss-nested-calc/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-omq/2O2ZENbCa/UY9i6uo4MloNMXZg/lqMv0utOwlNFUgdrpMdnDKWcNRiHV5OvlOnvg188MRyzHwQjqapbJ7w==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-normalize-display-values/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-mN5ycsvVkPjt81fVo33p142imrhSBN3LAvvuP6qfkQ6C3452IWO1ZcbYQ/QYcYBymChsmbXmk1jQNZ2kZOFZag==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-oklab-function/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-PONCTLUqo0GFGG+adf6ZUJt7icC8s1SYxC18S9AQhRAGp4m9Fe9EnpaJofikCuZYHkrxr8ngh6D1mSHwA9aryQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/postcss-progressive-custom-properties': 2.0.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-progressive-custom-properties/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-jQl/sQRcMwgaWWzmy65LtxVWnSvRFnhnaRVCvHaMLf5ZT2LRE5w3EG7Z4FqV6IK4L/vB/GSZSzl8AEA9CXN8Zg==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-scope-pseudo-class/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-YvsluKH7w/R86BLDl9urwpMUc5PAdeRdrWj20AcHCmr9+2FdsIuWZxYWnof6kNdVYGpK1ox7lXXuCz06VBowPw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /@csstools/postcss-stepped-value-functions/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-6PWwbiolpSx9Lbmdq39wvt9XKYjWlnIq5cRkAKrZA1lJsL09GRmYdwjYjBuESe6mrkysOED4CIMwEJ+EbginLA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-text-decoration-shorthand/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-+Ce+VVbEj2/TJUGUULiMyC/30JruYpCcADwWSW8kLUoO35XWQWQW09MCRFhTS50AHvIuzYG8lZ5TeFXuVAt/uw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-trigonometric-functions/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-T7SZreVZUX0b2m3+X25Bp7cW2eJWfsCm40NoERSZPxsW6He8zuz+Hx6opOVelMyoM8YvYIBOFns8eNCHX7WL/Q==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /@csstools/postcss-unset-value/2.0.0_postcss@8.4.21: + resolution: {integrity: sha512-dx15RWSMlYsgtcl4YkVOe7Rd8tEEx8AEBnxpURI7AQa4dDJC3utZWD3am4Ynx2aoGu5C5lMF/RvSA3+uRpHPXw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + dev: true + + /@csstools/selector-specificity/2.1.0_jwkxkvlpbeeukrxssifiwvrjeq: + resolution: {integrity: sha512-zJ6hb3FDgBbO8d2e83vg6zq7tNvDqSq9RwdwfzJ8tdm9JHNvANq2fqwyRn6mlpUb7CwTs5ILdUrGwi9Gk4vY5w==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + postcss-selector-parser: ^6.0.10 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /@emotion/is-prop-valid/0.8.8: + resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} + requiresBuild: true + dependencies: + '@emotion/memoize': 0.7.4 + dev: true + optional: true + + /@emotion/memoize/0.7.4: + resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} + dev: true + optional: true + + /@esbuild/android-arm/0.16.17: + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.16.17: + resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.16.17: + resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.16.17: + resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.16.17: + resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.16.17: + resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.16.17: + resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.16.17: + resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.16.17: + resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.16.17: + resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64/0.16.17: + resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.16.17: + resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.16.17: + resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.16.17: + resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.16.17: + resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.16.17: + resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.16.17: + resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.16.17: + resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.16.17: + resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.16.17: + resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.16.17: + resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.16.17: + resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint/eslintrc/1.4.1: + resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.4.0 + globals: 13.19.0 + ignore: 5.2.0 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@fontsource/inter/4.5.15: + resolution: {integrity: sha512-FzleM9AxZQK2nqsTDtBiY0PMEVWvnKnuu2i09+p6DHvrHsuucoV2j0tmw+kAT3L4hvsLdAIDv6MdGehsPIdT+Q==} + dev: true + + /@fontsource/roboto-mono/4.5.10: + resolution: {integrity: sha512-KrJdmkqz6DszT2wV/bbhXef4r0hV3B0vw2mAqei8A2kRnvq+gcJLmmIeQ94vu9VEXrUQzos5M9lH1TAAXpRphw==} + dev: true + + /@humanwhocodes/config-array/0.11.8: + resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer/1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema/1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@jest/expect-utils/29.1.2: + resolution: {integrity: sha512-4a48bhKfGj/KAH39u0ppzNTABXQ8QPccWAFUFobWBaEMSMp+sB31Z2fK/l47c4a/Mu1po2ffmfAIPxXbVTXdtg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.0.0 + dev: true + + /@jest/schemas/29.0.0: + resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.24.44 + dev: true + + /@jest/types/29.1.2: + resolution: {integrity: sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.0.0 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 18.8.3 + '@types/yargs': 17.0.13 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping/0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@jridgewell/gen-mapping/0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.16 + dev: true + + /@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array/1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map/0.3.2: + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} + dependencies: + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.16 + dev: true + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/trace-mapping/0.3.16: + resolution: {integrity: sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@kurkle/color/0.3.2: + resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==} + dev: true + + /@motionone/animation/10.15.1: + resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==} + dependencies: + '@motionone/easing': 10.15.1 + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + tslib: 2.4.1 + dev: true + + /@motionone/dom/10.15.5: + resolution: {integrity: sha512-Xc5avlgyh3xukU9tydh9+8mB8+2zAq+WlLsC3eEIp7Ax7DnXgY7Bj/iv0a4X2R9z9ZFZiaXK3BO0xMYHKbAAdA==} + dependencies: + '@motionone/animation': 10.15.1 + '@motionone/generators': 10.15.1 + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + hey-listen: 1.0.8 + tslib: 2.4.1 + dev: true + + /@motionone/easing/10.15.1: + resolution: {integrity: sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==} + dependencies: + '@motionone/utils': 10.15.1 + tslib: 2.4.1 + dev: true + + /@motionone/generators/10.15.1: + resolution: {integrity: sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==} + dependencies: + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + tslib: 2.4.1 + dev: true + + /@motionone/types/10.15.1: + resolution: {integrity: sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==} + dev: true + + /@motionone/utils/10.15.1: + resolution: {integrity: sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==} + dependencies: + '@motionone/types': 10.15.1 + hey-listen: 1.0.8 + tslib: 2.4.1 + dev: true + + /@nicolo-ribaudo/eslint-scope-5-internals/5.1.1-v1: + resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} + dependencies: + eslint-scope: 5.1.1 + dev: true + + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + dev: true + + /@reach/auto-id/0.18.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-XwY1IwhM7mkHZFghhjiqjQ6dstbOdpbFLdggeke75u8/8icT8uEHLbovFUgzKjy9qPvYwZIB87rLiR8WdtOXCg==} + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + dependencies: + '@reach/utils': 0.18.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@reach/observe-rect/1.2.0: + resolution: {integrity: sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==} + dev: false + + /@reach/polymorphic/0.18.0_react@18.2.0: + resolution: {integrity: sha512-N9iAjdMbE//6rryZZxAPLRorzDcGBnluf7YQij6XDLiMtfCj1noa7KyLpEc/5XCIB/EwhX3zCluFAwloBKdblA==} + peerDependencies: + react: ^16.8.0 || 17.x + dependencies: + react: 18.2.0 + dev: false + + /@reach/portal/0.18.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-TImozRapd576ofRk30Le2L3lRTFXF1p47B182wnp5eMTdZa74JX138BtNGEPJFOyrMaVmguVF8SSwZ6a0fon1Q==} + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + dependencies: + '@reach/utils': 0.18.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@reach/rect/0.18.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-Xk8urN4NLn3F70da/DtByMow83qO6DF6vOxpLjuDBqud+kjKgxAU9vZMBSZJyH37+F8mZinRnHyXtlLn5njQOg==} + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + dependencies: + '@reach/observe-rect': 1.2.0 + '@reach/utils': 0.18.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@reach/tooltip/0.18.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-yugoTmTjB3qoMk/nUvcnw99MqpyE2TQMOXE29qnQhSqHriRwQhfftjXlTAGTSzsUJmbyms3A/1gQW0X61kjFZw==} + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + dependencies: + '@reach/auto-id': 0.18.0_biqbaboplfbrettd7655fr4n2y + '@reach/polymorphic': 0.18.0_react@18.2.0 + '@reach/portal': 0.18.0_biqbaboplfbrettd7655fr4n2y + '@reach/rect': 0.18.0_biqbaboplfbrettd7655fr4n2y + '@reach/utils': 0.18.0_biqbaboplfbrettd7655fr4n2y + '@reach/visually-hidden': 0.18.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@reach/utils/0.18.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A==} + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + dependencies: + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@reach/visually-hidden/0.18.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-NsJ3oeHJtPc6UOeV6MHMuzQ5sl1ouKhW85i3C0S7VM+klxVlYScBZ2J4UVnWB50A2c+evdVpCnld2YeuyYYwBw==} + peerDependencies: + react: ^16.8.0 || 17.x || 18.x + react-dom: ^16.8.0 || 17.x || 18.x + dependencies: + '@reach/polymorphic': 0.18.0_react@18.2.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@remix-run/router/1.3.1: + resolution: {integrity: sha512-+eun1Wtf72RNRSqgU7qM2AMX/oHp+dnx7BHk1qhK5ZHzdHTUU4LA1mGG1vT+jMc8sbhG3orvsfOmryjzx2PzQw==} + engines: {node: '>=14'} + dev: true + + /@rollup/plugin-babel/5.3.1_3dsfpkpoyvuuxyfgdbpn4j4uzm: + resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} + engines: {node: '>= 10.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-module-imports': 7.18.6 + '@rollup/pluginutils': 3.1.0_rollup@2.79.1 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-node-resolve/11.2.1_rollup@2.79.1: + resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.79.1 + '@types/resolve': 1.17.1 + builtin-modules: 3.3.0 + deepmerge: 4.2.2 + is-module: 1.0.0 + resolve: 1.22.1 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-replace/2.4.2_rollup@2.79.1: + resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.79.1 + magic-string: 0.25.9 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-replace/5.0.2_rollup@3.11.0: + resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2_rollup@3.11.0 + magic-string: 0.27.0 + rollup: 3.11.0 + dev: true + + /@rollup/pluginutils/3.1.0_rollup@2.79.1: + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils/5.0.2_rollup@3.11.0: + resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.0 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 3.11.0 + dev: true + + /@rushstack/eslint-patch/1.2.0: + resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} + dev: true + + /@sinclair/typebox/0.24.44: + resolution: {integrity: sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==} + dev: true + + /@surma/rollup-plugin-off-main-thread/2.2.3: + resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} + dependencies: + ejs: 3.1.8 + json5: 2.2.3 + magic-string: 0.25.9 + string.prototype.matchall: 4.0.8 + dev: true + + /@trysound/sax/0.2.0: + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + dev: true + + /@types/estree/0.0.39: + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + dev: true + + /@types/estree/1.0.0: + resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} + dev: true + + /@types/invariant/2.2.35: + resolution: {integrity: sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==} + dev: true + + /@types/istanbul-lib-coverage/2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true + + /@types/istanbul-reports/3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/jest/29.4.0: + resolution: {integrity: sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==} + dependencies: + expect: 29.1.2 + pretty-format: 29.1.2 + dev: true + + /@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: true + + /@types/json5/0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/lodash-es/4.17.6: + resolution: {integrity: sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==} + dependencies: + '@types/lodash': 4.14.186 + dev: true + + /@types/lodash/4.14.186: + resolution: {integrity: sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==} + dev: true + + /@types/node/18.8.3: + resolution: {integrity: sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==} + dev: true + + /@types/parse-json/4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + dev: true + + /@types/prop-types/15.7.5: + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + dev: true + + /@types/react-dom/18.0.10: + resolution: {integrity: sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==} + dependencies: + '@types/react': 18.0.27 + dev: true + + /@types/react-modal/3.13.1: + resolution: {integrity: sha512-iY/gPvTDIy6Z+37l+ibmrY+GTV4KQTHcCyR5FIytm182RQS69G5ps4PH2FxtC7bAQ2QRHXMevsBgck7IQruHNg==} + dependencies: + '@types/react': 18.0.27 + dev: true + + /@types/react-window/1.8.5: + resolution: {integrity: sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==} + dependencies: + '@types/react': 18.0.27 + dev: true + + /@types/react/18.0.27: + resolution: {integrity: sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 + csstype: 3.1.1 + dev: true + + /@types/resolve/1.17.1: + resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} + dependencies: + '@types/node': 18.8.3 + dev: true + + /@types/scheduler/0.16.2: + resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} + dev: true + + /@types/semver/7.3.13: + resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} + dev: true + + /@types/stack-utils/2.0.1: + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true + + /@types/trusted-types/2.0.2: + resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==} + dev: true + + /@types/yargs-parser/21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs/17.0.13: + resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + + /@typescript-eslint/eslint-plugin/5.49.0_iu322prlnwsygkcra5kbpy22si: + resolution: {integrity: sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.49.0_7uibuqfxkfaozanbtbziikiqje + '@typescript-eslint/scope-manager': 5.49.0 + '@typescript-eslint/type-utils': 5.49.0_7uibuqfxkfaozanbtbziikiqje + '@typescript-eslint/utils': 5.49.0_7uibuqfxkfaozanbtbziikiqje + debug: 4.3.4 + eslint: 8.32.0 + ignore: 5.2.0 + natural-compare-lite: 1.4.0 + regexpp: 3.2.0 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/experimental-utils/5.39.0_7uibuqfxkfaozanbtbziikiqje: + resolution: {integrity: sha512-n5N9kG/oGu2xXhHzsWzn94s6CWoiUj59FPU2dF2IQZxPftw+q6Jm5sV2vj5qTgAElRooHhrgtl2gxBQDCPt6WA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@typescript-eslint/utils': 5.39.0_7uibuqfxkfaozanbtbziikiqje + eslint: 8.32.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/parser/5.49.0_7uibuqfxkfaozanbtbziikiqje: + resolution: {integrity: sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.49.0 + '@typescript-eslint/types': 5.49.0 + '@typescript-eslint/typescript-estree': 5.49.0_typescript@4.9.4 + debug: 4.3.4 + eslint: 8.32.0 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager/5.39.0: + resolution: {integrity: sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.39.0 + '@typescript-eslint/visitor-keys': 5.39.0 + dev: true + + /@typescript-eslint/scope-manager/5.49.0: + resolution: {integrity: sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.49.0 + '@typescript-eslint/visitor-keys': 5.49.0 + dev: true + + /@typescript-eslint/type-utils/5.49.0_7uibuqfxkfaozanbtbziikiqje: + resolution: {integrity: sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 5.49.0_typescript@4.9.4 + '@typescript-eslint/utils': 5.49.0_7uibuqfxkfaozanbtbziikiqje + debug: 4.3.4 + eslint: 8.32.0 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types/5.39.0: + resolution: {integrity: sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/types/5.49.0: + resolution: {integrity: sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.39.0_typescript@4.9.4: + resolution: {integrity: sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.39.0 + '@typescript-eslint/visitor-keys': 5.39.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree/5.49.0_typescript@4.9.4: + resolution: {integrity: sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.49.0 + '@typescript-eslint/visitor-keys': 5.49.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.39.0_7uibuqfxkfaozanbtbziikiqje: + resolution: {integrity: sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@typescript-eslint/scope-manager': 5.39.0 + '@typescript-eslint/types': 5.39.0 + '@typescript-eslint/typescript-estree': 5.39.0_typescript@4.9.4 + eslint: 8.32.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.32.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/utils/5.49.0_7uibuqfxkfaozanbtbziikiqje: + resolution: {integrity: sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@types/semver': 7.3.13 + '@typescript-eslint/scope-manager': 5.49.0 + '@typescript-eslint/types': 5.49.0 + '@typescript-eslint/typescript-estree': 5.49.0_typescript@4.9.4 + eslint: 8.32.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.32.0 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys/5.39.0: + resolution: {integrity: sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.39.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /@typescript-eslint/visitor-keys/5.49.0: + resolution: {integrity: sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.49.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /@vitejs/plugin-react/3.0.1_vite@4.0.4: + resolution: {integrity: sha512-mx+QvYwIbbpOIJw+hypjnW1lAbKDHtWK5ibkF/V1/oMBu8HU/chb+SnqJDAsLq1+7rGqjktCEomMTM5KShzUKQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + dependencies: + '@babel/core': 7.20.12 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12 + magic-string: 0.27.0 + react-refresh: 0.14.0 + vite: 4.0.4_sass@1.57.1 + transitivePeerDependencies: + - supports-color + dev: true + + /acorn-jsx/5.3.2_acorn@8.8.0: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.8.0 + dev: true + + /acorn/8.8.0: + resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /aggregate-error/3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv/8.11.0: + resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-escapes/4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles/5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles/6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /anymatch/3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /argparse/2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /aria-query/5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + dependencies: + deep-equal: 2.2.0 + dev: true + + /array-includes/3.1.6: + resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + get-intrinsic: 1.1.3 + is-string: 1.0.7 + dev: true + + /array-union/2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.flat/1.3.1: + resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.flatmap/1.3.1: + resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.tosorted/1.1.1: + resolution: {integrity: sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + es-shim-unscopables: 1.0.0 + get-intrinsic: 1.1.3 + dev: true + + /ast-types-flow/0.0.7: + resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} + dev: true + + /astral-regex/2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /async/3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + dev: true + + /at-least-node/1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + dev: true + + /autoprefixer/10.4.13_postcss@8.4.21: + resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.21.4 + caniuse-lite: 1.0.30001448 + fraction.js: 4.2.0 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /available-typed-arrays/1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /axe-core/4.6.3: + resolution: {integrity: sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==} + engines: {node: '>=4'} + dev: true + + /axobject-query/3.1.1: + resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} + dependencies: + deep-equal: 2.2.0 + dev: true + + /babel-plugin-dynamic-import-node/2.3.3: + resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} + dependencies: + object.assign: 4.1.4 + dev: true + + /babel-plugin-macros/3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + dependencies: + '@babel/runtime': 7.20.13 + cosmiconfig: 7.0.1 + resolve: 1.22.1 + dev: true + + /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.20.12: + resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.10 + '@babel/core': 7.20.12 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.12 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.20.12: + resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.12 + core-js-compat: 3.25.5 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.20.12: + resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.12 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-transform-react-remove-prop-types/0.4.24: + resolution: {integrity: sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==} + dev: true + + /babel-preset-react-app/10.0.1: + resolution: {integrity: sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==} + dependencies: + '@babel/core': 7.20.12 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-decorators': 7.19.3_@babel+core@7.20.12 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.12 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-flow-strip-types': 7.19.0_@babel+core@7.20.12 + '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-runtime': 7.19.1_@babel+core@7.20.12 + '@babel/preset-env': 7.19.4_@babel+core@7.20.12 + '@babel/preset-react': 7.18.6_@babel+core@7.20.12 + '@babel/preset-typescript': 7.18.6_@babel+core@7.20.12 + '@babel/runtime': 7.20.13 + babel-plugin-macros: 3.1.0 + babel-plugin-transform-react-remove-prop-types: 0.4.24 + transitivePeerDependencies: + - supports-color + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /big-integer/1.6.51: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} + engines: {node: '>=0.6'} + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /boolbase/1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion/2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /broadcast-channel/3.7.0: + resolution: {integrity: sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==} + dependencies: + '@babel/runtime': 7.20.13 + detect-node: 2.1.0 + js-sha3: 0.8.0 + microseconds: 0.2.0 + nano-time: 1.0.0 + oblivious-set: 1.0.0 + rimraf: 3.0.2 + unload: 2.2.0 + dev: true + + /browserslist/4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001448 + electron-to-chromium: 1.4.276 + node-releases: 2.0.6 + update-browserslist-db: 1.0.10_browserslist@4.21.4 + dev: true + + /buffer-from/1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /builtin-modules/3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.3 + dev: true + + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /caniuse-api/3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + dependencies: + browserslist: 4.21.4 + caniuse-lite: 1.0.30001448 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + dev: true + + /caniuse-lite/1.0.30001448: + resolution: {integrity: sha512-tq2YI+MJnooG96XpbTRYkBxLxklZPOdLmNIOdIhvf7SNJan6u5vCKum8iT7ZfCt70m1GPkuC7P3TtX6UuhupuA==} + dev: true + + /chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chart.js/4.2.0: + resolution: {integrity: sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==} + engines: {pnpm: ^7.0.0} + dependencies: + '@kurkle/color': 0.3.2 + dev: true + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /ci-info/3.5.0: + resolution: {integrity: sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==} + dev: true + + /clean-stack/2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-cursor/3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-truncate/2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + dev: true + + /cli-truncate/3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.1.2 + dev: true + + /clsx/1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + dev: false + + /color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /colord/2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + dev: true + + /colorette/2.0.19: + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} + dev: true + + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander/7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: true + + /commander/9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /common-tags/1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /confusing-browser-globals/1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + dev: true + + /convert-source-map/1.8.0: + resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /core-js-compat/3.25.5: + resolution: {integrity: sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==} + dependencies: + browserslist: 4.21.4 + dev: true + + /core-js/3.27.2: + resolution: {integrity: sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w==} + requiresBuild: true + dev: true + + /cosmiconfig/7.0.1: + resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + + /cross-fetch/3.1.5: + resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} + dependencies: + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: true + + /cross-spawn/7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypto-random-string/2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: true + + /css-blank-pseudo/5.0.0_postcss@8.4.21: + resolution: {integrity: sha512-2QwvERc+e7bWoO6Cva1goJR3r/qe2opbizEWpWEtKAxW9KDpEovI2Y8M2UgqoEVQyPAsWJwWnBpSpItqvjveoQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /css-declaration-sorter/6.3.1_postcss@8.4.21: + resolution: {integrity: sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==} + engines: {node: ^10 || ^12 || >=14} + peerDependencies: + postcss: ^8.0.9 + dependencies: + postcss: 8.4.21 + dev: true + + /css-has-pseudo/5.0.0_postcss@8.4.21: + resolution: {integrity: sha512-vFe2z1/y8xG3JiJCAMOoCCXCwSbG2ndQJqFVVaFHoSuaEmvni8VNuFTC9IAYmqJU7c5elPEXJm40i/x5Zk0GSQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/selector-specificity': 2.1.0_jwkxkvlpbeeukrxssifiwvrjeq + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + postcss-value-parser: 4.2.0 + dev: true + + /css-prefers-color-scheme/8.0.0_postcss@8.4.21: + resolution: {integrity: sha512-Fb6GOyJRTI3YZ1v0ySi/X+at+ImRGgySsHvAXYsFo62aTa+ClaMi8E9R/oQmJmD8WPpNHgZXQ1nhkXbCCCne3g==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + dev: true + + /css-select/4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + dev: true + + /css-tree/1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + dev: true + + /css-what/6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: true + + /cssdb/7.4.1: + resolution: {integrity: sha512-0Q8NOMpXJ3iTDDbUv9grcmQAfdDx4qz+fN/+Md2FGbevT+6+bJNQ2LjB2YIUlLbpBTM32idU1Sb+tb/uGt6/XQ==} + dev: true + + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /cssnano-preset-default/5.2.13_postcss@8.4.21: + resolution: {integrity: sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + css-declaration-sorter: 6.3.1_postcss@8.4.21 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-calc: 8.2.4_postcss@8.4.21 + postcss-colormin: 5.3.0_postcss@8.4.21 + postcss-convert-values: 5.1.3_postcss@8.4.21 + postcss-discard-comments: 5.1.2_postcss@8.4.21 + postcss-discard-duplicates: 5.1.0_postcss@8.4.21 + postcss-discard-empty: 5.1.1_postcss@8.4.21 + postcss-discard-overridden: 5.1.0_postcss@8.4.21 + postcss-merge-longhand: 5.1.7_postcss@8.4.21 + postcss-merge-rules: 5.1.3_postcss@8.4.21 + postcss-minify-font-values: 5.1.0_postcss@8.4.21 + postcss-minify-gradients: 5.1.1_postcss@8.4.21 + postcss-minify-params: 5.1.4_postcss@8.4.21 + postcss-minify-selectors: 5.2.1_postcss@8.4.21 + postcss-normalize-charset: 5.1.0_postcss@8.4.21 + postcss-normalize-display-values: 5.1.0_postcss@8.4.21 + postcss-normalize-positions: 5.1.1_postcss@8.4.21 + postcss-normalize-repeat-style: 5.1.1_postcss@8.4.21 + postcss-normalize-string: 5.1.0_postcss@8.4.21 + postcss-normalize-timing-functions: 5.1.0_postcss@8.4.21 + postcss-normalize-unicode: 5.1.1_postcss@8.4.21 + postcss-normalize-url: 5.1.0_postcss@8.4.21 + postcss-normalize-whitespace: 5.1.1_postcss@8.4.21 + postcss-ordered-values: 5.1.3_postcss@8.4.21 + postcss-reduce-initial: 5.1.1_postcss@8.4.21 + postcss-reduce-transforms: 5.1.0_postcss@8.4.21 + postcss-svgo: 5.1.0_postcss@8.4.21 + postcss-unique-selectors: 5.1.1_postcss@8.4.21 + dev: true + + /cssnano-utils/3.1.0_postcss@8.4.21: + resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /cssnano/5.1.14_postcss@8.4.21: + resolution: {integrity: sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + cssnano-preset-default: 5.2.13_postcss@8.4.21 + lilconfig: 2.0.6 + postcss: 8.4.21 + yaml: 1.10.2 + dev: true + + /csso/4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + dependencies: + css-tree: 1.1.3 + dev: true + + /csstype/3.1.1: + resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + dev: true + + /damerau-levenshtein/1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + + /date-fns/2.29.3: + resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} + engines: {node: '>=0.11'} + dev: true + + /debug/3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deep-equal/2.2.0: + resolution: {integrity: sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==} + dependencies: + call-bind: 1.0.2 + es-get-iterator: 1.1.3 + get-intrinsic: 1.1.3 + is-arguments: 1.1.1 + is-array-buffer: 3.0.1 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + isarray: 2.0.5 + object-is: 1.1.5 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.4.3 + side-channel: 1.0.4 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.9 + dev: true + + /deep-is/0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge/4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: true + + /define-properties/1.1.4: + resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /detect-node/2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + dev: true + + /diff-sequences/29.0.0: + resolution: {integrity: sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /dir-glob/3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine/2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine/3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dom-serializer/1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + dev: true + + /domelementtype/2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + + /domhandler/4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: true + + /domutils/2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + dev: true + + /eastasianwidth/0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /ejs/3.1.8: + resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.8.5 + dev: true + + /electron-to-chromium/1.4.276: + resolution: {integrity: sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ==} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emoji-regex/9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /entities/2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + dev: true + + /error-ex/1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract/1.20.4: + resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + es-to-primitive: 1.2.1 + function-bind: 1.1.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.1.3 + get-symbol-description: 1.0.0 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-symbols: 1.0.3 + internal-slot: 1.0.3 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-weakref: 1.0.2 + object-inspect: 1.12.2 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.4.3 + safe-regex-test: 1.0.0 + string.prototype.trimend: 1.0.5 + string.prototype.trimstart: 1.0.5 + unbox-primitive: 1.0.2 + dev: true + + /es-get-iterator/1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.2 + is-set: 2.0.2 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + dev: true + + /es-shim-unscopables/1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive/1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild/0.16.17: + resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.16.17 + '@esbuild/android-arm64': 0.16.17 + '@esbuild/android-x64': 0.16.17 + '@esbuild/darwin-arm64': 0.16.17 + '@esbuild/darwin-x64': 0.16.17 + '@esbuild/freebsd-arm64': 0.16.17 + '@esbuild/freebsd-x64': 0.16.17 + '@esbuild/linux-arm': 0.16.17 + '@esbuild/linux-arm64': 0.16.17 + '@esbuild/linux-ia32': 0.16.17 + '@esbuild/linux-loong64': 0.16.17 + '@esbuild/linux-mips64el': 0.16.17 + '@esbuild/linux-ppc64': 0.16.17 + '@esbuild/linux-riscv64': 0.16.17 + '@esbuild/linux-s390x': 0.16.17 + '@esbuild/linux-x64': 0.16.17 + '@esbuild/netbsd-x64': 0.16.17 + '@esbuild/openbsd-x64': 0.16.17 + '@esbuild/sunos-x64': 0.16.17 + '@esbuild/win32-arm64': 0.16.17 + '@esbuild/win32-ia32': 0.16.17 + '@esbuild/win32-x64': 0.16.17 + dev: true + + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp/2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escape-string-regexp/4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-airbnb-base/15.0.0_ps7hf4l2dvbuxvtusmrfhmzsba: + resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.2 + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 8.32.0 + eslint-plugin-import: 2.27.5_6savw6y3b7jng6f64kgkyoij64 + object.assign: 4.1.4 + object.entries: 1.1.5 + semver: 6.3.0 + dev: true + + /eslint-config-prettier/8.6.0_eslint@8.32.0: + resolution: {integrity: sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.32.0 + dev: true + + /eslint-config-react-app/7.0.1_7uibuqfxkfaozanbtbziikiqje: + resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==} + engines: {node: '>=14.0.0'} + peerDependencies: + eslint: ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@babel/core': 7.19.3 + '@babel/eslint-parser': 7.19.1_7zv64ewctsjhrlqbm3wep2xela + '@rushstack/eslint-patch': 1.2.0 + '@typescript-eslint/eslint-plugin': 5.49.0_iu322prlnwsygkcra5kbpy22si + '@typescript-eslint/parser': 5.49.0_7uibuqfxkfaozanbtbziikiqje + babel-preset-react-app: 10.0.1 + confusing-browser-globals: 1.0.11 + eslint: 8.32.0 + eslint-plugin-flowtype: 8.0.3_eslint@8.32.0 + eslint-plugin-import: 2.27.5_6savw6y3b7jng6f64kgkyoij64 + eslint-plugin-jest: 25.7.0_sa4tfo476gi7rdzbz5wa2vwvhe + eslint-plugin-jsx-a11y: 6.7.1_eslint@8.32.0 + eslint-plugin-react: 7.32.1_eslint@8.32.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.32.0 + eslint-plugin-testing-library: 5.7.2_7uibuqfxkfaozanbtbziikiqje + typescript: 4.9.4 + transitivePeerDependencies: + - '@babel/plugin-syntax-flow' + - '@babel/plugin-transform-react-jsx' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + dev: true + + /eslint-import-resolver-node/0.3.7: + resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} + dependencies: + debug: 3.2.7 + is-core-module: 2.11.0 + resolve: 1.22.1 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils/2.7.4_cnxxylyx37asr43xy64ejg3pwe: + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.49.0_7uibuqfxkfaozanbtbziikiqje + debug: 3.2.7 + eslint: 8.32.0 + eslint-import-resolver-node: 0.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-flowtype/8.0.3_eslint@8.32.0: + resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@babel/plugin-syntax-flow': ^7.14.5 + '@babel/plugin-transform-react-jsx': ^7.14.9 + eslint: ^8.1.0 + dependencies: + eslint: 8.32.0 + lodash: 4.17.21 + string-natural-compare: 3.0.1 + dev: true + + /eslint-plugin-import/2.27.5_6savw6y3b7jng6f64kgkyoij64: + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.49.0_7uibuqfxkfaozanbtbziikiqje + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.32.0 + eslint-import-resolver-node: 0.3.7 + eslint-module-utils: 2.7.4_cnxxylyx37asr43xy64ejg3pwe + has: 1.0.3 + is-core-module: 2.11.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.1 + semver: 6.3.0 + tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jest/25.7.0_sa4tfo476gi7rdzbz5wa2vwvhe: + resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^4.0.0 || ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 5.49.0_iu322prlnwsygkcra5kbpy22si + '@typescript-eslint/experimental-utils': 5.39.0_7uibuqfxkfaozanbtbziikiqje + eslint: 8.32.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-jest/27.2.1_sa4tfo476gi7rdzbz5wa2vwvhe: + resolution: {integrity: sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 5.49.0_iu322prlnwsygkcra5kbpy22si + '@typescript-eslint/utils': 5.49.0_7uibuqfxkfaozanbtbziikiqje + eslint: 8.32.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-jsx-a11y/6.7.1_eslint@8.32.0: + resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + '@babel/runtime': 7.20.13 + aria-query: 5.1.3 + array-includes: 3.1.6 + array.prototype.flatmap: 1.3.1 + ast-types-flow: 0.0.7 + axe-core: 4.6.3 + axobject-query: 3.1.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.32.0 + has: 1.0.3 + jsx-ast-utils: 3.3.3 + language-tags: 1.0.5 + minimatch: 3.1.2 + object.entries: 1.1.6 + object.fromentries: 2.0.6 + semver: 6.3.0 + dev: true + + /eslint-plugin-react-hooks/4.6.0_eslint@8.32.0: + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.32.0 + dev: true + + /eslint-plugin-react/7.32.1_eslint@8.32.0: + resolution: {integrity: sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.6 + array.prototype.flatmap: 1.3.1 + array.prototype.tosorted: 1.1.1 + doctrine: 2.1.0 + eslint: 8.32.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.3 + minimatch: 3.1.2 + object.entries: 1.1.6 + object.fromentries: 2.0.6 + object.hasown: 1.1.2 + object.values: 1.1.6 + prop-types: 15.8.1 + resolve: 2.0.0-next.4 + semver: 6.3.0 + string.prototype.matchall: 4.0.8 + dev: true + + /eslint-plugin-simple-import-sort/9.0.0_eslint@8.32.0: + resolution: {integrity: sha512-PtrLjyXP8kjRneWT1n0b99y/2Fyup37we7FVoWsI61/O7x4ztLohzhep/pxI/cYlECr/cQ2j6utckdvWpVwXNA==} + peerDependencies: + eslint: '>=5.0.0' + dependencies: + eslint: 8.32.0 + dev: true + + /eslint-plugin-testing-library/5.7.2_7uibuqfxkfaozanbtbziikiqje: + resolution: {integrity: sha512-0ZmHeR/DUUgEzW8rwUBRWxuqntipDtpvxK0hymdHnLlABryJkzd+CAHr+XnISaVsTisZ5MLHp6nQF+8COHLLTA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} + peerDependencies: + eslint: ^7.5.0 || ^8.0.0 + dependencies: + '@typescript-eslint/utils': 5.49.0_7uibuqfxkfaozanbtbziikiqje + eslint: 8.32.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope/7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils/3.0.0_eslint@8.32.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.32.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys/2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys/3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint/8.32.0: + resolution: {integrity: sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint/eslintrc': 1.4.1 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.32.0 + eslint-visitor-keys: 3.3.0 + espree: 9.4.0 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.19.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.0 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.1.5 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + regexpp: 3.2.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree/9.4.0: + resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.0 + acorn-jsx: 5.3.2_acorn@8.8.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /esquery/1.4.0: + resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse/5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker/1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + dev: true + + /estree-walker/2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /execa/6.1.0: + resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 3.0.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + dev: true + + /exenv/1.2.2: + resolution: {integrity: sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==} + dev: false + + /expect/29.1.2: + resolution: {integrity: sha512-AuAGn1uxva5YBbBlXb+2JPxJRuemZsmlGcapPXWNSBNsQtAULfjioREGBWuI0EOvYUKjDnrCy8PW5Zlr1md5mw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.1.2 + jest-get-type: 29.0.0 + jest-matcher-utils: 29.1.2 + jest-message-util: 29.1.2 + jest-util: 29.1.2 + dev: true + + /fast-deep-equal/3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-glob/3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein/2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq/1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-entry-cache/6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /filelist/1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + dependencies: + minimatch: 5.1.0 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up/5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache/3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + rimraf: 3.0.2 + dev: true + + /flatted/3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + + /for-each/0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /fraction.js/4.2.0: + resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + dev: true + + /framer-motion/8.5.3_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-CkQHhGlldJptI0SGjmjUzseXCzi0lljDkToE7cANHRCs12F5I84ymdWvCi6HfIKkt6Ykq2RiDd3dGuYV0oMn2w==} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + dependencies: + '@motionone/dom': 10.15.5 + hey-listen: 1.0.8 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + tslib: 2.4.1 + optionalDependencies: + '@emotion/is-prop-valid': 0.8.8 + dev: true + + /fs-extra/9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.10 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name/1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names/1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-intrinsic/1.1.3: + resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + + /get-own-enumerable-property-symbols/3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + dev: true + + /get-stream/6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-symbol-description/1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent/6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals/13.19.0: + resolution: {integrity: sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globby/11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.2.12 + ignore: 5.2.0 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd/1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.1.3 + dev: true + + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /grapheme-splitter/1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /hamt_plus/1.0.2: + resolution: {integrity: sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA==} + dev: true + + /has-bigints/1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag/3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors/1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.1.3 + dev: true + + /has-symbols/1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag/1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /hey-listen/1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + dev: true + + /history/5.3.0: + resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==} + dependencies: + '@babel/runtime': 7.20.13 + dev: false + + /html-parse-stringify/3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + dependencies: + void-elements: 3.1.0 + dev: true + + /human-signals/3.0.1: + resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==} + engines: {node: '>=12.20.0'} + dev: true + + /husky/8.0.3: + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /i18next-browser-languagedetector/7.0.1: + resolution: {integrity: sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==} + dependencies: + '@babel/runtime': 7.20.13 + dev: true + + /i18next-http-backend/2.1.1: + resolution: {integrity: sha512-jByfUCDVgQ8+/Wens7queQhYYvMcGTW/lR4IJJNEDDXnmqjLrwi8ubXKpmp76/JIWEZHffNdWqnxFJcTVGeaOw==} + dependencies: + cross-fetch: 3.1.5 + transitivePeerDependencies: + - encoding + dev: true + + /i18next/22.4.9: + resolution: {integrity: sha512-8gWMmUz460KJDQp/ob3MNUX84cVuDRY9PLFPnV8d+Qezz/6dkjxwOaH70xjrCNDO+JrUL25iXfAIN9wUkInNZw==} + dependencies: + '@babel/runtime': 7.20.13 + dev: true + + /idb/7.1.0: + resolution: {integrity: sha512-Wsk07aAxDsntgYJY4h0knZJuTxM73eQ4reRAO+Z1liOh8eMCJ/MoDS8fCui1vGT9mnjtl1sOu3I2i/W1swPYZg==} + dev: true + + /ignore/5.2.0: + resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} + engines: {node: '>= 4'} + dev: true + + /immer/9.0.18: + resolution: {integrity: sha512-eAPNpsj7Ax1q6Y/3lm2PmlwRcFzpON7HSNQ3ru5WQH1/PSpnyed/HpNOELl2CxLKoj4r+bAHgdyKqW5gc2Se1A==} + dev: true + + /immutable/4.1.0: + resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} + dev: true + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash/0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string/4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /internal-slot/1.0.3: + resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.3 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /internal-slot/1.0.4: + resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.3 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /invariant/2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /is-arguments/1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-array-buffer/3.0.1: + resolution: {integrity: sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + is-typed-array: 1.1.10 + dev: true + + /is-arrayish/0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint/1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object/1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable/1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module/2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object/1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-fullwidth-code-point/4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-map/2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + + /is-module/1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + dev: true + + /is-negative-zero/2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object/1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj/1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-path-inside/3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-regex/1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-regexp/1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-set/2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + + /is-shared-array-buffer/1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream/2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-stream/3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string/1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol/1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array/1.1.10: + resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /is-weakmap/2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + + /is-weakref/1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-weakset/2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + dev: true + + /isarray/2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe/2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /jake/10.8.5: + resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.4 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: true + + /jest-diff/29.1.2: + resolution: {integrity: sha512-4GQts0aUopVvecIT4IwD/7xsBaMhKTYoM4/njE/aVw9wpw+pIUVp8Vab/KnSzSilr84GnLBkaP3JLDnQYCKqVQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.0.0 + jest-get-type: 29.0.0 + pretty-format: 29.1.2 + dev: true + + /jest-get-type/29.0.0: + resolution: {integrity: sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-matcher-utils/29.1.2: + resolution: {integrity: sha512-MV5XrD3qYSW2zZSHRRceFzqJ39B2z11Qv0KPyZYxnzDHFeYZGJlgGi0SW+IXSJfOewgJp/Km/7lpcFT+cgZypw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.1.2 + jest-get-type: 29.0.0 + pretty-format: 29.1.2 + dev: true + + /jest-message-util/29.1.2: + resolution: {integrity: sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.18.6 + '@jest/types': 29.1.2 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 29.1.2 + slash: 3.0.0 + stack-utils: 2.0.5 + dev: true + + /jest-util/29.1.2: + resolution: {integrity: sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.1.2 + '@types/node': 18.8.3 + chalk: 4.1.2 + ci-info: 3.5.0 + graceful-fs: 4.2.10 + picomatch: 2.3.1 + dev: true + + /jest-worker/26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 18.8.3 + merge-stream: 2.0.0 + supports-color: 7.2.0 + dev: true + + /js-sdsl/4.1.5: + resolution: {integrity: sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==} + dev: true + + /js-sha3/0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + dev: true + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc/0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse/1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-schema/0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + + /json-stable-stringify-without-jsonify/1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5/1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.6 + dev: true + + /json5/2.2.1: + resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json5/2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonfile/6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.10 + dev: true + + /jsonpointer/5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + dev: true + + /jsx-ast-utils/3.3.3: + resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.6 + object.assign: 4.1.4 + dev: true + + /language-subtag-registry/0.3.22: + resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + dev: true + + /language-tags/1.0.5: + resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} + dependencies: + language-subtag-registry: 0.3.22 + dev: true + + /leven/3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /levn/0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig/2.0.6: + resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns/1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /lint-staged/13.1.0: + resolution: {integrity: sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + cli-truncate: 3.1.0 + colorette: 2.0.19 + commander: 9.5.0 + debug: 4.3.4 + execa: 6.1.0 + lilconfig: 2.0.6 + listr2: 5.0.7 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-inspect: 1.12.2 + pidtree: 0.6.0 + string-argv: 0.3.1 + yaml: 2.2.1 + transitivePeerDependencies: + - enquirer + - supports-color + dev: true + + /listr2/5.0.7: + resolution: {integrity: sha512-MD+qXHPmtivrHIDRwPYdfNkrzqDiuaKU/rfBcec3WMyMF3xylQj3jMq344OtvQxz7zaCFViRAeqlr2AFhPvXHw==} + engines: {node: ^14.13.1 || >=16.0.0} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.19 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.3.0 + rxjs: 7.8.0 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + + /locate-path/6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash-es/4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + + /lodash.debounce/4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.memoize/4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + dev: true + + /lodash.merge/4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.sortby/4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + + /lodash.uniq/4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + dev: true + + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-update/4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + + /loose-envify/1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + + /lru-cache/5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /magic-string/0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /magic-string/0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /match-sorter/6.3.1: + resolution: {integrity: sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==} + dependencies: + '@babel/runtime': 7.20.13 + remove-accents: 0.4.2 + dev: true + + /mdn-data/2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + dev: true + + /memoize-one/5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + dev: false + + /memoize-one/6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + dev: false + + /merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /microseconds/0.2.0: + resolution: {integrity: sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==} + dev: true + + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-fn/4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch/5.1.0: + resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist/1.2.6: + resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + dev: true + + /modern-normalize/1.1.0: + resolution: {integrity: sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==} + engines: {node: '>=6'} + dev: false + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms/2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /nano-time/1.0.0: + resolution: {integrity: sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==} + dependencies: + big-integer: 1.6.51 + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /natural-compare-lite/1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare/1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /node-fetch/2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-releases/2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-range/0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-url/6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + dev: true + + /npm-run-path/5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + + /nth-check/2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-inspect/1.12.2: + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + + /object-is/1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + dev: true + + /object-keys/1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign/4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries/1.1.5: + resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /object.entries/1.1.6: + resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /object.fromentries/2.0.6: + resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /object.hasown/1.1.2: + resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} + dependencies: + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /object.values/1.1.6: + resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /oblivious-set/1.0.0: + resolution: {integrity: sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==} + dev: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /onetime/6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator/0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /p-limit/3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate/5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map/4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-json/5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.18.6 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists/4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-key/4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pidtree/0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /postcss-attribute-case-insensitive/6.0.0_postcss@8.4.21: + resolution: {integrity: sha512-Bi5tVYe9rKjU1k1v9xzAAZqMzUrlb2sVbRyV7ZDdtLJVpxV+6db5Yd6ESe6CMl09brexIfDUrGPVB1IbVc7bQQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-calc/8.2.4_postcss@8.4.21: + resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} + peerDependencies: + postcss: ^8.2.2 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-clamp/4.1.0_postcss@8.4.21: + resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} + engines: {node: '>=7.6.0'} + peerDependencies: + postcss: ^8.4.6 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-color-functional-notation/5.0.0_postcss@8.4.21: + resolution: {integrity: sha512-oxsPSdf6i2DJyNj24/hvQDaTyoztDwG0TMannHGUnFAdA6xSwB8Io5iDDqZcDrXTJTy32erpG9ETmwhMPPuCNg==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-color-hex-alpha/9.0.0_postcss@8.4.21: + resolution: {integrity: sha512-NdIN7IzYadBApUm+wULJR03746sKliIrmRIdjHF6GaUCztsDdcq4L9wtYz5X3mw/t08mjZx8ld5By6StB+1lLQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-color-rebeccapurple/8.0.0_postcss@8.4.21: + resolution: {integrity: sha512-K0PT/ZNEYva+jIlueaI8OUPL59SfPThflYe/htggUKaS6ydiimPmtvrFb8OsTJHcQ6QUPcIySTZdFNmdnEITQg==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-colormin/5.3.0_postcss@8.4.21: + resolution: {integrity: sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.4 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-convert-values/5.1.3_postcss@8.4.21: + resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.4 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-custom-media/9.1.0_postcss@8.4.21: + resolution: {integrity: sha512-K9sIQhdsXazHyhHaMIL/wztFV6ABHi6NwxNPO3q0o0T2zkI4oEqI1TjeoncBKIY6xPrqnWTV40KF8AJ7yd0W6g==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/cascade-layer-name-parser': 1.0.0_jhntdqzgrqlkpxki6fy253alji + '@csstools/css-parser-algorithms': 2.0.0_wcbxa2wg3evugsqpd27xwuyb6a + '@csstools/css-tokenizer': 2.0.0 + '@csstools/media-query-list-parser': 2.0.0_jhntdqzgrqlkpxki6fy253alji + postcss: 8.4.21 + dev: true + + /postcss-custom-properties/13.1.0_postcss@8.4.21: + resolution: {integrity: sha512-O0Lg0CuHwADctEMBgGtaeams7eFES8pXo/9zBClTbRVdU3LFAkFluw1l9eYnJ3rtidp80EGbAIuiisEIu1Z+uA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/cascade-layer-name-parser': 1.0.0_jhntdqzgrqlkpxki6fy253alji + '@csstools/css-parser-algorithms': 2.0.0_wcbxa2wg3evugsqpd27xwuyb6a + '@csstools/css-tokenizer': 2.0.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-custom-selectors/7.1.0_postcss@8.4.21: + resolution: {integrity: sha512-83a8lfR+3tWotHDGGPSadPB0oqBieqi62EhdBe7Qo+eW/aEst7xjq2fXH+dUy8KVEFcM3jobXMYJnSo6omcVHA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/cascade-layer-name-parser': 1.0.0_jhntdqzgrqlkpxki6fy253alji + '@csstools/css-parser-algorithms': 2.0.0_wcbxa2wg3evugsqpd27xwuyb6a + '@csstools/css-tokenizer': 2.0.0 + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-dir-pseudo-class/7.0.0_postcss@8.4.21: + resolution: {integrity: sha512-i8I6vqB0T0fpanLBjFoMPp3iTgKPccZCyZ149Q1RuRVlnKD00DbRFSkbp4/XDJaNzKJeto/DM/Uj62icEtVh9A==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-discard-comments/5.1.2_postcss@8.4.21: + resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-discard-duplicates/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-discard-empty/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-discard-overridden/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-double-position-gradients/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-RTOs3chf/D1ETvaT+BcdGkPmRxoImZn3hmfAkFGET5ijx3Lnw7npubQDvwqOL1on54/uN6w9BGuEMSUsOK+2kA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/postcss-progressive-custom-properties': 2.0.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-focus-visible/8.0.0_postcss@8.4.21: + resolution: {integrity: sha512-mLIYkOFGXJSJtFwj9VX5LYUfWbxuwBWQxOqcdKk2p4apCAvsxji0jFpZhOPEpwD9YFbcTi0RWb+9Zam5y7qw5g==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-focus-within/7.0.0_postcss@8.4.21: + resolution: {integrity: sha512-DdIAwUY/7D981ROrWjxDuhCOTlbgjqbn2lCCuHWcGm+4s3m7thOCQzBGWBFc1heIx3MkiG1qF4Ew4logiPOxaQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-font-variant/5.0.0_postcss@8.4.21: + resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-gap-properties/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-ACrVEX+DZRkFNImiRBiFw56BW7OY43F/0AjusgBxGNE0mLvfqINkYQT421YMHB7HGs+rekladOcBNmYZu6+/iQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-image-set-function/5.0.0_postcss@8.4.21: + resolution: {integrity: sha512-a7q8XdGnU4OMnBqRzVkUBTtuRztD4YIy0b+52OxAcBqvhOU39A4ego9fUpVaqqrQrDOVuXmh/MYwC82aYuJkfQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-initial/4.0.1_postcss@8.4.21: + resolution: {integrity: sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-lab-function/5.0.0_postcss@8.4.21: + resolution: {integrity: sha512-XTV77sdIJGPxDYzZxXE0giTn3mQDC/sl/a9i2VVOPdVEEK7wFbd3kM9Dom20F4WtioTFllpDl3oMBoQvCrl79w==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/postcss-progressive-custom-properties': 2.0.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-logical/6.0.0_postcss@8.4.21: + resolution: {integrity: sha512-pn50jY5c+PmpYiTZ7KfYQ4aKXAVaFfZgNevtUwXglD22TxfLrrYD5d8m7UDQkT9CAfYvBgSkzPSBWTyE0WuQmA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-media-minmax/5.0.0_postcss@8.4.21: + resolution: {integrity: sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-merge-longhand/5.1.7_postcss@8.4.21: + resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + stylehacks: 5.1.1_postcss@8.4.21 + dev: true + + /postcss-merge-rules/5.1.3_postcss@8.4.21: + resolution: {integrity: sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.4 + caniuse-api: 3.0.0 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-minify-font-values/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-gradients/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + colord: 2.9.3 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-params/5.1.4_postcss@8.4.21: + resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.4 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-selectors/5.2.1_postcss@8.4.21: + resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-nesting/11.0.0_postcss@8.4.21: + resolution: {integrity: sha512-Y+jmDpQuSSoM/Qq+rqDc4D3E8Cn84qUmJLFS/M5u0YgM+5adLi9qFApbz5XzjzXjGAzItTUCP7RikLGy06ebiA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/selector-specificity': 2.1.0_jwkxkvlpbeeukrxssifiwvrjeq + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-normalize-charset/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-normalize-display-values/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-positions/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-repeat-style/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-string/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-timing-functions/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-unicode/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.4 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-url/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + normalize-url: 6.1.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-whitespace/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-opacity-percentage/1.1.3_postcss@8.4.21: + resolution: {integrity: sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==} + engines: {node: ^12 || ^14 || >=16} + peerDependencies: + postcss: ^8.2 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-ordered-values/5.1.3_postcss@8.4.21: + resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-overflow-shorthand/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-HJ+HIX6IeVyDBu+b5cJScwGYPnGokswXWH1izVgJGT6D5mrHzQJUvWWvHBRlopCAEbtose+JNOjRQgTRGHjm3A==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-page-break/3.0.4_postcss@8.4.21: + resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} + peerDependencies: + postcss: ^8 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-place/8.0.0_postcss@8.4.21: + resolution: {integrity: sha512-LFAiOWgekmvJ8/o4Cl1pPTuMryoMkr8PqAgv4j8i7iB9quinOhG4TXaq8RpF4nNIb9qOvn6+6LX4/BLcnza3rQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-preset-env/8.0.0_postcss@8.4.21: + resolution: {integrity: sha512-/kFWdq109OONR2Hl3T3nmo1dOdS7lHB6kF/nPaBn/2lGjQ99f/j5vGBYvupSmSni+F7T/0A0Xb0nfbJLnxwdjA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/postcss-cascade-layers': 3.0.0_postcss@8.4.21 + '@csstools/postcss-color-function': 2.0.0_postcss@8.4.21 + '@csstools/postcss-font-format-keywords': 2.0.0_postcss@8.4.21 + '@csstools/postcss-hwb-function': 2.0.0_postcss@8.4.21 + '@csstools/postcss-ic-unit': 2.0.0_postcss@8.4.21 + '@csstools/postcss-is-pseudo-class': 3.0.0_postcss@8.4.21 + '@csstools/postcss-logical-float-and-clear': 1.0.0_postcss@8.4.21 + '@csstools/postcss-logical-resize': 1.0.0_postcss@8.4.21 + '@csstools/postcss-logical-viewport-units': 1.0.1_postcss@8.4.21 + '@csstools/postcss-media-queries-aspect-ratio-number-values': 1.0.0_postcss@8.4.21 + '@csstools/postcss-nested-calc': 2.0.0_postcss@8.4.21 + '@csstools/postcss-normalize-display-values': 2.0.0_postcss@8.4.21 + '@csstools/postcss-oklab-function': 2.0.0_postcss@8.4.21 + '@csstools/postcss-progressive-custom-properties': 2.0.0_postcss@8.4.21 + '@csstools/postcss-scope-pseudo-class': 2.0.0_postcss@8.4.21 + '@csstools/postcss-stepped-value-functions': 2.0.0_postcss@8.4.21 + '@csstools/postcss-text-decoration-shorthand': 2.0.0_postcss@8.4.21 + '@csstools/postcss-trigonometric-functions': 2.0.0_postcss@8.4.21 + '@csstools/postcss-unset-value': 2.0.0_postcss@8.4.21 + autoprefixer: 10.4.13_postcss@8.4.21 + browserslist: 4.21.4 + css-blank-pseudo: 5.0.0_postcss@8.4.21 + css-has-pseudo: 5.0.0_postcss@8.4.21 + css-prefers-color-scheme: 8.0.0_postcss@8.4.21 + cssdb: 7.4.1 + postcss: 8.4.21 + postcss-attribute-case-insensitive: 6.0.0_postcss@8.4.21 + postcss-clamp: 4.1.0_postcss@8.4.21 + postcss-color-functional-notation: 5.0.0_postcss@8.4.21 + postcss-color-hex-alpha: 9.0.0_postcss@8.4.21 + postcss-color-rebeccapurple: 8.0.0_postcss@8.4.21 + postcss-custom-media: 9.1.0_postcss@8.4.21 + postcss-custom-properties: 13.1.0_postcss@8.4.21 + postcss-custom-selectors: 7.1.0_postcss@8.4.21 + postcss-dir-pseudo-class: 7.0.0_postcss@8.4.21 + postcss-double-position-gradients: 4.0.0_postcss@8.4.21 + postcss-focus-visible: 8.0.0_postcss@8.4.21 + postcss-focus-within: 7.0.0_postcss@8.4.21 + postcss-font-variant: 5.0.0_postcss@8.4.21 + postcss-gap-properties: 4.0.0_postcss@8.4.21 + postcss-image-set-function: 5.0.0_postcss@8.4.21 + postcss-initial: 4.0.1_postcss@8.4.21 + postcss-lab-function: 5.0.0_postcss@8.4.21 + postcss-logical: 6.0.0_postcss@8.4.21 + postcss-media-minmax: 5.0.0_postcss@8.4.21 + postcss-nesting: 11.0.0_postcss@8.4.21 + postcss-opacity-percentage: 1.1.3_postcss@8.4.21 + postcss-overflow-shorthand: 4.0.0_postcss@8.4.21 + postcss-page-break: 3.0.4_postcss@8.4.21 + postcss-place: 8.0.0_postcss@8.4.21 + postcss-pseudo-class-any-link: 8.0.0_postcss@8.4.21 + postcss-replace-overflow-wrap: 4.0.0_postcss@8.4.21 + postcss-selector-not: 7.0.0_postcss@8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-pseudo-class-any-link/8.0.0_postcss@8.4.21: + resolution: {integrity: sha512-9+SUrDDrmyQijQBRSZFfx5eL0N9sdtHhibcGPgmyQyYCshFZbhH22vfbo2z84U2TI8kh1TrN86t5N2xN2ojq0w==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-reduce-initial/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.4 + caniuse-api: 3.0.0 + postcss: 8.4.21 + dev: true + + /postcss-reduce-transforms/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-replace-overflow-wrap/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} + peerDependencies: + postcss: ^8.0.3 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-selector-not/7.0.0_postcss@8.4.21: + resolution: {integrity: sha512-vYYltgqe8JXLW/oWuENL6mKc7zbJWDA86kwQgGzJsalkvPOPcaM+G90FqjEiGllRAXIv3WmgehtQEfIJUDlUhg==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-selector-parser/6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-svgo/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + svgo: 2.8.0 + dev: true + + /postcss-unique-selectors/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /prelude-ls/1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier/2.8.3: + resolution: {integrity: sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-bytes/5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + dev: true + + /pretty-bytes/6.0.0: + resolution: {integrity: sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==} + engines: {node: ^14.13.1 || >=16.0.0} + dev: true + + /pretty-format/29.1.2: + resolution: {integrity: sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.0.0 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + + /prop-types/15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + /punycode/2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /randombytes/2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /react-dom/18.2.0_react@18.2.0: + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + + /react-feather/2.0.10_react@18.2.0: + resolution: {integrity: sha512-BLhukwJ+Z92Nmdcs+EMw6dy1Z/VLiJTzEQACDUEnWMClhYnFykJCGWQx+NmwP/qQHGX/5CzQ+TGi8ofg2+HzVQ==} + peerDependencies: + react: '>=16.8.6' + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /react-i18next/12.1.4_iakk3dtjhjpukdoa4oua5khgci: + resolution: {integrity: sha512-XQND7jYtgM7ht5PH3yIZljCRpAMTlH/zmngM9ZjToqa+0BR6xuu8c7QF0WIIOEjcMTB2S3iOfpN/xG/ZrAnO6g==} + peerDependencies: + i18next: '>= 19.0.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.20.13 + html-parse-stringify: 3.0.1 + i18next: 22.4.9 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: true + + /react-icons/4.7.1_react@18.2.0: + resolution: {integrity: sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==} + peerDependencies: + react: '*' + dependencies: + react: 18.2.0 + dev: true + + /react-is/16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + /react-is/18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + + /react-lifecycles-compat/3.0.4: + resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} + dev: false + + /react-modal/3.16.1_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==} + engines: {node: '>=8'} + peerDependencies: + react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 + react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 + dependencies: + exenv: 1.2.2 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-lifecycles-compat: 3.0.4 + warning: 4.0.3 + dev: false + + /react-query/3.39.3_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.20.13 + broadcast-channel: 3.7.0 + match-sorter: 6.3.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: true + + /react-refresh/0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: true + + /react-router-dom/6.8.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-hQouduSTywGJndE86CXJ2h7YEy4HYC6C/uh19etM+79FfQ6cFFFHnHyDlzO4Pq0eBUI96E4qVE5yUjA00yJZGQ==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.3.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-router: 6.8.0_react@18.2.0 + dev: true + + /react-router/6.8.0_react@18.2.0: + resolution: {integrity: sha512-760bk7y3QwabduExtudhWbd88IBbuD1YfwzpuDUAlJUJ7laIIcqhMvdhSVh1Fur1PE8cGl84L0dxhR3/gvHF7A==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.3.1 + react: 18.2.0 + dev: true + + /react-switch/7.0.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-KkDeW+cozZXI6knDPyUt3KBN1rmhoVYgAdCJqAh7st7tk8YE6N0iR89zjCWO8T8dUTeJGTR0KU+5CHCRMRffiA==} + peerDependencies: + react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: true + + /react-table/7.8.0_react@18.2.0: + resolution: {integrity: sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==} + peerDependencies: + react: ^16.8.3 || ^17.0.0-0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: true + + /react-tabs/6.0.0_react@18.2.0: + resolution: {integrity: sha512-8jKLKrlwxmn5/+xsa76yi27ZdB8E/WhlhQZw739O5UlOeUGtVoVeWnpqIewv/KbjTw7gQf/uA51zWUNt4IVygQ==} + peerDependencies: + react: ^18.0.0 + dependencies: + clsx: 1.2.1 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /react-tiny-fab/4.0.4_react@18.2.0: + resolution: {integrity: sha512-PxT6gEnIQR2vFfeIaa1Oq4PRX+cIEDbEfbS6PyevWCQngrKfqjMKPEcZOaaURaUclB9u3RilgjkaBUQFVlbWcg==} + engines: {node: '>=10'} + peerDependencies: + react: '>=16.8' + dependencies: + react: 18.2.0 + dev: false + + /react-window/1.8.8_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ==} + engines: {node: '>8.0.0'} + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.20.13 + memoize-one: 5.2.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /react/18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /recoil/0.7.6_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-hsBEw7jFdpBCY/tu2GweiyaqHKxVj6EqF2/SfrglbKvJHhpN57SANWvPW+gE90i3Awi+A5gssOd3u+vWlT+g7g==} + peerDependencies: + react: '>=16.13.1' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + hamt_plus: 1.0.2 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: true + + /regenerate-unicode-properties/10.1.0: + resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate/1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime/0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + /regenerator-transform/0.15.0: + resolution: {integrity: sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==} + dependencies: + '@babel/runtime': 7.20.13 + dev: true + + /regexp.prototype.flags/1.4.3: + resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + functions-have-names: 1.2.3 + dev: true + + /regexpp/3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /regexpu-core/5.2.1: + resolution: {integrity: sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsgen: 0.7.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.0.0 + dev: true + + /regjsgen/0.7.1: + resolution: {integrity: sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==} + dev: true + + /regjsparser/0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /remove-accents/0.4.2: + resolution: {integrity: sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==} + dev: true + + /require-from-string/2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /reselect/4.1.7: + resolution: {integrity: sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==} + dev: true + + /resize-observer-polyfill/1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + dev: true + + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /resolve/2.0.0-next.4: + resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor/3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rfdc/1.3.0: + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup-plugin-terser/7.0.2_rollup@2.79.1: + resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser + peerDependencies: + rollup: ^2.0.0 + dependencies: + '@babel/code-frame': 7.18.6 + jest-worker: 26.6.2 + rollup: 2.79.1 + serialize-javascript: 4.0.0 + terser: 5.15.1 + dev: true + + /rollup/2.79.1: + resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /rollup/3.11.0: + resolution: {integrity: sha512-+uWPPkpWQ2H3Qi7sNBcRfhhHJyUNgBYhG4wKe5wuGRj2m55kpo+0p5jubKNBjQODyPe6tSBE3tNpdDwEisQvAQ==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs/7.8.0: + resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} + dependencies: + tslib: 2.4.1 + dev: true + + /safe-buffer/5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-regex-test/1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + is-regex: 1.1.4 + dev: true + + /sass/1.57.1: + resolution: {integrity: sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + chokidar: 3.5.3 + immutable: 4.1.0 + source-map-js: 1.0.2 + dev: true + + /scheduler/0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + + /semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver/7.3.8: + resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /serialize-javascript/4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + dependencies: + randombytes: 2.1.0 + dev: true + + /shebang-command/2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + object-inspect: 1.12.2 + dev: true + + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /slash/3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi/3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi/4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi/5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-support/0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map/0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + + /sourcemap-codec/1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + /stable/0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + dev: true + + /stack-utils/2.0.5: + resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /stop-iteration-iterator/1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + dependencies: + internal-slot: 1.0.4 + dev: true + + /string-argv/0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + dev: true + + /string-natural-compare/3.0.1: + resolution: {integrity: sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==} + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string-width/5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.0.1 + dev: true + + /string.prototype.matchall/4.0.8: + resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + get-intrinsic: 1.1.3 + has-symbols: 1.0.3 + internal-slot: 1.0.3 + regexp.prototype.flags: 1.4.3 + side-channel: 1.0.4 + dev: true + + /string.prototype.trimend/1.0.5: + resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /string.prototype.trimstart/1.0.5: + resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /stringify-object/3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom/3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-comments/2.0.1: + resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} + engines: {node: '>=10'} + dev: true + + /strip-final-newline/3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-json-comments/3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /stylehacks/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.4 + postcss: 8.4.21 + postcss-selector-parser: 6.0.10 + dev: true + + /supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /svgo/2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + engines: {node: '>=10.13.0'} + hasBin: true + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.0.0 + stable: 0.1.8 + dev: true + + /temp-dir/2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + dev: true + + /tempy/0.6.0: + resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} + engines: {node: '>=10'} + dependencies: + is-stream: 2.0.1 + temp-dir: 2.0.0 + type-fest: 0.16.0 + unique-string: 2.0.0 + dev: true + + /terser/5.15.1: + resolution: {integrity: sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.2 + acorn: 8.8.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /text-table/0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /through/2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tr46/0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + + /tr46/1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.1.1 + dev: true + + /tsconfig-paths/3.14.1: + resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.1 + minimist: 1.2.6 + strip-bom: 3.0.0 + dev: true + + /tslib/1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib/2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + + /tsutils/3.21.0_typescript@4.9.4: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.9.4 + dev: true + + /type-check/0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest/0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /typescript/4.9.4: + resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /unbox-primitive/1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /unicode-canonical-property-names-ecmascript/2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript/2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript/2.0.0: + resolution: {integrity: sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript/2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /unique-string/2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + dependencies: + crypto-random-string: 2.0.0 + dev: true + + /universalify/2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /unload/2.2.0: + resolution: {integrity: sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==} + dependencies: + '@babel/runtime': 7.20.13 + detect-node: 2.1.0 + dev: true + + /upath/1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + dev: true + + /update-browserslist-db/1.0.10_browserslist@4.21.4: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.4 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /use-asset/1.0.4_react@18.2.0: + resolution: {integrity: sha512-7/hqDrWa0iMnCoET9W1T07EmD4Eg/Wmoj/X8TGBc++ECRK4m5yTsjP4O6s0yagbxfqIOuUkIxe2/sA+VR2GxZA==} + peerDependencies: + react: '>=17.0' + dependencies: + fast-deep-equal: 3.1.3 + react: 18.2.0 + dev: false + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /vite-plugin-pwa/0.14.1_vite@4.0.4: + resolution: {integrity: sha512-5zx7yhQ8RTLwV71+GA9YsQQ63ALKG8XXIMqRJDdZkR8ZYftFcRgnzM7wOWmQZ/DATspyhPih5wCdcZnAIsM+mA==} + peerDependencies: + vite: ^3.1.0 || ^4.0.0 + dependencies: + '@rollup/plugin-replace': 5.0.2_rollup@3.11.0 + debug: 4.3.4 + fast-glob: 3.2.12 + pretty-bytes: 6.0.0 + rollup: 3.11.0 + vite: 4.0.4_sass@1.57.1 + workbox-build: 6.5.4 + workbox-window: 6.5.4 + transitivePeerDependencies: + - '@types/babel__core' + - supports-color + dev: true + + /vite/4.0.4_sass@1.57.1: + resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.16.17 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.11.0 + sass: 1.57.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /void-elements/3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: true + + /warning/4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /webidl-conversions/3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /webidl-conversions/4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /whatwg-url/5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /whatwg-url/7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + + /which-boxed-primitive/1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-collection/1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + + /which-typed-array/1.1.9: + resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + is-typed-array: 1.1.10 + dev: true + + /which/2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap/1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /workbox-background-sync/6.5.4: + resolution: {integrity: sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==} + dependencies: + idb: 7.1.0 + workbox-core: 6.5.4 + dev: true + + /workbox-broadcast-update/6.5.4: + resolution: {integrity: sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-build/6.5.4: + resolution: {integrity: sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==} + engines: {node: '>=10.0.0'} + dependencies: + '@apideck/better-ajv-errors': 0.3.6_ajv@8.11.0 + '@babel/core': 7.20.12 + '@babel/preset-env': 7.19.4_@babel+core@7.20.12 + '@babel/runtime': 7.20.13 + '@rollup/plugin-babel': 5.3.1_3dsfpkpoyvuuxyfgdbpn4j4uzm + '@rollup/plugin-node-resolve': 11.2.1_rollup@2.79.1 + '@rollup/plugin-replace': 2.4.2_rollup@2.79.1 + '@surma/rollup-plugin-off-main-thread': 2.2.3 + ajv: 8.11.0 + common-tags: 1.8.2 + fast-json-stable-stringify: 2.1.0 + fs-extra: 9.1.0 + glob: 7.2.3 + lodash: 4.17.21 + pretty-bytes: 5.6.0 + rollup: 2.79.1 + rollup-plugin-terser: 7.0.2_rollup@2.79.1 + source-map: 0.8.0-beta.0 + stringify-object: 3.3.0 + strip-comments: 2.0.1 + tempy: 0.6.0 + upath: 1.2.0 + workbox-background-sync: 6.5.4 + workbox-broadcast-update: 6.5.4 + workbox-cacheable-response: 6.5.4 + workbox-core: 6.5.4 + workbox-expiration: 6.5.4 + workbox-google-analytics: 6.5.4 + workbox-navigation-preload: 6.5.4 + workbox-precaching: 6.5.4 + workbox-range-requests: 6.5.4 + workbox-recipes: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + workbox-streams: 6.5.4 + workbox-sw: 6.5.4 + workbox-window: 6.5.4 + transitivePeerDependencies: + - '@types/babel__core' + - supports-color + dev: true + + /workbox-cacheable-response/6.5.4: + resolution: {integrity: sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-core/6.5.4: + resolution: {integrity: sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==} + dev: true + + /workbox-expiration/6.5.4: + resolution: {integrity: sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==} + dependencies: + idb: 7.1.0 + workbox-core: 6.5.4 + dev: true + + /workbox-google-analytics/6.5.4: + resolution: {integrity: sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==} + dependencies: + workbox-background-sync: 6.5.4 + workbox-core: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + dev: true + + /workbox-navigation-preload/6.5.4: + resolution: {integrity: sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-precaching/6.5.4: + resolution: {integrity: sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==} + dependencies: + workbox-core: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + dev: true + + /workbox-range-requests/6.5.4: + resolution: {integrity: sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-recipes/6.5.4: + resolution: {integrity: sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==} + dependencies: + workbox-cacheable-response: 6.5.4 + workbox-core: 6.5.4 + workbox-expiration: 6.5.4 + workbox-precaching: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + dev: true + + /workbox-routing/6.5.4: + resolution: {integrity: sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-strategies/6.5.4: + resolution: {integrity: sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-streams/6.5.4: + resolution: {integrity: sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==} + dependencies: + workbox-core: 6.5.4 + workbox-routing: 6.5.4 + dev: true + + /workbox-sw/6.5.4: + resolution: {integrity: sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==} + dev: true + + /workbox-window/6.5.4: + resolution: {integrity: sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==} + dependencies: + '@types/trusted-types': 2.0.2 + workbox-core: 6.5.4 + dev: true + + /wrap-ansi/6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi/7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /yallist/3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml/1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yaml/2.2.1: + resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} + engines: {node: '>= 14'} + dev: true + + /yocto-queue/0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..68f3713 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +module.exports = { + plugins: [require('postcss-preset-env')()], +}; diff --git a/src/App.module.scss b/src/App.module.scss new file mode 100644 index 0000000..e67057f --- /dev/null +++ b/src/App.module.scss @@ -0,0 +1,20 @@ +.app { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + + display: flex; + background: var(--color-background); + color: var(--color-text); + + @media (max-width: 768px) { + flex-direction: column; + } +} + +.content { + flex-grow: 1; + overflow-y: auto; +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..7023bc9 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,75 @@ +import * as React from 'react'; +import { QueryClientProvider } from 'react-query'; +import { HashRouter as Router, Route, RouteObject, Routes, useRoutes } from 'react-router-dom'; +import { RecoilRoot } from 'recoil'; + +import APIConfig from '~/components//APIConfig'; +import { About } from '~/components/about/About'; +import APIDiscovery from '~/components/APIDiscovery'; +import ErrorBoundary from '~/components/ErrorBoundary'; +import Home from '~/components/Home'; +import Loading from '~/components/Loading'; +import Loading2 from '~/components/Loading2'; +import { Head } from '~/components/shared/Head'; +import SideBar from '~/components/SideBar'; +import StateProvider from '~/components/StateProvider'; +import StyleGuide from '~/components/StyleGuide'; +import { queryClient } from '~/misc/query'; +import { actions, initialState } from '~/store'; + +import styles from './App.module.scss'; + +const { lazy, Suspense } = React; + +const Connections = lazy(() => import('~/components/Connections')); +const Config = lazy(() => import('~/components/Config')); +const Logs = lazy(() => import('~/components/Logs')); +const Proxies = lazy(() => import('~/components/proxies/Proxies')); +const Rules = lazy(() => import('~/components/Rules')); + +const routes = [ + { path: '/', element: }, + { path: '/connections', element: }, + { path: '/configs', element: }, + { path: '/logs', element: }, + { path: '/proxies', element: }, + { path: '/rules', element: }, + { path: '/about', element: }, + process.env.NODE_ENV === 'development' ? { path: '/style', element: } : false, +].filter(Boolean) as RouteObject[]; + +function SideBarApp() { + return ( + <> + + +
+ }>{useRoutes(routes)} +
+ + ); +} + +const App = () => ( + + + + +
+ + }> + + + } /> + } /> + + + +
+
+
+
+
+); + +export default App; diff --git a/src/api/configs.ts b/src/api/configs.ts new file mode 100644 index 0000000..ff62ce7 --- /dev/null +++ b/src/api/configs.ts @@ -0,0 +1,48 @@ +import { getURLAndInit } from '~/misc/request-helper'; +import { ClashGeneralConfig, TunPartial } from '~/store/types'; +import { ClashAPIConfig } from '~/types'; + +const endpoint = '/configs'; +const updateGeoDatabasesFileEndpoint = '/configs/geo'; +const flushFakeIPPoolEndpoint = '/cache/fakeip/flush'; + +export async function fetchConfigs(apiConfig: ClashAPIConfig) { + const { url, init } = getURLAndInit(apiConfig); + return await fetch(url + endpoint, init); +} + +// TODO support PUT /configs +// req body +// { Path: string } + +type ClashConfigPartial = TunPartial; +function configsPatchWorkaround(o: ClashConfigPartial) { + // backward compatibility for older clash using `socket-port` + if ('socks-port' in o) { + o['socket-port'] = o['socks-port']; + } + return o; +} + +export async function updateConfigs(apiConfig: ClashAPIConfig, o: ClashConfigPartial) { + const { url, init } = getURLAndInit(apiConfig); + const body = JSON.stringify(configsPatchWorkaround(o)); + return await fetch(url + endpoint, { ...init, body, method: 'PATCH' }); +} + +export async function reloadConfigFile(apiConfig: ClashAPIConfig) { + const { url, init } = getURLAndInit(apiConfig); + const body = '{"path": "", "payload": ""}'; + return await fetch(url + endpoint + '?force=true', { ...init, body, method: 'PUT' }); +} + +export async function updateGeoDatabasesFile(apiConfig: ClashAPIConfig) { + const { url, init } = getURLAndInit(apiConfig); + const body = '{"path": "", "payload": ""}'; + return await fetch(url + updateGeoDatabasesFileEndpoint, { ...init, body, method: 'POST' }); +} + +export async function flushFakeIPPool(apiConfig: ClashAPIConfig) { + const { url, init } = getURLAndInit(apiConfig); + return await fetch(url + flushFakeIPPoolEndpoint, { ...init, method: 'POST' }); +} diff --git a/src/api/connections.ts b/src/api/connections.ts new file mode 100644 index 0000000..7f27ebf --- /dev/null +++ b/src/api/connections.ts @@ -0,0 +1,91 @@ +import { ClashAPIConfig } from '~/types'; + +import { buildWebSocketURL, getURLAndInit } from '../misc/request-helper'; + +const endpoint = '/connections'; + +const fetched = false; +const subscribers = []; + +// see also https://github.com/Dreamacro/clash/blob/dev/constant/metadata.go#L41 +type UUID = string; +type ConnNetwork = 'tcp' | 'udp'; +type ConnType = 'HTTP' | 'HTTP Connect' | 'Socks5' | 'Redir' | 'Unknown'; +export type ConnectionItem = { + id: UUID; + metadata: { + network: ConnNetwork; + type: ConnType; + sourceIP: string; + destinationIP: string; + remoteDestination: string; + sourcePort: string; + destinationPort: string; + host: string; + process?: string; + sniffHost?: string; + }; + upload: number; + download: number; + // e.g. "2019-11-30T22:48:13.416668+08:00", + start: string; + chains: string[]; + // e.g. 'Match', 'DomainKeyword' + rule: string; + rulePayload?: string; +}; +type ConnectionsData = { + downloadTotal: number; + uploadTotal: number; + connections: Array; +}; + +function appendData(s: string) { + let o: ConnectionsData; + try { + o = JSON.parse(s); + } catch (err) { + // eslint-disable-next-line no-console + console.log('JSON.parse error', JSON.parse(s)); + } + subscribers.forEach((f) => f(o)); +} + +type UnsubscribeFn = () => void; + +let wsState: number; +export function fetchData(apiConfig: ClashAPIConfig, listener: unknown): UnsubscribeFn | void { + if (fetched || wsState === 1) { + if (listener) return subscribe(listener); + } + wsState = 1; + const url = buildWebSocketURL(apiConfig, endpoint); + const ws = new WebSocket(url); + ws.addEventListener('error', () => (wsState = 3)); + ws.addEventListener('message', (event) => appendData(event.data)); + if (listener) return subscribe(listener); +} + +function subscribe(listener: unknown): UnsubscribeFn { + subscribers.push(listener); + return function unsubscribe() { + const idx = subscribers.indexOf(listener); + subscribers.splice(idx, 1); + }; +} + +export async function closeAllConnections(apiConfig: ClashAPIConfig) { + const { url, init } = getURLAndInit(apiConfig); + return await fetch(url + endpoint, { ...init, method: 'DELETE' }); +} + +export async function fetchConns(apiConfig: ClashAPIConfig) { + const { url, init } = getURLAndInit(apiConfig); + return await fetch(url + endpoint, { ...init }); +} + +export async function closeConnById(apiConfig: ClashAPIConfig, id: string) { + const { url: baseURL, init } = getURLAndInit(apiConfig); + const url = `${baseURL}${endpoint}/${id}`; + return await fetch(url, { ...init, method: 'DELETE' }); +} diff --git a/src/api/logs.ts b/src/api/logs.ts new file mode 100644 index 0000000..db37bcd --- /dev/null +++ b/src/api/logs.ts @@ -0,0 +1,151 @@ +import { pad0 } from '~/misc/utils'; +import { Log } from '~/store/types'; +import { LogsAPIConfig } from '~/types'; + +import { buildLogsWebSocketURL, getURLAndInit } from '../misc/request-helper'; + +type AppendLogFn = (x: Log) => void; +enum WebSocketReadyState { + Connecting = 0, + Open = 1, + Closing = 2, + Closed = 3, +} + +const endpoint = '/logs'; +const textDecoder = new TextDecoder('utf-8'); + +const getRandomStr = () => { + return Math.floor((1 + Math.random()) * 0x10000).toString(16); +}; + +let even = false; +let fetched = false; +let decoded = ''; +let ws: WebSocket; +let prevAppendLogFn: AppendLogFn; + +function appendData(s: string, callback: AppendLogFn) { + let o: Partial; + try { + o = JSON.parse(s); + } catch (err) { + // eslint-disable-next-line no-console + console.log('JSON.parse error', JSON.parse(s)); + } + + const now = new Date(); + const time = formatDate(now); + // mutate input param in place intentionally + o.time = time; + o.id = +now - 0 + getRandomStr(); + o.even = even = !even; + callback(o as Log); +} + +function formatDate(d: Date) { + // 19-03-09 12:45 + const YY = d.getFullYear() % 100; + const MM = pad0(d.getMonth() + 1, 2); + const dd = pad0(d.getDate(), 2); + const HH = pad0(d.getHours(), 2); + const mm = pad0(d.getMinutes(), 2); + const ss = pad0(d.getSeconds(), 2); + return `${YY}-${MM}-${dd} ${HH}:${mm}:${ss}`; +} + +function pump(reader: ReadableStreamDefaultReader, appendLog: AppendLogFn) { + return reader.read().then(({ done, value }) => { + const str = textDecoder.decode(value, { stream: !done }); + decoded += str; + + const splits = decoded.split('\n'); + + const lastSplit = splits[splits.length - 1]; + + for (let i = 0; i < splits.length - 1; i++) { + appendData(splits[i], appendLog); + } + + if (done) { + appendData(lastSplit, appendLog); + decoded = ''; + + // eslint-disable-next-line no-console + console.log('GET /logs streaming done'); + fetched = false; + return; + } else { + decoded = lastSplit; + } + return pump(reader, appendLog); + }); +} + +/** loose hashing of the connection configuration */ +function makeConnStr(c: LogsAPIConfig) { + const keys = Object.keys(c); + keys.sort(); + return keys.map((k) => c[k]).join('|'); +} + +let prevConnStr: string; +let controller: AbortController; + +export function fetchLogs(apiConfig: LogsAPIConfig, appendLog: AppendLogFn) { + if (apiConfig.logLevel === 'uninit') return; + if (fetched || (ws && ws.readyState === WebSocketReadyState.Open)) return; + prevAppendLogFn = appendLog; + const url = buildLogsWebSocketURL(apiConfig, endpoint); + ws = new WebSocket(url); + ws.addEventListener('error', () => { + fetchLogsWithFetch(apiConfig, appendLog); + }); + ws.addEventListener('message', function (event) { + appendData(event.data, appendLog); + }); +} + +export function stop() { + ws.close(); + if (controller) controller.abort(); +} + +export function reconnect(apiConfig: LogsAPIConfig) { + if (!prevAppendLogFn || !ws) return; + ws.close(); + fetched = false; + fetchLogs(apiConfig, prevAppendLogFn); +} + +function fetchLogsWithFetch(apiConfig: LogsAPIConfig, appendLog: AppendLogFn) { + if (controller && makeConnStr(apiConfig) !== prevConnStr) { + controller.abort(); + } else if (fetched) { + return; + } + + fetched = true; + prevConnStr = makeConnStr(apiConfig); + + controller = new AbortController(); + const signal = controller.signal; + + const { url, init } = getURLAndInit(apiConfig); + fetch(url + endpoint + '?level=' + apiConfig.logLevel, { + ...init, + signal, + }).then( + (response) => { + const reader = response.body.getReader(); + pump(reader, appendLog); + }, + (err) => { + fetched = false; + if (signal.aborted) return; + + // eslint-disable-next-line no-console + console.log('GET /logs error:', err.message); + } + ); +} diff --git a/src/api/proxies.ts b/src/api/proxies.ts new file mode 100644 index 0000000..36aa05d --- /dev/null +++ b/src/api/proxies.ts @@ -0,0 +1,78 @@ +import { getURLAndInit } from '../misc/request-helper'; + +const endpoint = '/proxies'; + +/* +$ curl "http://127.0.0.1:8080/proxies/Proxy" -XPUT -d '{ "name": "ss3" }' -i +HTTP/1.1 400 Bad Request +Content-Type: text/plain; charset=utf-8 + +{"error":"Selector update error: Proxy does not exist"} + +~ +$ curl "http://127.0.0.1:8080/proxies/GLOBAL" -XPUT -d '{ "name": "Proxy" }' -i +HTTP/1.1 204 No Content +*/ + +export async function fetchProxies(config) { + const { url, init } = getURLAndInit(config); + const res = await fetch(url + endpoint, init); + return await res.json(); +} + +export async function requestToSwitchProxy(apiConfig, name1, name2) { + const body = { name: name2 }; + const { url, init } = getURLAndInit(apiConfig); + const fullURL = `${url}${endpoint}/${name1}`; + return await fetch(fullURL, { + ...init, + method: 'PUT', + body: JSON.stringify(body), + }); +} + +export async function requestDelayForProxy( + apiConfig, + name, + latencyTestUrl = 'http://www.gstatic.com/generate_204' +) { + const { url, init } = getURLAndInit(apiConfig); + const qs = `timeout=5000&url=${encodeURIComponent(latencyTestUrl)}`; + const fullURL = `${url}${endpoint}/${encodeURIComponent(name)}/delay?${qs}`; + return await fetch(fullURL, init); +} + +export async function requestDelayForProxyGroup( + apiConfig, + name, + latencyTestUrl = 'http://www.gstatic.com/generate_202' +) { + const { url, init } = getURLAndInit(apiConfig); + const qs = `url=${encodeURIComponent(latencyTestUrl)}&timeout=2000`; + const fullUrl = `${url}/group/${encodeURIComponent(name)}/delay?${qs}`; + return await fetch(fullUrl, init); +} + +export async function fetchProviderProxies(config) { + const { url, init } = getURLAndInit(config); + const res = await fetch(url + '/providers/proxies', init); + if (res.status === 404) { + return { providers: {} }; + } + return await res.json(); +} + +export async function updateProviderByName(config, name) { + const { url, init } = getURLAndInit(config); + const options = { ...init, method: 'PUT' }; + return await fetch(url + '/providers/proxies/' + encodeURIComponent(name), options); +} + +export async function healthcheckProviderByName(config, name) { + const { url, init } = getURLAndInit(config); + const options = { ...init, method: 'GET' }; + return await fetch( + url + '/providers/proxies/' + encodeURIComponent(name) + '/healthcheck', + options + ); +} diff --git a/src/api/rule-provider.ts b/src/api/rule-provider.ts new file mode 100644 index 0000000..14d9917 --- /dev/null +++ b/src/api/rule-provider.ts @@ -0,0 +1,84 @@ +import { getURLAndInit } from '~/misc/request-helper'; +import { ClashAPIConfig } from '~/types'; + +export type RuleProvider = RuleProviderAPIItem & { idx: number }; + +export type RuleProviderAPIItem = { + behavior: string; + name: string; + ruleCount: number; + type: 'Rule'; + // example value "2020-06-30T16:23:01.44143802+08:00" + updatedAt: string; + vehicleType: 'HTTP' | 'File'; +}; + +type RuleProviderAPIData = { + providers: Record; +}; + +function normalizeAPIResponse(data: RuleProviderAPIData) { + const providers = data.providers; + const names = Object.keys(providers); + const byName: Record = {}; + + // attach an idx to each item + for (let i = 0; i < names.length; i++) { + const name = names[i]; + byName[name] = { ...providers[name], idx: i }; + } + + return { byName, names }; +} + +export async function fetchRuleProviders(endpoint: string, apiConfig: ClashAPIConfig) { + const { url, init } = getURLAndInit(apiConfig); + + let data = { providers: {} }; + try { + const res = await fetch(url + endpoint, init); + if (res.ok) { + data = await res.json(); + } + } catch (err) { + // log and ignore + // eslint-disable-next-line no-console + console.log('failed to GET /providers/rules', err); + } + return normalizeAPIResponse(data); +} + +export async function refreshRuleProviderByName({ + name, + apiConfig, +}: { + name: string; + apiConfig: ClashAPIConfig; +}) { + const { url, init } = getURLAndInit(apiConfig); + try { + const res = await fetch(url + `/providers/rules/${name}`, { + method: 'PUT', + ...init, + }); + return res.ok; + } catch (err) { + // log and ignore + // eslint-disable-next-line no-console + console.log('failed to PUT /providers/rules/:name', err); + return false; + } +} + +export async function updateRuleProviders({ + names, + apiConfig, +}: { + names: string[]; + apiConfig: ClashAPIConfig; +}) { + for (let i = 0; i < names.length; i++) { + // run in sequence + await refreshRuleProviderByName({ name: names[i], apiConfig }); + } +} diff --git a/src/api/rules.ts b/src/api/rules.ts new file mode 100644 index 0000000..3edb8d4 --- /dev/null +++ b/src/api/rules.ts @@ -0,0 +1,40 @@ +import invariant from 'invariant'; + +import { getURLAndInit } from '~/misc/request-helper'; +import { ClashAPIConfig } from '~/types'; + +// const endpoint = '/rules'; + +type RuleItem = RuleAPIItem & { id: number }; + +type RuleAPIItem = { + type: string; + payload: string; + proxy: string; +}; + +function normalizeAPIResponse(json: { rules: Array }): Array { + invariant( + json.rules && json.rules.length >= 0, + 'there is no valid rules list in the rules API response' + ); + + // attach an id + return json.rules.map((r: RuleAPIItem, i: number) => ({ ...r, id: i })); +} + +export async function fetchRules(endpoint: string, apiConfig: ClashAPIConfig) { + let json = { rules: [] }; + try { + const { url, init } = getURLAndInit(apiConfig); + const res = await fetch(url + endpoint, init); + if (res.ok) { + json = await res.json(); + } + } catch (err) { + // log and ignore + // eslint-disable-next-line no-console + console.log('failed to fetch rules', err); + } + return normalizeAPIResponse(json); +} diff --git a/src/api/traffic.ts b/src/api/traffic.ts new file mode 100644 index 0000000..34e9c91 --- /dev/null +++ b/src/api/traffic.ts @@ -0,0 +1,119 @@ +import { ClashAPIConfig } from '~/types'; + +import { buildWebSocketURL, getURLAndInit } from '../misc/request-helper'; + +const endpoint = '/traffic'; +const textDecoder = new TextDecoder('utf-8'); + +const Size = 150; + +const traffic = { + labels: Array(Size).fill(0), + up: Array(Size), + down: Array(Size), + + size: Size, + subscribers: [], + appendData(o: { up: number; down: number }) { + this.up.shift(); + this.down.shift(); + this.labels.shift(); + + const l = Date.now(); + this.up.push(o.up); + this.down.push(o.down); + this.labels.push(l); + + this.subscribers.forEach((f) => f(o)); + }, + + subscribe(listener: (x: any) => void) { + this.subscribers.push(listener); + return () => { + const idx = this.subscribers.indexOf(listener); + this.subscribers.splice(idx, 1); + }; + }, +}; + +let fetched = false; +let decoded = ''; + +function parseAndAppend(x: string) { + traffic.appendData(JSON.parse(x)); +} + +function pump(reader: ReadableStreamDefaultReader) { + return reader.read().then(({ done, value }) => { + const str = textDecoder.decode(value, { stream: !done }); + decoded += str; + + const splits = decoded.split('\n'); + + const lastSplit = splits[splits.length - 1]; + + for (let i = 0; i < splits.length - 1; i++) { + parseAndAppend(splits[i]); + } + + if (done) { + parseAndAppend(lastSplit); + decoded = ''; + + // eslint-disable-next-line no-console + console.log('GET /traffic streaming done'); + fetched = false; + return; + } else { + decoded = lastSplit; + } + return pump(reader); + }); +} + +// 1 OPEN +// other value CLOSED +// similar to ws readyState but not the same +// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState +let wsState: number; +function fetchData(apiConfig: ClashAPIConfig) { + if (fetched || wsState === 1) return traffic; + wsState = 1; + const url = buildWebSocketURL(apiConfig, endpoint); + const ws = new WebSocket(url); + ws.addEventListener('error', function (_ev) { + wsState = 3; + }); + ws.addEventListener('close', function (_ev) { + wsState = 3; + fetchDataWithFetch(apiConfig); + }); + ws.addEventListener('message', function (event) { + parseAndAppend(event.data); + }); + return traffic; +} + +function fetchDataWithFetch(apiConfig: ClashAPIConfig) { + if (fetched) return traffic; + fetched = true; + const { url, init } = getURLAndInit(apiConfig); + fetch(url + endpoint, init).then( + (response) => { + if (response.ok) { + const reader = response.body.getReader(); + pump(reader); + } else { + fetched = false; + } + }, + (err) => { + // eslint-disable-next-line no-console + console.log('fetch /traffic error', err); + fetched = false; + } + ); + return traffic; +} + +export { fetchData }; diff --git a/src/api/version.ts b/src/api/version.ts new file mode 100644 index 0000000..6c29125 --- /dev/null +++ b/src/api/version.ts @@ -0,0 +1,27 @@ +import { getURLAndInit } from '~/misc/request-helper'; +import { ClashAPIConfig } from '~/types'; + +type VersionData = { + version?: string; + premium?: boolean; + meta?: boolean; +}; + +export async function fetchVersion( + endpoint: string, + apiConfig: ClashAPIConfig +): Promise { + let json = {}; + try { + const { url, init } = getURLAndInit(apiConfig); + const res = await fetch(url + endpoint, init); + if (res.ok) { + json = await res.json(); + } + } catch (err) { + // log and ignore + // eslint-disable-next-line no-console + console.log(`failed to fetch ${endpoint}`, err); + } + return json; +} diff --git a/src/components/APIConfig.module.scss b/src/components/APIConfig.module.scss new file mode 100644 index 0000000..6581d46 --- /dev/null +++ b/src/components/APIConfig.module.scss @@ -0,0 +1,52 @@ +.root { + &:focus { + outline: none; + } +} + +.header { + display: flex; + justify-content: center; + align-items: center; + + .icon { + --stroke: #f3f3f3; + color: #20497e; + opacity: 0.7; + transition: opacity 400ms; + &:hover { + opacity: 1; + } + } +} + +.body { + padding: 15px 0 0; +} + +.hostnamePort { + display: flex; + + div { + flex: 1 1 auto; + } + + div:nth-child(2) { + flex-grow: 0; + flex-basis: 120px; + margin-left: 10px; + } +} + +.error { + height: 20px; + font-size: 0.8em; + color: #ff8b8b; +} + +.footer { + padding: 5px 0 10px; + display: flex; + justify-content: flex-end; + align-items: center; +} diff --git a/src/components/APIConfig.tsx b/src/components/APIConfig.tsx new file mode 100644 index 0000000..6de1f30 --- /dev/null +++ b/src/components/APIConfig.tsx @@ -0,0 +1,162 @@ +import * as React from 'react'; + +import { fetchConfigs } from '~/api/configs'; +import { BackendList } from '~/components/BackendList'; +import { addClashAPIConfig, getClashAPIConfig } from '~/store/app'; +import { State } from '~/store/types'; +import { ClashAPIConfig } from '~/types'; + +import s0 from './APIConfig.module.scss'; +import Button from './Button'; +import Field from './Field'; +import { connect } from './StateProvider'; +import SvgYacd from './SvgYacd'; + +const { useState, useRef, useCallback, useEffect } = React; +const Ok = 0; + +const mapState = (s: State) => ({ + apiConfig: getClashAPIConfig(s), +}); + +function APIConfig({ dispatch }) { + const [baseURL, setBaseURL] = useState(''); + const [secret, setSecret] = useState(''); + const [errMsg, setErrMsg] = useState(''); + + const userTouchedFlagRef = useRef(false); + const contentEl = useRef(null); + + const handleInputOnChange = useCallback((e) => { + userTouchedFlagRef.current = true; + setErrMsg(''); + const target = e.target; + const { name } = target; + const value = target.value; + switch (name) { + case 'baseURL': + setBaseURL(value); + break; + case 'secret': + setSecret(value); + break; + default: + throw new Error(`unknown input name ${name}`); + } + }, []); + + const onConfirm = useCallback(() => { + let unconfirmedBaseURL = baseURL; + if (unconfirmedBaseURL) { + const prefix = baseURL.substring(0, 7); + if (prefix.includes(':/')) { + // same logic in verify function + if (prefix !== 'http://' && prefix !== 'https:/') { + return [1, 'Must starts with http:// or https://']; + } + } else if (window.location.protocol) { + // only append scheme when prefix does not include scheme and current location includes scheme + unconfirmedBaseURL = `${window.location.protocol}//${unconfirmedBaseURL}`; + } + } + verify({ baseURL: unconfirmedBaseURL, secret }).then((ret) => { + if (ret[0] !== Ok) { + setErrMsg(ret[1]); + } else { + dispatch(addClashAPIConfig({ baseURL: unconfirmedBaseURL, secret })); + } + }); + }, [baseURL, secret, dispatch]); + + const handleContentOnKeyDown = useCallback( + (e: React.KeyboardEvent) => { + if ( + e.target instanceof Element && + (!e.target.tagName || e.target.tagName.toUpperCase() !== 'INPUT') + ) { + return; + } + if (e.key !== 'Enter') return; + + onConfirm(); + }, + [onConfirm] + ); + + const detectApiServer = async () => { + // if there is already a clash API server at `/`, just use it as default value + const res = await fetch('/'); + res.json().then((data) => { + if (data['hello'] === 'clash') { + setBaseURL(window.location.origin); + } + }); + }; + useEffect(() => { + detectApiServer(); + }, []); + + return ( + // eslint-disable-next-line jsx-a11y/no-static-element-interactions +
+
+
+ +
+
+
+
+ + +
+
+
{errMsg ? errMsg : null}
+
+
+
+ +
+ ); +} + +export default connect(mapState)(APIConfig); + +async function verify(apiConfig: ClashAPIConfig): Promise<[number, string?]> { + try { + new URL(apiConfig.baseURL); + } catch (e) { + if (apiConfig.baseURL) { + const prefix = apiConfig.baseURL.substring(0, 7); + if (prefix !== 'http://' && prefix !== 'https:/') { + return [1, 'Must starts with http:// or https://']; + } + } + + return [1, 'Invalid URL']; + } + try { + const res = await fetchConfigs(apiConfig); + if (res.status > 399) { + return [1, res.statusText]; + } + return [Ok]; + } catch (e) { + return [1, 'Failed to connect']; + } +} diff --git a/src/components/APIDiscovery.module.scss b/src/components/APIDiscovery.module.scss new file mode 100644 index 0000000..e2161f8 --- /dev/null +++ b/src/components/APIDiscovery.module.scss @@ -0,0 +1,33 @@ +.content.content { + background: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + + transform: none; + padding: 0; + border-radius: 0; + + display: flex; + justify-content: center; + overflow-y: auto; +} + +.container { + position: relative; + margin-left: 20px; + margin-right: 20px; +} + +.overlay.overlay { + background-color: var(--color-background); +} + +.fixed { + position: fixed; + padding: 16px; + bottom: 0; + right: 0; +} diff --git a/src/components/APIDiscovery.tsx b/src/components/APIDiscovery.tsx new file mode 100644 index 0000000..9340b60 --- /dev/null +++ b/src/components/APIDiscovery.tsx @@ -0,0 +1,58 @@ +import * as React from 'react'; + +import { ThemeSwitcher } from '~/components/shared/ThemeSwitcher'; +import { DOES_NOT_SUPPORT_FETCH, errors } from '~/misc/errors'; +import { getClashAPIConfig } from '~/store/app'; +import { fetchConfigs } from '~/store/configs'; +import { closeModal } from '~/store/modals'; +import { State } from '~/store/types'; + +import APIConfig from './APIConfig'; +import s0 from './APIDiscovery.module.scss'; +import Modal from './Modal'; +import { connect } from './StateProvider'; + +const { useCallback, useEffect } = React; + +function APIDiscovery({ dispatch, apiConfig, modals }) { + if (!window.fetch) { + const { detail } = errors[DOES_NOT_SUPPORT_FETCH]; + const err = new Error(detail); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'code' does not exist on type 'Error'. + err.code = DOES_NOT_SUPPORT_FETCH; + throw err; + } + + const closeApiConfigModal = useCallback(() => { + dispatch(closeModal('apiConfig')); + }, [dispatch]); + useEffect(() => { + dispatch(fetchConfigs(apiConfig)); + }, [dispatch, apiConfig]); + + return ( + +
+ +
+ +
+ +
+
+ ); +} + +const mapState = (s: State) => ({ + modals: s.modals, + apiConfig: getClashAPIConfig(s), +}); + +export default connect(mapState)(APIDiscovery); diff --git a/src/components/BackendList.module.scss b/src/components/BackendList.module.scss new file mode 100644 index 0000000..6872d3a --- /dev/null +++ b/src/components/BackendList.module.scss @@ -0,0 +1,102 @@ +.ul { + position: relative; + margin: 0; + padding: 0; + list-style: none; + line-height: 1.8; + + --width-max-content: 230px; +} + +.li { + position: relative; + margin: 5px 0; + padding: 10px 0; + border-radius: 10px; + display: grid; + place-content: center; + grid-template-columns: 40px 1fr 40px; + grid-template-rows: 30px; + grid-template-areas: 'close url .'; + column-gap: 10px; + border: 1px solid var(--bg-near-transparent); +} + +.li:hover { + background-color: var(--bg-near-transparent); +} + +.close { + opacity: 0; + grid-area: close; + place-self: center; + cursor: pointer; +} + +.li:hover .close, +.li:hover .eye { + opacity: 1; +} +.close:focus, +.eye:focus { + opacity: 1; +} + +.hasSecret { + grid-template-rows: repeat(2, 30px); + grid-template-areas: + 'close url .' + 'close secret eye'; +} + +.url { + grid-area: url; +} +.secret { + grid-area: secret; +} +.eye { + grid-area: eye; + opacity: 0; + place-self: center; + cursor: pointer; +} + +.url, +.secret { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.btn { + outline: none; + appearance: none; + border: 1px solid transparent; + background-color: transparent; + color: inherit; + display: flex; + align-items: center; + padding: 5px; + border-radius: 100px; +} +.btn:focus { + border-color: var(--color-focus-blue); +} +.btn:hover:enabled { + background-color: var(--color-focus-blue); + color: white; +} +.btn:active:enabled { + transform: scale(0.97); +} +.btn:disabled { + color: var(--color-text-secondary); +} + +.url { + cursor: pointer; +} +.url:hover { + color: var(--color-text-highlight); +} diff --git a/src/components/BackendList.tsx b/src/components/BackendList.tsx new file mode 100644 index 0000000..d16a28e --- /dev/null +++ b/src/components/BackendList.tsx @@ -0,0 +1,142 @@ +import cx from 'clsx'; +import * as React from 'react'; +import { Eye, EyeOff, X as Close } from 'react-feather'; + +import { useToggle } from '~/hooks/basic'; +import { getClashAPIConfigs, getSelectedClashAPIConfigIndex } from '~/store/app'; +import { ClashAPIConfig } from '~/types'; + +import s from './BackendList.module.scss'; +import { connect, useStoreActions } from './StateProvider'; + +type Config = ClashAPIConfig & { addedAt: number }; + +const mapState = (s) => ({ + apiConfigs: getClashAPIConfigs(s), + selectedClashAPIConfigIndex: getSelectedClashAPIConfigIndex(s), +}); + +export const BackendList = connect(mapState)(BackendListImpl); + +function BackendListImpl({ + apiConfigs, + selectedClashAPIConfigIndex, +}: { + apiConfigs: Config[]; + selectedClashAPIConfigIndex: number; +}) { + const { + app: { removeClashAPIConfig, selectClashAPIConfig }, + } = useStoreActions(); + + const onRemove = React.useCallback( + (conf: ClashAPIConfig) => { + removeClashAPIConfig(conf); + }, + [removeClashAPIConfig] + ); + const onSelect = React.useCallback( + (conf: ClashAPIConfig) => { + selectClashAPIConfig(conf); + }, + [selectClashAPIConfig] + ); + + return ( + <> +
    + {apiConfigs.map((item, idx) => { + return ( +
  • + +
  • + ); + })} +
+ + ); +} + +function Item({ + baseURL, + secret, + disableRemove, + onRemove, + onSelect, +}: { + baseURL: string; + secret: string; + disableRemove: boolean; + onRemove: (x: ClashAPIConfig) => void; + onSelect: (x: ClashAPIConfig) => void; +}) { + const [show, toggle] = useToggle(); + const Icon = show ? EyeOff : Eye; + + const handleTap = React.useCallback((e: React.KeyboardEvent) => { + e.stopPropagation(); + }, []); + + return ( + <> + + onSelect({ baseURL, secret })} + onKeyUp={handleTap} + > + {baseURL} + + + {secret ? ( + <> + {show ? secret : '***'} + + {/* @ts-expect-error ts-migrate(2322) FIXME: Type 'boolean | (() => void)' is not assignable to... Remove this comment to see the full error message */} + + + ) : null} + + ); +} + +function Button({ + children, + onClick, + className, + disabled, +}: { + children: React.ReactNode; + + onClick?: (e: React.MouseEvent) => unknown; + className: string; + disabled?: boolean; +}) { + return ( + + ); +} diff --git a/src/components/Button.module.scss b/src/components/Button.module.scss new file mode 100644 index 0000000..bdbbcb5 --- /dev/null +++ b/src/components/Button.module.scss @@ -0,0 +1,72 @@ +@import '~/styles/utils/custom-media'; + +.btn { + -webkit-appearance: none; + outline: none; + user-select: none; + position: relative; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--color-btn-fg); + background: var(--color-btn-bg); + border: 1px solid #555; + border-radius: 100px; + &:focus { + border-color: var(--color-focus-blue); + } + &:hover { + background: #387cec; + border: 1px solid #387cec; + color: #fff; + } + &:active { + transform: scale(0.97); + } + + font-size: 0.75em; + padding: 4px 7px; + @media (--breakpoint-not-small) { + font-size: small; + padding: 6px 12px; + } + + &.minimal { + border-color: transparent; + background: none; + &:focus { + border-color: var(--color-focus-blue); + } + &:hover { + color: #fff; + background: #387cec; + border: 1px solid #387cec; + } + } +} + +.btn:disabled { + opacity: 0.5; +} + +.btnInternal { + display: flex; + align-items: center; + justify-content: center; + column-gap: 4px; +} + +.btnStart { + display: inline-flex; + align-items: center; + justify-content: center; +} + +.loadingContainer { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: inline-flex; +} diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 0000000..9bd0d61 --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,82 @@ +import cx from 'clsx'; +import * as React from 'react'; + +import s0 from './Button.module.scss'; +import { LoadingDot } from './shared/Basic'; + +const { forwardRef, useCallback } = React; + +type ButtonInternalProps = { + children?: React.ReactNode; + label?: string; + text?: string; + start?: React.ReactNode | (() => React.ReactNode); +}; + +type ButtonProps = { + isLoading?: boolean; + onClick?: (e: React.MouseEvent) => unknown; + disabled?: boolean; + kind?: 'primary' | 'minimal'; + className?: string; + title?: string; +} & ButtonInternalProps; + +function Button(props: ButtonProps, ref: React.Ref) { + const { + onClick, + disabled = false, + isLoading, + kind = 'primary', + className, + children, + label, + text, + start, + ...restProps + } = props; + const internalProps = { children, label, text, start }; + const internalOnClick = useCallback( + (e) => { + if (isLoading) return; + onClick && onClick(e); + }, + [isLoading, onClick] + ); + const btnClassName = cx(s0.btn, { [s0.minimal]: kind === 'minimal' }, className); + return ( + + ); +} + +function ButtonInternal({ children, label, text, start }: ButtonInternalProps) { + return ( +
+ {start && ( + {typeof start === 'function' ? start() : start} + )} + {children || label || text} +
+ ); +} + +export default forwardRef(Button); diff --git a/src/components/Collapsible.tsx b/src/components/Collapsible.tsx new file mode 100644 index 0000000..47b882c --- /dev/null +++ b/src/components/Collapsible.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import ResizeObserver from 'resize-observer-polyfill'; + +import { framerMotionResouce } from '../misc/motion'; + +const { memo, useState, useRef, useEffect } = React; + +function usePrevious(value) { + const ref = useRef(); + useEffect(() => void (ref.current = value), [value]); + return ref.current; +} + +function useMeasure() { + const ref = useRef(); + const [bounds, set] = useState({ height: 0 }); + useEffect(() => { + const ro = new ResizeObserver(([entry]) => set(entry.contentRect)); + if (ref.current) ro.observe(ref.current); + return () => ro.disconnect(); + }, []); + return [ref, bounds]; +} + +const variantsCollpapsibleWrap = { + initialOpen: { + height: 'auto', + transition: { duration: 0 }, + }, + open: (height) => ({ + height, + opacity: 1, + visibility: 'visible', + transition: { duration: 0.3 }, + }), + closed: { + height: 0, + opacity: 0, + visibility: 'hidden', + overflowY: 'hidden', + transition: { duration: 0.3 }, + }, +}; + +const variantsCollpapsibleChildContainer = { + open: {}, + closed: {}, +}; + +// @ts-expect-error ts-migrate(2339) FIXME: Property 'isOpen' does not exist on type '{ childr... Remove this comment to see the full error message +const Collapsible = memo(({ children, isOpen }) => { + const module = framerMotionResouce.read(); + const motion = module.motion; + const previous = usePrevious(isOpen); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'height' does not exist on type 'MutableR... Remove this comment to see the full error message + const [refToMeature, { height }] = useMeasure(); + return ( +
+ + + {children} + + +
+ ); +}); + +export default Collapsible; diff --git a/src/components/CollapsibleSectionHeader.module.scss b/src/components/CollapsibleSectionHeader.module.scss new file mode 100644 index 0000000..b654f35 --- /dev/null +++ b/src/components/CollapsibleSectionHeader.module.scss @@ -0,0 +1,39 @@ +.header { + display: flex; + align-items: center; + + &:focus { + outline: none; + } + + .arrow { + display: inline-flex; + transform: rotate(0deg); + transition: transform 0.3s; + + &.isOpen { + transform: rotate(180deg); + } + + &:focus { + outline: var(--color-focus-blue) solid 1px; + } + } +} + +.btn { + margin-left: 5px; +} + +/* TODO duplicate with connQty in Connections.module.css */ +.qty { + font-family: var(--font-normal); + font-size: 0.75em; + margin-left: 3px; + padding: 2px 7px; + display: inline-flex; + justify-content: center; + align-items: center; + background-color: var(--bg-near-transparent); + border-radius: 30px; +} diff --git a/src/components/CollapsibleSectionHeader.tsx b/src/components/CollapsibleSectionHeader.tsx new file mode 100644 index 0000000..8b701e1 --- /dev/null +++ b/src/components/CollapsibleSectionHeader.tsx @@ -0,0 +1,49 @@ +import cx from 'clsx'; +import * as React from 'react'; +import { ChevronDown } from 'react-feather'; + +import Button from './Button'; +import s from './CollapsibleSectionHeader.module.scss'; +import { SectionNameType } from './shared/Basic'; + +type Props = { + name: string; + type: string; + qty?: number; + toggle?: () => void; + isOpen?: boolean; +}; + +export default function Header({ name, type, toggle, isOpen, qty }: Props) { + const handleKeyDown = React.useCallback( + (e: React.KeyboardEvent) => { + e.preventDefault(); + if (e.key === 'Enter' || e.key === ' ') { + toggle(); + } + }, + [toggle] + ); + return ( +
+
+ +
+ + {typeof qty === 'number' ? {qty} : null} + + +
+ ); +} diff --git a/src/components/Config.module.scss b/src/components/Config.module.scss new file mode 100644 index 0000000..b9998a3 --- /dev/null +++ b/src/components/Config.module.scss @@ -0,0 +1,43 @@ +@import '~/styles/utils/custom-media'; + +.root, +.section { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(49%, 1fr)); + max-width: 900px; + gap: 5px; + @media (--breakpoint-not-small) { + gap: 15px; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + } +} + +.root, +.section { + padding: 6px 15px 10px; + @media (--breakpoint-not-small) { + padding: 10px 40px 15px; + } +} + +.wrapSwitch { + height: 40px; + display: flex; + align-items: center; +} + +.sep { + max-width: 900px; + padding: 0 15px; + @media (--breakpoint-not-small) { + padding: 0 40px; + } + > div { + border-top: 1px dashed #373737; + } +} + +.label { + padding: 15px 0; + font-size: small; +} diff --git a/src/components/Config.tsx b/src/components/Config.tsx new file mode 100644 index 0000000..84be48e --- /dev/null +++ b/src/components/Config.tsx @@ -0,0 +1,403 @@ +import * as React from 'react'; +import { DownloadCloud, LogOut, RotateCw, Trash2 } from 'react-feather'; +import { useTranslation } from 'react-i18next'; +import { useQuery } from 'react-query'; + +import * as logsApi from '~/api/logs'; +import { fetchVersion } from '~/api/version'; +import Select from '~/components/shared/Select'; +import { ClashGeneralConfig, DispatchFn, State } from '~/store/types'; +import { ClashAPIConfig } from '~/types'; + +import { getClashAPIConfig, getLatencyTestUrl, getSelectedChartStyleIndex } from '../store/app'; +import { + fetchConfigs, + flushFakeIPPool, + getConfigs, + reloadConfigFile, + updateConfigs, + updateGeoDatabasesFile, +} from '../store/configs'; +import { openModal } from '../store/modals'; +import Button from './Button'; +import s0 from './Config.module.scss'; +import ContentHeader from './ContentHeader'; +import Input, { SelfControlledInput } from './Input'; +import { Selection2 } from './Selection'; +import { connect, useStoreActions } from './StateProvider'; +import Switch from './SwitchThemed'; +import TrafficChartSample from './TrafficChartSample'; + +const { useEffect, useState, useCallback, useRef } = React; + +const propsList = [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }]; + +const logLeveOptions = [ + ['debug', 'Debug'], + ['info', 'Info'], + ['warning', 'Warning'], + ['error', 'Error'], + ['silent', 'Silent'], +]; + +const portFields = [ + { key: 'port', label: 'Http Port' }, + { key: 'socks-port', label: 'Socks5 Port' }, + { key: 'mixed-port', label: 'Mixed Port' }, + { key: 'redir-port', label: 'Redir Port' }, + { key: 'mitm-port', label: 'MITM Port' }, +]; + +const langOptions = [ + ['zh', '中文'], + ['en', 'English'], +]; + +const modeOptions = [ + ['direct', 'Direct'], + ['rule', 'Rule'], + ['script', 'Script'], + ['global', 'Global'], +]; + +const tunStackOptions = [ + ['gvisor', 'gVisor'], + ['system', 'System'], + ['lwip', 'LWIP'], +]; + +const mapState = (s: State) => ({ + configs: getConfigs(s), + apiConfig: getClashAPIConfig(s), +}); + +const mapState2 = (s: State) => ({ + selectedChartStyleIndex: getSelectedChartStyleIndex(s), + latencyTestUrl: getLatencyTestUrl(s), + apiConfig: getClashAPIConfig(s), +}); + +const Config = connect(mapState2)(ConfigImpl); +export default connect(mapState)(ConfigContainer); + +function ConfigContainer({ dispatch, configs, apiConfig }) { + useEffect(() => { + dispatch(fetchConfigs(apiConfig)); + }, [dispatch, apiConfig]); + return ; +} + +type ConfigImplProps = { + dispatch: DispatchFn; + configs: ClashGeneralConfig; + selectedChartStyleIndex: number; + latencyTestUrl: string; + apiConfig: ClashAPIConfig; +}; + +function ConfigImpl({ + dispatch, + configs, + selectedChartStyleIndex, + latencyTestUrl, + apiConfig, +}: ConfigImplProps) { + const { t, i18n } = useTranslation(); + + const [configState, setConfigStateInternal] = useState(configs); + const refConfigs = useRef(configs); + useEffect(() => { + if (refConfigs.current !== configs) { + setConfigStateInternal(configs); + } + refConfigs.current = configs; + }, [configs]); + + const openAPIConfigModal = useCallback(() => { + dispatch(openModal('apiConfig')); + }, [dispatch]); + + const setConfigState = useCallback( + (name: string, val: any) => { + setConfigStateInternal({ ...configState, [name]: val }); + }, + [configState] + ); + + const setTunConfigState = useCallback( + (name: any, val: any) => { + const tun = { ...configState.tun, [name]: val }; + setConfigStateInternal({ ...configState, tun: { ...tun } }); + }, + [configState] + ); + + const handleInputOnChange = useCallback( + ({ name, value }) => { + switch (name) { + case 'mode': + case 'log-level': + case 'allow-lan': + case 'sniffing': + setConfigState(name, value); + dispatch(updateConfigs(apiConfig, { [name]: value })); + if (name === 'log-level') { + logsApi.reconnect({ ...apiConfig, logLevel: value }); + } + break; + case 'mitm-port': + case 'redir-port': + case 'socks-port': + case 'mixed-port': + case 'port': + if (value !== '') { + const num = parseInt(value, 10); + if (num < 0 || num > 65535) return; + } + setConfigState(name, value); + break; + case 'enable': + case 'stack': + setTunConfigState(name, value); + dispatch(updateConfigs(apiConfig, { tun: { [name]: value } })); + break; + default: + return; + } + }, + [apiConfig, dispatch, setConfigState, setTunConfigState] + ); + + const { selectChartStyleIndex, updateAppConfig } = useStoreActions(); + + const handleInputOnBlur = useCallback( + ( + e: + | React.FocusEvent + | React.ChangeEvent + ) => { + const { name, value } = e.target; + + switch (name) { + case 'port': + case 'socks-port': + case 'mixed-port': + case 'redir-port': + case 'mitm-port': { + const num = parseInt(value, 10); + if (num < 0 || num > 65535) return; + dispatch(updateConfigs(apiConfig, { [name]: num })); + break; + } + case 'latencyTestUrl': { + updateAppConfig(name, value); + break; + } + case 'device name': + case 'interface name': + break; + default: + throw new Error(`unknown input name ${name}`); + } + }, + [apiConfig, dispatch, updateAppConfig] + ); + const handleReloadConfigFile = useCallback(() => { + dispatch(reloadConfigFile(apiConfig)); + }, [apiConfig, dispatch]); + + const handleUpdateGeoDatabasesFile = useCallback(() => { + dispatch(updateGeoDatabasesFile(apiConfig)); + }, [apiConfig, dispatch]); + + const handleFlushFakeIPPool = useCallback(() => { + dispatch(flushFakeIPPool(apiConfig)); + }, [apiConfig, dispatch]); + + const { data: version } = useQuery(['/version', apiConfig], () => + fetchVersion('/version', apiConfig) + ); + + return ( +
+ +
+ {portFields.map((f) => + configState[f.key] !== undefined ? ( +
+
{f.label}
+ handleInputOnChange({ name, value })} + onBlur={handleInputOnBlur} + /> +
+ ) : null + )} + +
+
Mode
+ handleInputOnChange({ name: 'log-level', value: e.target.value })} + /> +
+ +
+
{t('allow_lan')}
+
+ + handleInputOnChange({ name: 'allow-lan', value: value }) + } + /> +
+
+ {version.meta && ( +
+
{t('tls_sniffing')}
+
+ + handleInputOnChange({ name: 'sniffing', value: value }) + } + /> +
+
+ )} +
+
+
+
+ {version.meta && ( + <> +
+
+
{t('enable_tun_device')}
+
+ + handleInputOnChange({ name: 'enable', value: value }) + } + /> +
+
+
+
TUN IP Stack
+ +
+
+
Interface Name
+ +
+
+
+
+
+
+
+
Reload
+
+
+
GEO Databases
+
+
+
FakeIP
+
+
+
+
+
+ + )} + +
+
+
{t('latency_test_url')}
+ +
+
+
{t('lang')}
+
+ setFilterKeyword(e.target.value)} + /> +
+
+
+
+ + <>{renderTableOrPlaceholder(filteredConns)} + : } + mainButtonStyles={isRefreshPaused ? { background: '#e74c3c' } : {}} + style={fabPosition} + text={isRefreshPaused ? t('Resume Refresh') : t('Pause Refresh')} + onClick={toggleIsRefreshPaused} + > + + + + + + {renderTableOrPlaceholder(filteredClosedConns)} +
+
+ + +
+ ); +} + +const mapState = (s: State) => ({ + apiConfig: getClashAPIConfig(s), +}); + +export default connect(mapState)(Conn); diff --git a/src/components/ContentHeader.module.scss b/src/components/ContentHeader.module.scss new file mode 100644 index 0000000..3fc4cc7 --- /dev/null +++ b/src/components/ContentHeader.module.scss @@ -0,0 +1,18 @@ +@import '~/styles/utils/custom-media'; + +.root { + height: 76px; + display: flex; + align-items: center; +} + +.h1 { + padding: 0 15px; + font-size: 1.7em; + @media (--breakpoint-not-small) { + padding: 0 40px; + font-size: 2em; + } + text-align: left; + margin: 0; +} diff --git a/src/components/ContentHeader.tsx b/src/components/ContentHeader.tsx new file mode 100644 index 0000000..473cd4c --- /dev/null +++ b/src/components/ContentHeader.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +import s0 from './ContentHeader.module.scss'; + +type Props = { + title: string; +}; + +function ContentHeader({ title }: Props) { + return ( +
+

{title}

+
+ ); +} + +export default React.memo(ContentHeader); diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx new file mode 100644 index 0000000..f95c581 --- /dev/null +++ b/src/components/ErrorBoundary.tsx @@ -0,0 +1,32 @@ +import * as React from 'react'; + +// import { getSentry } from '../misc/sentry'; +import { deriveMessageFromError, Err } from '../misc/errors'; +import ErrorBoundaryFallback from './ErrorBoundaryFallback'; + +type Props = { + children: React.ReactNode; +}; + +type State = { + error?: Err; +}; + +class ErrorBoundary extends React.Component { + state = { error: null }; + + static getDerivedStateFromError(error: Err) { + return { error }; + } + + render() { + if (this.state.error) { + const { message, detail } = deriveMessageFromError(this.state.error); + return ; + } else { + return this.props.children; + } + } +} + +export default ErrorBoundary; diff --git a/src/components/ErrorBoundaryFallback.module.scss b/src/components/ErrorBoundaryFallback.module.scss new file mode 100644 index 0000000..6133568 --- /dev/null +++ b/src/components/ErrorBoundaryFallback.module.scss @@ -0,0 +1,37 @@ +.root { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow: hidden; + + padding: 20px; + background: var(--color-background); + color: var(--color-text); + text-align: center; +} + +.yacd { + color: #2a477a; + opacity: 0.6; + display: flex; + justify-content: center; + align-items: center; + padding: 40px; +} + +.link { + display: inline-flex; + align-items: center; + + color: var(--color-text-secondary); + &:hover, + &:active { + color: #387cec; + } + + svg { + margin-right: 5px; + } +} diff --git a/src/components/ErrorBoundaryFallback.tsx b/src/components/ErrorBoundaryFallback.tsx new file mode 100644 index 0000000..9f41d91 --- /dev/null +++ b/src/components/ErrorBoundaryFallback.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +import s0 from './ErrorBoundaryFallback.module.scss'; +import SvgGithub from './SvgGithub'; +import SvgYacd from './SvgYacd'; +const yacdRepoIssueUrl = 'https://github.com/metacubex/yacd'; + +type Props = { + message?: string; + detail?: string; +}; + +function ErrorBoundaryFallback({ message, detail }: Props) { + return ( +
+
+ +
+ {message ?

{message}

: null} + {detail ?

{detail}

: null} +

+ + + metacubex/yacd + +

+
+ ); +} + +export default ErrorBoundaryFallback; diff --git a/src/components/Field.module.scss b/src/components/Field.module.scss new file mode 100644 index 0000000..72a5149 --- /dev/null +++ b/src/components/Field.module.scss @@ -0,0 +1,42 @@ +.root { + position: relative; + padding: 10px 0; + input { + -webkit-appearance: none; + background-color: transparent; + background-image: none; + border: none; + border-radius: 0; + border-bottom: 1px solid var(--color-input-border); + box-sizing: border-box; + color: inherit; + display: inline-block; + font-size: inherit; + height: 40px; + outline: none; + padding: 0 4px; + width: 100%; + &:focus { + border-color: var(--color-focus-blue); + } + } + + label { + position: absolute; + left: 5px; + bottom: 22px; + transition: transform 150ms ease-in-out; + transform-origin: 0 0; + font-size: 0.9em; + &.floatAbove { + transform: scale(0.75) translateY(-25px); + } + } + + input { + &:focus + label { + color: var(--color-focus-blue); + transform: scale(0.75) translateY(-25px); + } + } +} diff --git a/src/components/Field.tsx b/src/components/Field.tsx new file mode 100644 index 0000000..a0d43cf --- /dev/null +++ b/src/components/Field.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; + +import s from './Field.module.scss'; + +const { useCallback } = React; + +type Props = { + name: string; + value?: string | number; + type?: 'text' | 'number'; + onChange?: (...args: any[]) => any; + id?: string; + label?: string; + placeholder?: string; +}; + +export default function Field({ id, label, value, onChange, ...props }: Props) { + const valueOnChange = useCallback((e) => onChange(e), [onChange]); + return ( +
+ + +
+ ); +} diff --git a/src/components/Home.module.scss b/src/components/Home.module.scss new file mode 100644 index 0000000..cd1fe30 --- /dev/null +++ b/src/components/Home.module.scss @@ -0,0 +1,8 @@ +@import '~/styles/utils/custom-media'; + +.root { + padding: 6px 15px; + @media (--breakpoint-not-small) { + padding: 10px 40px; + } +} diff --git a/src/components/Home.tsx b/src/components/Home.tsx new file mode 100644 index 0000000..d7ddbab --- /dev/null +++ b/src/components/Home.tsx @@ -0,0 +1,27 @@ +import React, { Suspense } from 'react'; +import { useTranslation } from 'react-i18next'; + +import ContentHeader from './ContentHeader'; +import s0 from './Home.module.scss'; +import Loading from './Loading'; +import TrafficChart from './TrafficChart'; +import TrafficNow from './TrafficNow'; + +export default function Home() { + const { t } = useTranslation(); + return ( +
+ +
+
+ +
+
+ }> + + +
+
+
+ ); +} diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx new file mode 100644 index 0000000..560fb6d --- /dev/null +++ b/src/components/Icon.tsx @@ -0,0 +1,20 @@ +import cx from 'clsx'; +import React from 'react'; + +type Props = { + id: string; + width?: number; + height?: number; + className?: string; +}; + +const Icon = ({ id, width = 20, height = 20, className, ...props }: Props) => { + const c = cx('icon', id, className); + const href = '#' + id; + return ( + + + + ); +}; +export default React.memo(Icon); diff --git a/src/components/Input.module.scss b/src/components/Input.module.scss new file mode 100644 index 0000000..021fe18 --- /dev/null +++ b/src/components/Input.module.scss @@ -0,0 +1,26 @@ +.input { + -webkit-appearance: none; + background-color: var(--color-input-bg); + background-image: none; + border-radius: 4px; + border: 1px solid var(--color-input-border); + box-sizing: border-box; + color: inherit; + display: inline-block; + font-size: inherit; + height: 35px; + outline: none; + padding: 0 15px; + width: 100%; + font-size: small; +} + +.input:focus { + box-shadow: rgba(66, 153, 225, 0.6) 0px 0px 0px 3px; +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} diff --git a/src/components/Input.tsx b/src/components/Input.tsx new file mode 100644 index 0000000..ade19b2 --- /dev/null +++ b/src/components/Input.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +import s0 from './Input.module.scss'; + +const { useState, useRef, useEffect, useCallback } = React; + +export default function Input(props: React.InputHTMLAttributes) { + return ; +} + +export function SelfControlledInput({ value, ...restProps }) { + const [internalValue, setInternalValue] = useState(value); + const refValue = useRef(value); + useEffect(() => { + if (refValue.current !== value) { + // ideally we should only do this when this input is not focused + setInternalValue(value); + } + refValue.current = value; + }, [value]); + const onChange = useCallback((e) => setInternalValue(e.target.value), [setInternalValue]); + + return ; +} diff --git a/src/components/Loading.module.scss b/src/components/Loading.module.scss new file mode 100644 index 0000000..c3f1d16 --- /dev/null +++ b/src/components/Loading.module.scss @@ -0,0 +1,28 @@ +.loading { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.spinner { + width: 20px; + height: 20px; + display: inline-block; + vertical-align: middle; + animation: rotate 1s steps(12, end) infinite; + background: transparent + url('data:image/svg+xml;charset=utf8, %3Csvg xmlns="http://www.w3.org/2000/svg" width="120" height="120" viewBox="0 0 100 100"%3E%3Cpath fill="none" d="M0 0h100v100H0z"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23E9E9E9" rx="5" ry="5" transform="translate(0 -30)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23989697" rx="5" ry="5" transform="rotate(30 105.98 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%239B999A" rx="5" ry="5" transform="rotate(60 75.98 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23A3A1A2" rx="5" ry="5" transform="rotate(90 65 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23ABA9AA" rx="5" ry="5" transform="rotate(120 58.66 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23B2B2B2" rx="5" ry="5" transform="rotate(150 54.02 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23BAB8B9" rx="5" ry="5" transform="rotate(180 50 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23C2C0C1" rx="5" ry="5" transform="rotate(-150 45.98 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23CBCBCB" rx="5" ry="5" transform="rotate(-120 41.34 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23D2D2D2" rx="5" ry="5" transform="rotate(-90 35 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23DADADA" rx="5" ry="5" transform="rotate(-60 24.02 65)"/%3E%3Crect width="7" height="20" x="46.5" y="40" fill="%23E2E2E2" rx="5" ry="5" transform="rotate(-30 -5.98 65)"/%3E%3C/svg%3E') + no-repeat; + background-size: 100%; +} + +@keyframes rotate { + 0% { + transform: rotate3d(0, 0, 1, 0deg); + } + 100% { + transform: rotate3d(0, 0, 1, 360deg); + } +} diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx new file mode 100644 index 0000000..12ced75 --- /dev/null +++ b/src/components/Loading.tsx @@ -0,0 +1,18 @@ +import React from 'react'; + +import s from './Loading.module.scss'; + +type Props = { + height?: string; +}; + +const Loading = ({ height }: Props) => { + const style = height ? { height } : {}; + return ( +
+
+
+ ); +}; + +export default Loading; diff --git a/src/components/Loading2.module.scss b/src/components/Loading2.module.scss new file mode 100644 index 0000000..067281e --- /dev/null +++ b/src/components/Loading2.module.scss @@ -0,0 +1,8 @@ +.lo { + opacity: 0.5; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/src/components/Loading2.tsx b/src/components/Loading2.tsx new file mode 100644 index 0000000..b847eb4 --- /dev/null +++ b/src/components/Loading2.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import s0 from './Loading2.module.scss'; +import SvgYacd from './SvgYacd'; + +function Loading() { + return ( +
+ +
+ ); +} + +export default Loading; diff --git a/src/components/LogSearch.ts b/src/components/LogSearch.ts new file mode 100644 index 0000000..9c7879f --- /dev/null +++ b/src/components/LogSearch.ts @@ -0,0 +1,6 @@ +import { getSearchText, updateSearchText } from '../store/logs'; +import Search from './Search'; +import { connect } from './StateProvider'; + +const mapState = (s) => ({ searchText: getSearchText(s), updateSearchText }); +export default connect(mapState)(Search); diff --git a/src/components/Logs.module.scss b/src/components/Logs.module.scss new file mode 100644 index 0000000..2eb0022 --- /dev/null +++ b/src/components/Logs.module.scss @@ -0,0 +1,75 @@ +.logMeta { + font-size: 0.8em; + margin-bottom: 5px; + display: block; + line-height: 1.55em; +} + +.logType { + flex-shrink: 0; + text-align: center; + width: 66px; + border-radius: 100px; + padding: 3px 5px; + margin: 0 8px; +} + +.logTime { + flex-shrink: 0; + color: #fb923c; +} + +.logText { + flex-shrink: 0; + color: #888; + align-items: center; + line-height: 1.35em; + /* force wrap */ + width: 100%; + @media (max-width: 768px) { + display: inline-block; + } +} + +/*******************/ + +.logsWrapper { + margin: 45px; + padding: 10px; + background-color: var(--bg-log-info-card); + border-radius: 4px; + color: var(--color-text); + overflow-y: auto; + @media (max-width: 768px) { + margin: 25px; + } + :global { + .log { + margin-bottom: 10px; + //background: var(--color-background); + } + .log.even { + //background: var(--color-background); + } + } +} + +/*******************/ + +.logPlaceholder { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: #2d2d30; + + div:nth-child(2) { + color: var(--color-text-secondary); + font-size: 1.4em; + opacity: 0.6; + } +} + +.logPlaceholderIcon { + opacity: 0.3; +} diff --git a/src/components/Logs.tsx b/src/components/Logs.tsx new file mode 100644 index 0000000..e672eed --- /dev/null +++ b/src/components/Logs.tsx @@ -0,0 +1,106 @@ +import * as React from 'react'; +import { Pause, Play } from 'react-feather'; +import { useTranslation } from 'react-i18next'; + +import { fetchLogs, reconnect as reconnectLogs, stop as stopLogs } from '~/api/logs'; +import ContentHeader from '~/components/ContentHeader'; +import LogSearch from '~/components/LogSearch'; +import { connect, useStoreActions } from '~/components/StateProvider'; +import SvgYacd from '~/components/SvgYacd'; +import useRemainingViewPortHeight from '~/hooks/useRemainingViewPortHeight'; +import { getClashAPIConfig, getLogStreamingPaused } from '~/store/app'; +import { getLogLevel } from '~/store/configs'; +import { appendLog, getLogsForDisplay } from '~/store/logs'; +import { Log, State } from '~/store/types'; + +import s from './Logs.module.scss'; +import { Fab, position as fabPosition } from './shared/Fab'; + +const { useCallback, useEffect } = React; + +const paddingBottom = 30; +const colors = { + debug: '#389d3d', + info: '#58c3f2', + warning: '#cc5abb', + error: '#c11c1c', +}; + +const logTypes = { + debug: 'debug', + info: 'info', + warning: 'warn', + error: 'error', +}; + +type LogLineProps = Partial; + +function LogLine({ time, payload, type }: LogLineProps) { + return ( +
+ {time} + + [ {logTypes[type]} ] + + {payload} +
+ ); +} + +function Logs({ dispatch, logLevel, apiConfig, logs, logStreamingPaused }) { + const actions = useStoreActions(); + const toggleIsRefreshPaused = useCallback(() => { + logStreamingPaused ? reconnectLogs({ ...apiConfig, logLevel }) : stopLogs(); + // being lazy here + // ideally we should check the result of previous operation before updating this + actions.app.updateAppConfig('logStreamingPaused', !logStreamingPaused); + }, [apiConfig, logLevel, logStreamingPaused, actions.app]); + const appendLogInternal = useCallback((log) => dispatch(appendLog(log)), [dispatch]); + useEffect(() => { + fetchLogs({ ...apiConfig, logLevel }, appendLogInternal); + }, [apiConfig, logLevel, appendLogInternal]); + const [refLogsContainer, containerHeight] = useRemainingViewPortHeight(); + const { t } = useTranslation(); + + return ( +
+ + +
+ {logs.length === 0 ? ( +
+
+ +
+
{t('no_logs')}
+
+ ) : ( +
+ {logs.map((log, index) => ( +
+ +
+ ))} + + : } + mainButtonStyles={logStreamingPaused ? { background: '#e74c3c' } : {}} + style={fabPosition} + text={logStreamingPaused ? t('Resume Refresh') : t('Pause Refresh')} + onClick={toggleIsRefreshPaused} + > +
+ )} +
+
+ ); +} + +const mapState = (s: State) => ({ + logs: getLogsForDisplay(s), + logLevel: getLogLevel(s), + apiConfig: getClashAPIConfig(s), + logStreamingPaused: getLogStreamingPaused(s), +}); + +export default connect(mapState)(Logs); diff --git a/src/components/Modal.module.scss b/src/components/Modal.module.scss new file mode 100644 index 0000000..8f9807c --- /dev/null +++ b/src/components/Modal.module.scss @@ -0,0 +1,21 @@ +.overlay { + position: fixed; + top: 0; + right: 0; + left: 0; + bottom: 0; + background: #444; + z-index: 1024; +} + +.content { + outline: none; + position: relative; + color: var(--color-text); + background: #444; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 20px; + border-radius: 10px; +} diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx new file mode 100644 index 0000000..e91523c --- /dev/null +++ b/src/components/Modal.tsx @@ -0,0 +1,38 @@ +import cx from 'clsx'; +import * as React from 'react'; +import Modal, { Props as ReactModalProps } from 'react-modal'; + +import s0 from './Modal.module.scss'; + +type Props = ReactModalProps & { + isOpen: boolean; + onRequestClose: (...args: any[]) => any; + children: React.ReactNode; + className?: string; + overlayClassName?: string; +}; + +function ModalAPIConfig({ + isOpen, + onRequestClose, + className, + overlayClassName, + children, + ...otherProps +}: Props) { + const contentCls = cx(className, s0.content); + const overlayCls = cx(overlayClassName, s0.overlay); + return ( + + {children} + + ); +} + +export default React.memo(ModalAPIConfig); diff --git a/src/components/ModalCloseAllConnections.module.scss b/src/components/ModalCloseAllConnections.module.scss new file mode 100644 index 0000000..9bb7c6a --- /dev/null +++ b/src/components/ModalCloseAllConnections.module.scss @@ -0,0 +1,23 @@ +.overlay { + background-color: rgba(0, 0, 0, 0.6); +} +.cnt { + background-color: var(--bg-modal); + color: var(--color-text); + max-width: 300px; + line-height: 1.4; + transform: translate(-50%, -50%) scale(1.2); + opacity: 0.6; + transition: all 0.3s ease; +} +.afterOpen { + opacity: 1; + transform: translate(-50%, -50%) scale(1); +} + +.btngrp { + display: flex; + align-items: center; + justify-content: center; + margin-top: 30px; +} diff --git a/src/components/ModalCloseAllConnections.tsx b/src/components/ModalCloseAllConnections.tsx new file mode 100644 index 0000000..a2c4303 --- /dev/null +++ b/src/components/ModalCloseAllConnections.tsx @@ -0,0 +1,43 @@ +import cx from 'clsx'; +import React from 'react'; +import Modal from 'react-modal'; + +import Button from './Button'; +import modalStyle from './Modal.module.scss'; +import s from './ModalCloseAllConnections.module.scss'; + +const { useRef, useCallback, useMemo } = React; + +export default function Comp({ isOpen, onRequestClose, primaryButtonOnTap }) { + const primaryButtonRef = useRef(null); + const onAfterOpen = useCallback(() => { + primaryButtonRef.current.focus(); + }, []); + const className = useMemo( + () => ({ + base: cx(modalStyle.content, s.cnt), + afterOpen: s.afterOpen, + beforeClose: '', + }), + [] + ); + return ( + +

Are you sure you want to close all connections?

+
+ + {/* im lazy :) */} +
+ +
+ + ); +} diff --git a/src/components/Rule.module.scss b/src/components/Rule.module.scss new file mode 100644 index 0000000..e4652b0 --- /dev/null +++ b/src/components/Rule.module.scss @@ -0,0 +1,38 @@ +@import '~/styles/utils/custom-media'; + +.rule { + display: flex; + align-items: center; + padding: 6px 15px; + @media (--breakpoint-not-small) { + padding: 10px 40px; + } +} + +.left { + width: 40px; + padding-right: 15px; + color: var(--color-text-secondary); + opacity: 0.4; +} + +.a { + display: flex; + align-items: center; + font-size: 12px; + opacity: 0.8; +} + +.b { + padding: 10px 0; + font-family: 'Roboto Mono', Menlo, monospace; + font-size: 12px; + @media (--breakpoint-not-small) { + font-size: 12px; + } +} + +.type { + width: 110px; + color: #3b5f76; +} diff --git a/src/components/Rule.tsx b/src/components/Rule.tsx new file mode 100644 index 0000000..b8ff70f --- /dev/null +++ b/src/components/Rule.tsx @@ -0,0 +1,42 @@ +import React from 'react'; + +import s0 from './Rule.module.scss'; + +const colorMap = { + _default: '#59caf9', + DIRECT: '#f5bc41', + REJECT: '#cb3166', +}; + +function getStyleFor({ proxy }) { + let color = colorMap._default; + if (colorMap[proxy]) { + color = colorMap[proxy]; + } + return { color }; +} + +type Props = { + id?: number; + type?: string; + payload?: string; + proxy?: string; +}; + +function Rule({ type, payload, proxy, id }: Props) { + const styleProxy = getStyleFor({ proxy }); + return ( +
+
{id}
+
+
{payload}
+
+
{type}
+
{proxy}
+
+
+
+ ); +} + +export default Rule; diff --git a/src/components/Rules.module.scss b/src/components/Rules.module.scss new file mode 100644 index 0000000..9c4e017 --- /dev/null +++ b/src/components/Rules.module.scss @@ -0,0 +1,23 @@ +@import '~/styles/utils/custom-media'; + +.header { + display: grid; + grid-template-columns: 1fr minmax(auto, 330px); + align-items: center; + + /* + * the content header has some padding + * we need to apply some right padding to this container then + */ + padding-right: 15px; + @media (--breakpoint-not-small) { + padding-right: 40px; + } +} + +.RuleProviderItemWrapper { + padding: 6px 15px; + @media (--breakpoint-not-small) { + padding: 10px 40px; + } +} diff --git a/src/components/Rules.tsx b/src/components/Rules.tsx new file mode 100644 index 0000000..2d72515 --- /dev/null +++ b/src/components/Rules.tsx @@ -0,0 +1,115 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { areEqual, VariableSizeList } from 'react-window'; + +import { RuleProviderItem } from '~/components/rules/RuleProviderItem'; +import { useRuleAndProvider } from '~/components/rules/rules.hooks'; +import { RulesPageFab } from '~/components/rules/RulesPageFab'; +import { TextFilter } from '~/components/shared/TextFitler'; +import { ruleFilterText } from '~/store/rules'; +import { State } from '~/store/types'; +import { ClashAPIConfig } from '~/types'; + +import useRemainingViewPortHeight from '../hooks/useRemainingViewPortHeight'; +import { getClashAPIConfig } from '../store/app'; +import ContentHeader from './ContentHeader'; +import Rule from './Rule'; +import s from './Rules.module.scss'; +import { connect } from './StateProvider'; + +const { memo } = React; + +const paddingBottom = 30; + +type ItemData = { + rules: any[]; + provider: any; + apiConfig: ClashAPIConfig; +}; + +function itemKey(index: number, { rules, provider }: ItemData) { + const providerQty = provider.names.length; + + if (index < providerQty) { + return provider.names[index]; + } + const item = rules[index - providerQty]; + return item.id; +} + +function getItemSizeFactory({ provider }) { + return function getItemSize(idx: number) { + const providerQty = provider.names.length; + if (idx < providerQty) { + // provider + return 90; + } + // rule + return 60; + }; +} + +// @ts-expect-error ts-migrate(2339) FIXME: Property 'index' does not exist on type '{ childre... Remove this comment to see the full error message +const Row = memo(({ index, style, data }) => { + const { rules, provider, apiConfig } = data; + const providerQty = provider.names.length; + + if (index < providerQty) { + const name = provider.names[index]; + const item = provider.byName[name]; + return ( +
+ +
+ ); + } + + const r = rules[index - providerQty]; + return ( +
+ +
+ ); +}, areEqual); + +const mapState = (s: State) => ({ + apiConfig: getClashAPIConfig(s), +}); + +export default connect(mapState)(Rules); + +type RulesProps = { + apiConfig: ClashAPIConfig; +}; + +function Rules({ apiConfig }: RulesProps) { + const [refRulesContainer, containerHeight] = useRemainingViewPortHeight(); + const { rules, provider } = useRuleAndProvider(apiConfig); + const getItemSize = getItemSizeFactory({ provider }); + + const { t } = useTranslation(); + + return ( +
+
+ + +
+
+ + {Row} + +
+ {provider && provider.names && provider.names.length > 0 ? ( + + ) : null} +
+ ); +} diff --git a/src/components/Search.module.scss b/src/components/Search.module.scss new file mode 100644 index 0000000..58c20aa --- /dev/null +++ b/src/components/Search.module.scss @@ -0,0 +1,47 @@ +.RuleSearch { + padding: 0 40px 5px; + @media (max-width: 768px) { + padding: 0 25px 5px; + } +} + +.RuleSearchContainer { + position: relative; + height: 40px; + @media (max-width: 768px) { + height: 30px; + } +} + +.inputWrapper { + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 0; + width: 100%; +} + +.input { + -webkit-appearance: none; + background-color: var(--color-input-bg); + background-image: none; + border-radius: 20px; + border: 1px solid var(--color-input-border); + box-sizing: border-box; + color: #c1c1c1; + display: inline-block; + font-size: inherit; + height: 40px; + outline: none; + padding: 0 15px 0 35px; + transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); + width: 100%; +} + +.iconWrapper { + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 10px; + line-height: 0; +} diff --git a/src/components/Search.tsx b/src/components/Search.tsx new file mode 100644 index 0000000..0e0269c --- /dev/null +++ b/src/components/Search.tsx @@ -0,0 +1,46 @@ +import debounce from 'lodash-es/debounce'; +import React, { useCallback, useMemo, useState } from 'react'; +import { Search as SearchIcon } from 'react-feather'; +import { useTranslation } from 'react-i18next'; + +import s0 from './Search.module.scss'; + +function RuleSearch({ dispatch, searchText, updateSearchText }) { + const { t } = useTranslation(); + const [text, setText] = useState(searchText); + const updateSearchTextInternal = useCallback( + (v) => { + dispatch(updateSearchText(v)); + }, + [dispatch, updateSearchText] + ); + const updateSearchTextDebounced = useMemo( + () => debounce(updateSearchTextInternal, 300), + [updateSearchTextInternal] + ); + const onChange = (e) => { + setText(e.target.value); + updateSearchTextDebounced(e.target.value); + }; + + return ( +
+
+
+ +
+
+ +
+
+
+ ); +} + +export default RuleSearch; diff --git a/src/components/Selection.module.scss b/src/components/Selection.module.scss new file mode 100644 index 0000000..5fa4576 --- /dev/null +++ b/src/components/Selection.module.scss @@ -0,0 +1,23 @@ +.fieldset { + margin: 0; + padding: 0; + border: 0; + display: flex; + flex-wrap: wrap; + flex-direction: row; +} + +.input + .cnt { + border: 1px solid transparent; + border-radius: 4px; + cursor: pointer; + margin-bottom: 5px; +} + +.input:focus + .cnt { + border-color: #387cec; +} + +.input:checked + .cnt { + border-color: #387cec; +} diff --git a/src/components/Selection.tsx b/src/components/Selection.tsx new file mode 100644 index 0000000..1b1f50e --- /dev/null +++ b/src/components/Selection.tsx @@ -0,0 +1,45 @@ +import cx from 'clsx'; +import React from 'react'; + +import s from './Selection.module.scss'; + +type SelectionProps = { + OptionComponent?: (...args: any[]) => any; + optionPropsList?: any[]; + selectedIndex?: number; + onChange?: (...args: any[]) => any; +}; + +export function Selection2({ + OptionComponent, + optionPropsList, + selectedIndex, + onChange, +}: SelectionProps) { + const inputCx = cx('visually-hidden', s.input); + const onInputChange = (e: React.ChangeEvent) => { + onChange(e.target.value); + }; + return ( +
+ {optionPropsList.map((props, idx) => { + return ( + + ); + })} +
+ ); +} diff --git a/src/components/SideBar.module.scss b/src/components/SideBar.module.scss new file mode 100644 index 0000000..ade5bf5 --- /dev/null +++ b/src/components/SideBar.module.scss @@ -0,0 +1,112 @@ +@import '~/styles/utils/custom-media'; + +.root { + background: var(--color-bg-sidebar); + min-width: 150px; + position: relative; +} + +.logoPlaceholder { + margin-top: 12px; + height: 120px; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3FpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQyIDc5LjE2MDkyNCwgMjAxNy8wNy8xMy0wMTowNjozOSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo1OGE5MDMzMS0zZWM3LTRhNGItOTUyNS1mZDNlYTZmZDU5ZGUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTFENDRDNEQ1OEQxMTFFQ0JBRjI4MzI2MEM4NEU4NDkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTFENDRDNEM1OEQxMTFFQ0JBRjI4MzI2MEM4NEU4NDkiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE1NWRkNmQzLTczOTItMmM0ZC1iNzQxLWYzY2JhYWQ5NjUxOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1OGE5MDMzMS0zZWM3LTRhNGItOTUyNS1mZDNlYTZmZDU5ZGUiLz4gPC9y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'); + background-size: 80px; + background-repeat: no-repeat; + background-position: center; + @media (max-width: 768px) { + display: none; + } +} + +.rows { + @media (max-width: 768px) { + display: flex; + justify-content: space-between; + overflow: auto; + } +} + +/* a router link */ +.row { + color: var(--color-text); + text-decoration: none; + + display: flex; + align-items: center; + padding: 6px 10px; + @media (--breakpoint-not-small) { + padding: 8px 20px; + } + + @media (max-width: 768px) { + flex-direction: column; + } + + svg { + color: var(--color-icon); + width: 22px; + height: 22px; + + @media (--breakpoint-not-small) { + width: 24px; + height: 24px; + } + } +} + +.rowActive { + background: var(--color-sb-active-row-bg); + + @media (max-width: 768px) { + background: none; + border-bottom: 2px solid #387cec; + } +} + +.label { + padding-left: 14px; + font-size: 0.75em; + @media (max-width: 768px) { + padding-left: 0; + padding-top: 5px; + } + + @media (--breakpoint-not-small) { + font-size: 1em; + } +} + +.footer { + position: absolute; + bottom: 10px; + left: 50%; + transform: translateX(-50%); +} + +@media (max-width: 768px) { + .footer { + display: none; + } +} + +.iconWrapper { + --sz: 40px; + + width: var(--sz); + height: var(--sz); + display: flex; + justify-content: center; + align-items: center; + + outline: none; + padding: 5px; + color: var(--color-text); + border-radius: 100%; + border: 1px solid transparent; +} +.iconWrapper:hover { + opacity: 0.6; +} +.iconWrapper:focus { + border-color: var(--color-focus-blue); +} diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx new file mode 100644 index 0000000..6ebd21e --- /dev/null +++ b/src/components/SideBar.tsx @@ -0,0 +1,105 @@ +import { Tooltip } from '@reach/tooltip'; +import cx from 'clsx'; +import * as React from 'react'; +import { Info } from 'react-feather'; +import { useTranslation } from 'react-i18next'; +import { FcAreaChart, FcDocument, FcGlobe, FcLink, FcRuler, FcSettings } from 'react-icons/fc'; +import { Link, useLocation } from 'react-router-dom'; + +import { ThemeSwitcher } from '~/components/shared/ThemeSwitcher'; + +import s from './SideBar.module.scss'; + +const icons = { + activity: FcAreaChart, + globe: FcGlobe, + command: FcRuler, + file: FcDocument, + settings: FcSettings, + link: FcLink, +}; + +const SideBarRow = React.memo(function SideBarRow({ + isActive, + to, + iconId, + labelText, +}: SideBarRowProps) { + const Comp = icons[iconId]; + const className = cx(s.row, isActive ? s.rowActive : null); + return ( + + +
{labelText}
+ + ); +}); + +interface SideBarRowProps { + isActive: boolean; + to: string; + iconId?: string; + labelText?: string; +} + +const pages = [ + { + to: '/', + iconId: 'activity', + labelText: 'Overview', + }, + { + to: '/proxies', + iconId: 'globe', + labelText: 'Proxies', + }, + { + to: '/rules', + iconId: 'command', + labelText: 'Rules', + }, + { + to: '/connections', + iconId: 'link', + labelText: 'Conns', + }, + { + to: '/configs', + iconId: 'settings', + labelText: 'Config', + }, + { + to: '/logs', + iconId: 'file', + labelText: 'Logs', + }, +]; + +export default function SideBar() { + const { t } = useTranslation(); + const location = useLocation(); + return ( +
+
+
+ {pages.map(({ to, iconId, labelText }) => ( + + ))} +
+
+ + + + + + +
+
+ ); +} diff --git a/src/components/StateProvider.tsx b/src/components/StateProvider.tsx new file mode 100644 index 0000000..1ef48d7 --- /dev/null +++ b/src/components/StateProvider.tsx @@ -0,0 +1,99 @@ +import produce, * as immer from 'immer'; +import React from 'react'; + +// in logs store we update logs in place +// outside of immer produce +// this is just workaround +immer.setAutoFreeze(false); + +const { createContext, memo, useMemo, useRef, useEffect, useCallback, useContext, useState } = + React; + +export { immer }; + +const StateContext = createContext(null); +const DispatchContext = createContext(null); +const ActionsContext = createContext(null); + +export function useStoreState() { + return useContext(StateContext); +} + +export function useStoreDispatch() { + return useContext(DispatchContext); +} + +export function useStoreActions() { + return useContext(ActionsContext); +} + +// boundActionCreators +export default function Provider({ initialState, actions = {}, children }) { + const stateRef = useRef(initialState); + const [state, setState] = useState(initialState); + const getState = useCallback(() => stateRef.current, []); + useEffect(() => { + if (process.env.NODE_ENV === 'development') { + (window as any).getState2 = getState; + } + }, [getState]); + const dispatch = useCallback( + (actionId: string | ((a: any, b: any) => any), fn: (s: any) => void) => { + if (typeof actionId === 'function') return actionId(dispatch, getState); + + const stateNext = produce(getState(), fn); + if (stateNext !== stateRef.current) { + if (process.env.NODE_ENV === 'development') { + // eslint-disable-next-line no-console + console.log(actionId, stateNext); + } + stateRef.current = stateNext; + setState(stateNext); + } + }, + [getState] + ); + const boundActions = useMemo(() => bindActions(actions, dispatch), [actions, dispatch]); + + return ( + + + {children} + + + ); +} + +export function connect(mapStateToProps: any) { + return (Component: any) => { + const MemoComponent = memo(Component); + function Connected(props: any) { + const state = useContext(StateContext); + const dispatch = useContext(DispatchContext); + const mapped = mapStateToProps(state, props); + const nextProps = { dispatch, ...props, ...mapped }; + return ; + } + return Connected; + }; +} + +// steal from https://github.com/reduxjs/redux/blob/master/src/bindActionCreators.ts +function bindAction(action: any, dispatch: any) { + return function (...args: any[]) { + return dispatch(action.apply(this, args)); + }; +} + +function bindActions(actions: any, dispatch: any) { + const boundActions = {}; + for (const key in actions) { + const action = actions[key]; + if (typeof action === 'function') { + boundActions[key] = bindAction(action, dispatch); + } else if (typeof action === 'object') { + boundActions[key] = bindActions(action, dispatch); + } + } + return boundActions; +} diff --git a/src/components/StyleGuide.tsx b/src/components/StyleGuide.tsx new file mode 100644 index 0000000..7b5cf6d --- /dev/null +++ b/src/components/StyleGuide.tsx @@ -0,0 +1,71 @@ +import React, { PureComponent } from 'react'; +import { Zap } from 'react-feather'; + +import Loading from '~/components/Loading'; + +import Button from './Button'; +import Input from './Input'; +import SwitchThemed from './SwitchThemed'; +import ToggleSwitch from './ToggleSwitch'; + +const noop = () => { + /* empty */ +}; + +const paneStyle = { + padding: '20px 0', +}; + +const optionsRule = [ + { label: 'Global', value: 'Global' }, + { label: 'Rule', value: 'Rule' }, + { label: 'Direct', value: 'Direct' }, +]; + +const Pane = ({ children, style }) =>
{children}
; + +function useToggle(initialState = false) { + const [onoff, setonoff] = React.useState(initialState); + const handleChange = React.useCallback(() => { + setonoff((x) => !x); + }, []); + return [onoff, handleChange]; +} + +function SwitchExample() { + const [checked, handleChange] = useToggle(false); + return ; +} + +class StyleGuide extends PureComponent { + render() { + return ( +
+ {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */} + + + + {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */} + + + + {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */} + + + + {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */} + +
+ ); + } +} + +export default StyleGuide; diff --git a/src/components/SvgGithub.tsx b/src/components/SvgGithub.tsx new file mode 100644 index 0000000..45828c2 --- /dev/null +++ b/src/components/SvgGithub.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +type Props = { + width?: number; + height?: number; +}; + +export default function SvgGithub({ width = 24, height = 24 }: Props = {}) { + return ( + + + + ); +} diff --git a/src/components/SvgYacd.module.scss b/src/components/SvgYacd.module.scss new file mode 100644 index 0000000..f668137 --- /dev/null +++ b/src/components/SvgYacd.module.scss @@ -0,0 +1,14 @@ +.path { + stroke-dasharray: 890; + stroke-dashoffset: 890; + animation: dash 3s ease-in-out forwards normal infinite; +} + +@keyframes dash { + from { + stroke-dashoffset: 890; + } + to { + stroke-dashoffset: 0; + } +} diff --git a/src/components/SvgYacd.tsx b/src/components/SvgYacd.tsx new file mode 100644 index 0000000..d7c1b2f --- /dev/null +++ b/src/components/SvgYacd.tsx @@ -0,0 +1,92 @@ +import cx from 'clsx'; +import * as React from 'react'; + +import s from './SvgYacd.module.scss'; + +type Props = { + width?: number; + height?: number; + animate?: boolean; + c0?: string; + c1?: string; + stroke?: string; + eye?: string; + line?: string; +}; + +function SvgYacd({ + width = 320, + height = 320, + animate = false, + c0 = '#316eb5', + c1 = '#f19500', + line = '#cccccc', +}: Props) { + const faceClasName = cx({ [s.path]: animate }); + return ( + + + + + + + + + ); +} + +export default SvgYacd; diff --git a/src/components/SwitchThemed.tsx b/src/components/SwitchThemed.tsx new file mode 100644 index 0000000..aba10d1 --- /dev/null +++ b/src/components/SwitchThemed.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import ReactSwitch from 'react-switch'; + +import { State } from '~/store/types'; + +import { getTheme } from '../store/app'; +import { connect } from './StateProvider'; + +// workaround https://github.com/vitejs/vite/issues/2139#issuecomment-802981228 +// @ts-ignore +const Switch = ReactSwitch.default ? ReactSwitch.default : ReactSwitch; + +function SwitchThemed({ checked = false, onChange, theme, name }) { + const offColor = theme === 'dark' ? '#393939' : '#e9e9e9'; + + return ( + + ); +} + +export default connect((s: State) => ({ theme: getTheme(s) }))(SwitchThemed); diff --git a/src/components/ToggleSwitch.module.scss b/src/components/ToggleSwitch.module.scss new file mode 100644 index 0000000..4b1388c --- /dev/null +++ b/src/components/ToggleSwitch.module.scss @@ -0,0 +1,39 @@ +.ToggleSwitch { + user-select: none; + border-radius: 4px; + border: 1px solid #525252; + color: var(--color-text); + background: var(--color-toggle-bg); + display: flex; + position: relative; + outline: none; + + &:focus { + border-color: var(--color-focus-blue); + } + + input { + position: absolute; + left: 0; + opacity: 0; + } + + label { + z-index: 2; + display: flex; + align-items: center; + justify-content: center; + padding: 10px 0; + cursor: pointer; + } +} + +.slider { + z-index: 1; + position: absolute; + display: block; + left: 0; + height: 100%; + transition: left 0.2s ease-out; + background: var(--color-toggle-selected); +} diff --git a/src/components/ToggleSwitch.tsx b/src/components/ToggleSwitch.tsx new file mode 100644 index 0000000..58400c9 --- /dev/null +++ b/src/components/ToggleSwitch.tsx @@ -0,0 +1,65 @@ +import React, { useCallback, useMemo } from 'react'; + +import s0 from './ToggleSwitch.module.scss'; + +type Props = { + options?: any[]; + value?: string; + name?: string; + onChange?: (...args: any[]) => any; +}; + +function ToggleSwitch({ options, value, name, onChange }: Props) { + const idxSelected = useMemo(() => options.map((o) => o.value).indexOf(value), [options, value]); + + const getPortionPercentage = useCallback( + (idx: number) => { + const w = Math.floor(100 / options.length); + if (idx === options.length - 1) { + return 100 - options.length * w + w; + } else if (idx > -1) { + return w; + } + }, + [options] + ); + + const sliderStyle = useMemo(() => { + return { + width: getPortionPercentage(idxSelected) + '%', + left: idxSelected * getPortionPercentage(0) + '%', + }; + }, [idxSelected, getPortionPercentage]); + + return ( +
+
+ {options.map((o, idx) => { + const id = `${name}-${o.label}`; + const className = idx === 0 ? '' : 'border-left'; + return ( + + ); + })} +
+ ); +} + +export default React.memo(ToggleSwitch); diff --git a/src/components/TrafficChart.tsx b/src/components/TrafficChart.tsx new file mode 100644 index 0000000..a6fdf27 --- /dev/null +++ b/src/components/TrafficChart.tsx @@ -0,0 +1,61 @@ +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { State } from '~/store/types'; + +import { fetchData } from '../api/traffic'; +import useLineChart from '../hooks/useLineChart'; +import { chartJSResource, chartStyles, commonDataSetProps } from '../misc/chart'; +import { getClashAPIConfig, getSelectedChartStyleIndex } from '../store/app'; +import { connect } from './StateProvider'; + +const { useMemo } = React; + +const chartWrapperStyle = { + // make chartjs chart responsive + position: 'relative', + maxWidth: 1000, + marginTop: '1em', +}; + +const mapState = (s: State) => ({ + apiConfig: getClashAPIConfig(s), + selectedChartStyleIndex: getSelectedChartStyleIndex(s), +}); + +export default connect(mapState)(TrafficChart); + +function TrafficChart({ apiConfig, selectedChartStyleIndex }) { + const ChartMod = chartJSResource.read(); + const traffic = fetchData(apiConfig); + const { t } = useTranslation(); + const data = useMemo( + () => ({ + labels: traffic.labels, + datasets: [ + { + ...commonDataSetProps, + ...chartStyles[selectedChartStyleIndex].up, + label: t('Up'), + data: traffic.up, + }, + { + ...commonDataSetProps, + ...chartStyles[selectedChartStyleIndex].down, + label: t('Down'), + data: traffic.down, + }, + ], + }), + [traffic, selectedChartStyleIndex, t] + ); + + useLineChart(ChartMod.Chart, 'trafficChart', data, traffic); + + return ( + // @ts-expect-error ts-migrate(2322) FIXME: Type '{ position: string; maxWidth: number; }' is ... Remove this comment to see the full error message +
+ +
+ ); +} diff --git a/src/components/TrafficChartSample.tsx b/src/components/TrafficChartSample.tsx new file mode 100644 index 0000000..00372f0 --- /dev/null +++ b/src/components/TrafficChartSample.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; + +import useLineChart from '../hooks/useLineChart'; +import { chartJSResource, chartStyles, commonDataSetProps } from '../misc/chart'; + +const { useMemo } = React; + +const extraChartOptions: import('chart.js').ChartOptions<'line'> = { + plugins: { + legend: { display: false }, + }, + scales: { + x: { display: false, type: 'category' }, + y: { display: false, type: 'linear' }, + }, +}; + +const data1 = [23e3, 35e3, 46e3, 33e3, 90e3, 68e3, 23e3, 45e3]; +const data2 = [184e3, 183e3, 196e3, 182e3, 190e3, 186e3, 182e3, 189e3]; +const labels = data1; + +export default function TrafficChart({ id }) { + const ChartMod = chartJSResource.read(); + + const data = useMemo( + () => ({ + labels, + datasets: [ + { + ...commonDataSetProps, + ...chartStyles[id].up, + data: data1, + }, + { + ...commonDataSetProps, + ...chartStyles[id].down, + data: data2, + }, + ], + }), + [id] + ); + + const eleId = 'chart-' + id; + useLineChart(ChartMod.Chart, eleId, data, null, extraChartOptions); + + return ( +
+ +
+ ); +} diff --git a/src/components/TrafficNow.module.scss b/src/components/TrafficNow.module.scss new file mode 100644 index 0000000..a150b32 --- /dev/null +++ b/src/components/TrafficNow.module.scss @@ -0,0 +1,28 @@ +.TrafficNow { + color: var(--color-text); + display: flex; + align-items: center; + flex-wrap: wrap; + justify-content: space-between; + max-width: 1000px; + + .sec { + padding: 10px; + width: 19%; + margin: 3px; + background-color: var(--color-bg-card); + border-radius: 10px; + box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.1); + div:nth-child(1) { + color: var(--color-text-secondary); + font-size: 0.65em; + } + div:nth-child(2) { + padding: 10px 0 0; + font-size: 1em; + } + @media (max-width: 768px) { + width: 48%; + } + } +} diff --git a/src/components/TrafficNow.tsx b/src/components/TrafficNow.tsx new file mode 100644 index 0000000..b82594c --- /dev/null +++ b/src/components/TrafficNow.tsx @@ -0,0 +1,81 @@ +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import * as connAPI from '../api/connections'; +import { fetchData } from '../api/traffic'; +import prettyBytes from '../misc/pretty-bytes'; +import { getClashAPIConfig } from '../store/app'; +import { connect } from './StateProvider'; +import s0 from './TrafficNow.module.scss'; + +const { useState, useEffect, useCallback } = React; + +const mapState = (s) => ({ + apiConfig: getClashAPIConfig(s), +}); +export default connect(mapState)(TrafficNow); + +function TrafficNow({ apiConfig }) { + const { t } = useTranslation(); + const { upStr, downStr } = useSpeed(apiConfig); + const { upTotal, dlTotal, connNumber } = useConnection(apiConfig); + return ( +
+
+
{t('Upload')}
+
{upStr}
+
+
+
{t('Download')}
+
{downStr}
+
+
+
{t('Upload Total')}
+
{upTotal}
+
+
+
{t('Download Total')}
+
{dlTotal}
+
+
+
{t('Active Connections')}
+
{connNumber}
+
+
+ ); +} + +function useSpeed(apiConfig) { + const [speed, setSpeed] = useState({ upStr: '0 B/s', downStr: '0 B/s' }); + useEffect(() => { + return fetchData(apiConfig).subscribe((o) => + setSpeed({ + upStr: prettyBytes(o.up) + '/s', + downStr: prettyBytes(o.down) + '/s', + }) + ); + }, [apiConfig]); + return speed; +} + +function useConnection(apiConfig) { + const [state, setState] = useState({ + upTotal: '0 B', + dlTotal: '0 B', + connNumber: 0, + }); + const read = useCallback( + ({ downloadTotal, uploadTotal, connections }) => { + setState({ + upTotal: prettyBytes(uploadTotal), + dlTotal: prettyBytes(downloadTotal), + connNumber: connections.length, + }); + }, + [setState] + ); + useEffect(() => { + return connAPI.fetchData(apiConfig, read); + }, [apiConfig, read]); + return state; +} diff --git a/src/components/about/About.module.scss b/src/components/about/About.module.scss new file mode 100644 index 0000000..7ed1aa5 --- /dev/null +++ b/src/components/about/About.module.scss @@ -0,0 +1,20 @@ +@import '~/styles/utils/custom-media'; + +.root { + padding: 6px 15px; + @media (--breakpoint-not-small) { + padding: 10px 40px; + } +} + +.mono { + font-family: var(--font-mono); +} + +.link { + color: var(--color-text-secondary); + display: inline-flex; +} +.link:hover { + color: var(--color-text-highlight); +} diff --git a/src/components/about/About.tsx b/src/components/about/About.tsx new file mode 100644 index 0000000..383e3f7 --- /dev/null +++ b/src/components/about/About.tsx @@ -0,0 +1,56 @@ +import * as React from 'react'; +import { GitHub } from 'react-feather'; +import { useQuery } from 'react-query'; + +import { fetchVersion } from '~/api/version'; +import ContentHeader from '~/components/ContentHeader'; +import { connect } from '~/components/StateProvider'; +import { getClashAPIConfig } from '~/store/app'; +import { ClashAPIConfig } from '~/types'; + +import s from './About.module.scss'; + +type Props = { apiConfig: ClashAPIConfig }; + +function Version({ name, link, version }: { name: string; link: string; version: string }) { + return ( +
+

{name}

+

+ Version + {version} +

+

+ + + Source + +

+
+ ); +} + +function AboutImpl(props: Props) { + const { data: version } = useQuery(['/version', props.apiConfig], () => + fetchVersion('/version', props.apiConfig) + ); + return ( + <> + + {version && version.version ? ( + + ) : null} + + + ); +} + +const mapState = (s) => ({ + apiConfig: getClashAPIConfig(s), +}); + +export const About = connect(mapState)(AboutImpl); diff --git a/src/components/proxies/ClosePrevConns.tsx b/src/components/proxies/ClosePrevConns.tsx new file mode 100644 index 0000000..6718fb2 --- /dev/null +++ b/src/components/proxies/ClosePrevConns.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; + +import Button from '../Button'; +import { FlexCenter } from '../shared/Styled'; + +const { useRef, useEffect } = React; + +type Props = { + onClickPrimaryButton?: () => void; + onClickSecondaryButton?: () => void; +}; + +export function ClosePrevConns({ onClickPrimaryButton, onClickSecondaryButton }: Props) { + const primaryButtonRef = useRef(null); + const secondaryButtonRef = useRef(null); + useEffect(() => { + primaryButtonRef.current.focus(); + }, []); + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.keyCode === 39) { + secondaryButtonRef.current.focus(); + } else if (e.keyCode === 37) { + primaryButtonRef.current.focus(); + } + }; + + return ( + // eslint-disable-next-line jsx-a11y/no-static-element-interactions +
+

Close Connections?

+

+ Click 'Yes' to close those connections that are still using the old selected proxy in this + group +

+
+ + +
+ + +
+ ); +} diff --git a/src/components/proxies/Proxies.module.scss b/src/components/proxies/Proxies.module.scss new file mode 100644 index 0000000..d3295cd --- /dev/null +++ b/src/components/proxies/Proxies.module.scss @@ -0,0 +1,38 @@ +@import '~/styles/utils/custom-media'; + +.topBar { + position: sticky; + top: 0; + + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + z-index: 1; + background-color: var(--color-background2); + backdrop-filter: blur(36px); +} + +.topBarRight { + display: flex; + align-items: center; + flex-wrap: wrap; + flex: 1; + justify-content: flex-end; + + margin-right: 20px; +} + +.textFilterContainer { + max-width: 350px; + min-width: 150px; + flex: 1; + margin-right: 8px; +} + +.group { + padding: 10px 15px; + @media (--breakpoint-not-small) { + padding: 10px 40px; + } +} diff --git a/src/components/proxies/Proxies.tsx b/src/components/proxies/Proxies.tsx new file mode 100644 index 0000000..7c6fd48 --- /dev/null +++ b/src/components/proxies/Proxies.tsx @@ -0,0 +1,128 @@ +import { Tooltip } from '@reach/tooltip'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import Button from '~/components/Button'; +import ContentHeader from '~/components/ContentHeader'; +import { ClosePrevConns } from '~/components/proxies/ClosePrevConns'; +import { ProxyGroup } from '~/components/proxies/ProxyGroup'; +import { ProxyPageFab } from '~/components/proxies/ProxyPageFab'; +import { ProxyProviderList } from '~/components/proxies/ProxyProviderList'; +import Settings from '~/components/proxies/Settings'; +import BaseModal from '~/components/shared/BaseModal'; +import { TextFilter } from '~/components/shared/TextFitler'; +import { connect, useStoreActions } from '~/components/StateProvider'; +import Equalizer from '~/components/svg/Equalizer'; +import { getClashAPIConfig } from '~/store/app'; +import { + fetchProxies, + getDelay, + getProxyGroupNames, + getProxyProviders, + getShowModalClosePrevConns, + proxyFilterText, +} from '~/store/proxies'; +import type { State } from '~/store/types'; + +import s0 from './Proxies.module.scss'; + +const { useState, useEffect, useCallback, useRef } = React; + +function Proxies({ + dispatch, + groupNames, + delay, + proxyProviders, + apiConfig, + showModalClosePrevConns, +}) { + const refFetchedTimestamp = useRef<{ startAt?: number; completeAt?: number }>({}); + + const fetchProxiesHooked = useCallback(() => { + refFetchedTimestamp.current.startAt = Date.now(); + dispatch(fetchProxies(apiConfig)).then(() => { + refFetchedTimestamp.current.completeAt = Date.now(); + }); + }, [apiConfig, dispatch]); + useEffect(() => { + // fetch it now + fetchProxiesHooked(); + + // arm a window on focus listener to refresh it + const fn = () => { + if ( + refFetchedTimestamp.current.startAt && + Date.now() - refFetchedTimestamp.current.startAt > 3e4 // 30s + ) { + fetchProxiesHooked(); + } + }; + window.addEventListener('focus', fn, false); + return () => window.removeEventListener('focus', fn, false); + }, [fetchProxiesHooked]); + + const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); + const closeSettingsModal = useCallback(() => { + setIsSettingsModalOpen(false); + }, []); + + const { + proxies: { closeModalClosePrevConns, closePrevConnsAndTheModal }, + } = useStoreActions(); + + const { t } = useTranslation(); + + return ( + <> + + + +
+ +
+
+ +
+ + + +
+
+
+ {groupNames.map((groupName: string) => { + return ( +
+ +
+ ); + })} +
+ +
+ + + closePrevConnsAndTheModal(apiConfig)} + onClickSecondaryButton={closeModalClosePrevConns} + /> + + + ); +} + +const mapState = (s: State) => ({ + apiConfig: getClashAPIConfig(s), + groupNames: getProxyGroupNames(s), + proxyProviders: getProxyProviders(s), + delay: getDelay(s), + showModalClosePrevConns: getShowModalClosePrevConns(s), +}); + +export default connect(mapState)(Proxies); diff --git a/src/components/proxies/Proxy.module.scss b/src/components/proxies/Proxy.module.scss new file mode 100644 index 0000000..a4ac16c --- /dev/null +++ b/src/components/proxies/Proxy.module.scss @@ -0,0 +1,103 @@ +@import '~/styles/utils/custom-media'; + +.proxy { + padding: 5px; + position: relative; + border-radius: 8px; + overflow: hidden; + + display: flex; + flex-direction: column; + justify-content: space-between; + + outline: none; + border: 2px solid transparent; + + &:focus { + border-color: var(--color-focus-blue); + } + + @media (--breakpoint-not-small) { + border-radius: 10px; + padding: 10px; + } + + background-color: var(--color-bg-proxy); + + &.now { + background-color: var(--color-focus-blue); + color: #ddd; + } + + &.error { + opacity: 0.5; + } + &.selectable { + transition: transform 0.2s ease-in-out; + cursor: pointer; + &:hover { + border-color: hsl(0deg, 0%, var(--card-hover-border-lightness)); + } + } +} + +.proxyType { + font-family: var(--font-mono); + font-size: 0.6em; + @media (--breakpoint-not-small) { + font-size: 0.7em; + } +} +.udpType { + font-family: var(--font-mono); + font-size: 0.6em; + margin-right: 3px; + @media (--breakpoint-not-small) { + font-size: 0.7em; + } +} +.tfoType { + padding: 2px; +} +.row { + display: flex; + align-items: center; + justify-content: space-between; +} + +.proxyName { + width: 100%; + margin-bottom: 5px; + font-size: 0.85em; + @media (--breakpoint-not-small) { + font-size: 0.85em; + } +} + +.proxySmall { + position: relative; + width: 10px; + height: 10px; + border-radius: 50%; + + .now { + position: absolute; + width: 6px; + height: 6px; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: 50%; + background-color: white; + } + + &.selectable { + transition: transform 0.1s ease-in-out; + cursor: pointer; + &:hover { + transform: scale(1.2); + } + } +} diff --git a/src/components/proxies/Proxy.tsx b/src/components/proxies/Proxy.tsx new file mode 100644 index 0000000..1aa6bb3 --- /dev/null +++ b/src/components/proxies/Proxy.tsx @@ -0,0 +1,231 @@ +import { TooltipPopup, useTooltip } from '@reach/tooltip'; +import cx from 'clsx'; +import * as React from 'react'; + +import { keyCodes } from '~/misc/keycode'; +import { + getLatencyTestUrl, +} from '~/store/app'; +import { ProxyItem } from '~/store/types'; + +import { getDelay, getProxies, NonProxyTypes } from '../../store/proxies'; +import { connect } from '../StateProvider'; +import s0 from './Proxy.module.scss'; +import { ProxyLatency } from './ProxyLatency'; + +const { useMemo } = React; + +const colorMap = { + // green + good: '#67c23a', + // yellow + normal: '#d4b75c', + // orange + bad: '#e67f3c', + // bad: '#F56C6C', + na: '#909399', +}; + +function getLabelColor({ + number, +}: { + number?: number; +} = {}, + httpsTest: boolean) { + const delayMap = { + good: httpsTest ? 800 : 200, + normal: httpsTest ? 1500 : 500, + }; + if (number === 0) { + return colorMap.na; + } else if (number < delayMap.good) { + return colorMap.good; + } else if (number < delayMap.normal) { + return colorMap.normal; + } else if (typeof number === 'number') { + return colorMap.bad; + } + return colorMap.na; +} + +function getProxyDotBackgroundColor( + latency: { + number?: number; + }, + proxyType: string, + httpsTest: boolean, +) { + if (NonProxyTypes.indexOf(proxyType) > -1) { + return 'linear-gradient(135deg, white 15%, #999 15% 30%, white 30% 45%, #999 45% 60%, white 60% 75%, #999 75% 90%, white 90% 100%)'; + } + return getLabelColor(latency, httpsTest); +} + +type ProxyProps = { + name: string; + now?: boolean; + proxy: ProxyItem; + latency: any; + httpsLatencyTest: boolean, + isSelectable?: boolean; + udp: boolean; + tfo: boolean; + onClick?: (proxyName: string) => unknown; +}; + +function ProxySmallImpl({ now, name, proxy, latency, httpsLatencyTest, isSelectable, onClick }: ProxyProps) { + const color = useMemo(() => getProxyDotBackgroundColor(latency, proxy.type, httpsLatencyTest), [latency, proxy]); + const title = useMemo(() => { + let ret = name; + if (latency && typeof latency.number === 'number') { + ret += ' ' + latency.number + ' ms'; + } + return ret; + }, [name, latency]); + + const doSelect = React.useCallback(() => { + isSelectable && onClick && onClick(name); + }, [name, onClick, isSelectable]); + + const handleKeyDown = React.useCallback( + (e: React.KeyboardEvent) => { + if (e.keyCode === keyCodes.Enter) { + doSelect(); + } + }, + [doSelect] + ); + + return ( +
+ {now &&
} +
+ ); +} + +function formatProxyType(t: string) { + if (t === 'Shadowsocks') return 'SS'; + return t; +} + +const positionProxyNameTooltip = (triggerRect: { left: number; top: number }) => { + return { + left: triggerRect.left + window.scrollX - 5, + top: triggerRect.top + window.scrollY - 38, + }; +}; + +function ProxyNameTooltip({ children, label, 'aria-label': ariaLabel }) { + const [trigger, tooltip] = useTooltip(); + return ( + <> + {React.cloneElement(children, trigger)} + + + ); +} + +function ProxyImpl({ now, name, proxy, latency, httpsLatencyTest, isSelectable, onClick }: ProxyProps) { + const color = useMemo(() => getLabelColor(latency, httpsLatencyTest), [latency]); + const doSelect = React.useCallback(() => { + isSelectable && onClick && onClick(name); + }, [name, onClick, isSelectable]); + function formatUdpType(udp: boolean, xudp?: boolean) { + if (!udp) return ''; + return xudp ? 'XUDP' : 'UDP'; + } + function formatTfo(t: boolean) { + if (!t) return ''; + return ( + + + + ); + } + const handleKeyDown = React.useCallback( + (e: React.KeyboardEvent) => { + if (e.keyCode === keyCodes.Enter) { + doSelect(); + } + }, + [doSelect] + ); + const className = useMemo(() => { + return cx(s0.proxy, { + [s0.now]: now, + [s0.error]: latency && latency.error, + [s0.selectable]: isSelectable, + }); + }, [isSelectable, now, latency]); + + const latencyNumber = latency?.number ?? proxy.history[proxy.history.length - 1]?.delay; + + return ( +
+
+ + {name} + + + {formatUdpType(proxy.udp, proxy.xudp)} + +
+ +
+
+ + {formatProxyType(proxy.type)} + + + {formatTfo(proxy.tfo)} +
+ + {latencyNumber ? : null} +
+
+ ); +} + +const mapState = (s: any, { name }) => { + const proxies = getProxies(s); + const delay = getDelay(s); + const latencyTestUrl = getLatencyTestUrl(s); + return { + proxy: proxies[name], + latency: delay[name], + httpsLatencyTest: latencyTestUrl.startsWith('https://'), + }; +}; + +export const Proxy = connect(mapState)(ProxyImpl); +export const ProxySmall = connect(mapState)(ProxySmallImpl); diff --git a/src/components/proxies/ProxyGroup.module.scss b/src/components/proxies/ProxyGroup.module.scss new file mode 100644 index 0000000..5409ea8 --- /dev/null +++ b/src/components/proxies/ProxyGroup.module.scss @@ -0,0 +1,11 @@ +.header { + margin-bottom: 12px; +} + +.zapWrapper { + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/components/proxies/ProxyGroup.tsx b/src/components/proxies/ProxyGroup.tsx new file mode 100644 index 0000000..fb97e28 --- /dev/null +++ b/src/components/proxies/ProxyGroup.tsx @@ -0,0 +1,137 @@ +import * as React from 'react'; +import { Zap } from 'react-feather'; +import { useQuery } from 'react-query'; + +import * as proxiesAPI from '~/api/proxies'; +import { fetchVersion } from '~/api/version'; +import { + getCollapsibleIsOpen, + getHideUnavailableProxies, + getLatencyTestUrl, + getProxySortBy, +} from '~/store/app'; +import { fetchProxies, getProxies, switchProxy } from '~/store/proxies'; + +import Button from '../Button'; +import CollapsibleSectionHeader from '../CollapsibleSectionHeader'; +import { connect, useStoreActions } from '../StateProvider'; +import { useFilteredAndSorted } from './hooks'; +import s0 from './ProxyGroup.module.scss'; +import { ProxyList, ProxyListSummaryView } from './ProxyList'; + +const { createElement, useCallback, useMemo, useState } = React; + +function ZapWrapper() { + return ( +
+ +
+ ); +} + +function ProxyGroupImpl({ + name, + all: allItems, + delay, + hideUnavailableProxies, + proxySortBy, + proxies, + type, + now, + isOpen, + latencyTestUrl, + apiConfig, + dispatch, +}) { + const all = useFilteredAndSorted(allItems, delay, hideUnavailableProxies, proxySortBy, proxies); + + const { data: version } = useQuery(['/version', apiConfig], () => + fetchVersion('/version', apiConfig) + ); + + const isSelectable = useMemo( + () => ['Selector', version.meta && 'Fallback'].includes(type), + [type, version.meta] + ); + + const { + app: { updateCollapsibleIsOpen }, + proxies: { requestDelayForProxies }, + } = useStoreActions(); + + const toggle = useCallback(() => { + updateCollapsibleIsOpen('proxyGroup', name, !isOpen); + }, [isOpen, updateCollapsibleIsOpen, name]); + + const itemOnTapCallback = useCallback( + (proxyName) => { + if (!isSelectable) return; + dispatch(switchProxy(apiConfig, name, proxyName)); + }, + [apiConfig, dispatch, name, isSelectable] + ); + const [isTestingLatency, setIsTestingLatency] = useState(false); + const testLatency = useCallback(async () => { + setIsTestingLatency(true); + try { + if (version.meta === true) { + await proxiesAPI.requestDelayForProxyGroup(apiConfig, name, latencyTestUrl); + await dispatch(fetchProxies(apiConfig)); + } else { + await requestDelayForProxies(apiConfig, all); + await dispatch(fetchProxies(apiConfig)); + } + } catch (err) {} + setIsTestingLatency(false); + }, [all, apiConfig, dispatch, name, version.meta]); + + return ( +
+
+ + +
+ {createElement(isOpen ? ProxyList : ProxyListSummaryView, { + all, + now, + isSelectable, + itemOnTapCallback, + })} +
+ ); +} + +export const ProxyGroup = connect((s, { name, delay }) => { + const proxies = getProxies(s); + const collapsibleIsOpen = getCollapsibleIsOpen(s); + const proxySortBy = getProxySortBy(s); + const hideUnavailableProxies = getHideUnavailableProxies(s); + const latencyTestUrl = getLatencyTestUrl(s); + + const group = proxies[name]; + const { all, type, now } = group; + return { + all, + delay, + hideUnavailableProxies, + proxySortBy, + proxies, + type, + now, + isOpen: collapsibleIsOpen[`proxyGroup:${name}`], + latencyTestUrl, + }; +})(ProxyGroupImpl); diff --git a/src/components/proxies/ProxyLatency.module.scss b/src/components/proxies/ProxyLatency.module.scss new file mode 100644 index 0000000..e5a5b3f --- /dev/null +++ b/src/components/proxies/ProxyLatency.module.scss @@ -0,0 +1,10 @@ +@import '~/styles/utils/custom-media'; + +.proxyLatency { + border-radius: 20px; + color: #eee; + font-size: 0.6em; + @media (--breakpoint-not-small) { + font-size: 0.7em; + } +} diff --git a/src/components/proxies/ProxyLatency.tsx b/src/components/proxies/ProxyLatency.tsx new file mode 100644 index 0000000..48e55af --- /dev/null +++ b/src/components/proxies/ProxyLatency.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; + +import s0 from './ProxyLatency.module.scss'; + +type ProxyLatencyProps = { + number: number; + color: string; +}; + +export function ProxyLatency({ number, color }: ProxyLatencyProps) { + return ( + + {number} ms + + ); +} diff --git a/src/components/proxies/ProxyList.module.scss b/src/components/proxies/ProxyList.module.scss new file mode 100644 index 0000000..33f76f0 --- /dev/null +++ b/src/components/proxies/ProxyList.module.scss @@ -0,0 +1,19 @@ +@import '~/styles/utils/custom-media'; + +.list { + margin: 8px 0; + display: grid; + grid-gap: 10px; +} + +.detail { + grid-template-columns: auto auto; + + @media (--breakpoint-not-small) { + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + } +} + +.summary { + grid-template-columns: repeat(auto-fill, 12px); +} diff --git a/src/components/proxies/ProxyList.tsx b/src/components/proxies/ProxyList.tsx new file mode 100644 index 0000000..913e49b --- /dev/null +++ b/src/components/proxies/ProxyList.tsx @@ -0,0 +1,56 @@ +import cx from 'clsx'; +import * as React from 'react'; + +import { Proxy, ProxySmall } from './Proxy'; +import s from './ProxyList.module.scss'; + +type ProxyListProps = { + all: string[]; + now?: string; + isSelectable?: boolean; + itemOnTapCallback?: (x: string) => void; + show?: boolean; +}; + +export function ProxyList({ all, now, isSelectable, itemOnTapCallback }: ProxyListProps) { + const proxies = all; + + return ( +
+ {proxies.map((proxyName) => { + return ( + + ); + })} +
+ ); +} + +export function ProxyListSummaryView({ + all, + now, + isSelectable, + itemOnTapCallback, +}: ProxyListProps) { + return ( +
+ {all.map((proxyName) => { + return ( + + ); + })} +
+ ); +} diff --git a/src/components/proxies/ProxyPageFab.tsx b/src/components/proxies/ProxyPageFab.tsx new file mode 100644 index 0000000..2adb0a5 --- /dev/null +++ b/src/components/proxies/ProxyPageFab.tsx @@ -0,0 +1,79 @@ +import * as React from 'react'; +import { Zap } from 'react-feather'; +import { useTranslation } from 'react-i18next'; + +import { useUpdateProviderItems } from '~/components/proxies/proxies.hooks'; +import { Action, Fab, IsFetching, position as fabPosition } from '~/components/shared/Fab'; +import { RotateIcon } from '~/components/shared/RotateIcon'; +import { requestDelayAll } from '~/store/proxies'; +import { DispatchFn, FormattedProxyProvider } from '~/store/types'; +import { ClashAPIConfig } from '~/types'; + +const { useState, useCallback } = React; + +function StatefulZap({ isLoading }: { isLoading: boolean }) { + return isLoading ? ( + + + + ) : ( + + ); +} + +function useTestLatencyAction({ + dispatch, + apiConfig, +}: { + dispatch: DispatchFn; + apiConfig: ClashAPIConfig; +}): [() => unknown, boolean] { + const [isTestingLatency, setIsTestingLatency] = useState(false); + const requestDelayAllFn = useCallback(() => { + if (isTestingLatency) return; + + setIsTestingLatency(true); + dispatch(requestDelayAll(apiConfig)).then( + () => setIsTestingLatency(false), + () => setIsTestingLatency(false) + ); + }, [apiConfig, dispatch, isTestingLatency]); + return [requestDelayAllFn, isTestingLatency]; +} + +export function ProxyPageFab({ + dispatch, + apiConfig, + proxyProviders, +}: { + dispatch: DispatchFn; + apiConfig: ClashAPIConfig; + proxyProviders: FormattedProxyProvider[]; +}) { + const { t } = useTranslation(); + const [requestDelayAllFn, isTestingLatency] = useTestLatencyAction({ + dispatch, + apiConfig, + }); + + const [updateProviders, isUpdating] = useUpdateProviderItems({ + apiConfig, + dispatch, + names: proxyProviders.map((item) => item.name), + }); + + return ( + } + onClick={requestDelayAllFn} + text={t('Test Latency')} + style={fabPosition} + > + {proxyProviders.length > 0 ? ( + + + + ) : null} + + ); +} diff --git a/src/components/proxies/ProxyProvider.module.scss b/src/components/proxies/ProxyProvider.module.scss new file mode 100644 index 0000000..223b089 --- /dev/null +++ b/src/components/proxies/ProxyProvider.module.scss @@ -0,0 +1,32 @@ +@import '~/styles/utils/custom-media'; + +.updatedAt { + margin-bottom: 12px; + small { + color: #777; + } +} + +.body { + padding: 10px 15px; + @media (--breakpoint-not-small) { + padding: 10px 40px; + } +} + +.actionFooter { + display: flex; + button { + margin: 0 5px; + &:first-child { + margin-left: 0; + } + } +} + +.refresh { + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; +} diff --git a/src/components/proxies/ProxyProvider.tsx b/src/components/proxies/ProxyProvider.tsx new file mode 100644 index 0000000..289293c --- /dev/null +++ b/src/components/proxies/ProxyProvider.tsx @@ -0,0 +1,197 @@ +import { formatDistance } from 'date-fns'; +import * as React from 'react'; +import { RotateCw, Zap } from 'react-feather'; + +import Button from '~/components/Button'; +import Collapsible from '~/components/Collapsible'; +import CollapsibleSectionHeader from '~/components/CollapsibleSectionHeader'; +import { useUpdateProviderItem } from '~/components/proxies/proxies.hooks'; +import { connect, useStoreActions } from '~/components/StateProvider'; +import { framerMotionResouce } from '~/misc/motion'; +import { + getClashAPIConfig, + getCollapsibleIsOpen, + getHideUnavailableProxies, + getProxySortBy, +} from '~/store/app'; +import { getDelay, healthcheckProviderByName } from '~/store/proxies'; +import { DelayMapping, SubscriptionInfo } from '~/store/types'; + +import { useFilteredAndSorted } from './hooks'; +import { ProxyList, ProxyListSummaryView } from './ProxyList'; +import s from './ProxyProvider.module.scss'; + +const { useState, useCallback } = React; + +type Props = { + name: string; + proxies: Array; + delay: DelayMapping; + hideUnavailableProxies: boolean; + proxySortBy: string; + type: 'Proxy' | 'Rule'; + vehicleType: 'HTTP' | 'File' | 'Compatible'; + updatedAt?: string; + subscriptionInfo?: SubscriptionInfo; + dispatch: (x: any) => Promise; + isOpen: boolean; + apiConfig: any; +}; + +function ProxyProviderImpl({ + name, + proxies: all, + delay, + hideUnavailableProxies, + proxySortBy, + vehicleType, + updatedAt, + subscriptionInfo, + isOpen, + dispatch, + apiConfig, +}: Props) { + const proxies = useFilteredAndSorted(all, delay, hideUnavailableProxies, proxySortBy); + const [isHealthcheckLoading, setIsHealthcheckLoading] = useState(false); + + const updateProvider = useUpdateProviderItem({ dispatch, apiConfig, name }); + + const healthcheckProvider = useCallback(async () => { + setIsHealthcheckLoading(true); + await dispatch(healthcheckProviderByName(apiConfig, name)); + setIsHealthcheckLoading(false); + }, [apiConfig, dispatch, name, setIsHealthcheckLoading]); + + const { + app: { updateCollapsibleIsOpen }, + } = useStoreActions(); + + const toggle = useCallback(() => { + updateCollapsibleIsOpen('proxyProvider', name, !isOpen); + }, [isOpen, updateCollapsibleIsOpen, name]); + + const timeAgo = formatDistance(new Date(updatedAt), new Date()); + const total = subscriptionInfo ? formatBytes(subscriptionInfo.Total) : 0; + const used = subscriptionInfo + ? formatBytes(subscriptionInfo.Download + subscriptionInfo.Upload) + : 0; + const percentage = subscriptionInfo + ? ( + ((subscriptionInfo.Download + subscriptionInfo.Upload) / subscriptionInfo.Total) * + 100 + ).toFixed(2) + : 0; + const expireStr = () => { + if (subscriptionInfo.Expire === 0) { + return 'Null'; + } + const expire = new Date(subscriptionInfo.Expire * 1000); + const getYear = expire.getFullYear() + '-'; + const getMonth = + (expire.getMonth() + 1 < 10 ? '0' + (expire.getMonth() + 1) : expire.getMonth() + 1) + '-'; + const getDate = expire.getDate() + ' '; + return getYear + getMonth + getDate; + }; + return ( +
+
+ +
+ {subscriptionInfo && ( +
+ + {used} / {total} ( {percentage}% )    Expire: {expireStr()}{' '} + +
+ )} +
+ Updated {timeAgo} ago +
+ {/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element[]; isOpen: boolean; }' i... Remove this comment to see the full error message */} + + +
+
+
+ {/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element; isOpen: boolean; }' is ... Remove this comment to see the full error message */} + + + +
+ ); +} + +const button = { + rest: { scale: 1 }, + pressed: { scale: 0.95 }, +}; +const arrow = { + rest: { rotate: 0 }, + hover: { rotate: 360, transition: { duration: 0.3 } }, +}; + +function formatBytes(bytes, decimals = 2) { + if (!+bytes) return '0 Bytes'; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; +} +function Refresh() { + const module = framerMotionResouce.read(); + const motion = module.motion; + return ( + + + + + + ); +} + +const mapState = (s, { proxies, name }) => { + const hideUnavailableProxies = getHideUnavailableProxies(s); + const delay = getDelay(s); + const collapsibleIsOpen = getCollapsibleIsOpen(s); + const apiConfig = getClashAPIConfig(s); + + const proxySortBy = getProxySortBy(s); + + return { + apiConfig, + proxies, + delay, + hideUnavailableProxies, + proxySortBy, + isOpen: collapsibleIsOpen[`proxyProvider:${name}`], + }; +}; + +export const ProxyProvider = connect(mapState)(ProxyProviderImpl); diff --git a/src/components/proxies/ProxyProviderList.tsx b/src/components/proxies/ProxyProviderList.tsx new file mode 100644 index 0000000..ae79ea8 --- /dev/null +++ b/src/components/proxies/ProxyProviderList.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; + +import ContentHeader from '~/components/ContentHeader'; +import { ProxyProvider } from '~/components/proxies/ProxyProvider'; +import { FormattedProxyProvider } from '~/store/types'; + +export function ProxyProviderList({ items }: { items: FormattedProxyProvider[] }) { + if (items.length === 0) return null; + return ( + <> + +
+ {items.map((item) => ( + + ))} +
+ + ); +} diff --git a/src/components/proxies/Settings.module.scss b/src/components/proxies/Settings.module.scss new file mode 100644 index 0000000..364d07d --- /dev/null +++ b/src/components/proxies/Settings.module.scss @@ -0,0 +1,17 @@ +.labeledInput { + max-width: 85vw; + width: 400px; + display: flex; + justify-content: space-between; + align-items: center; + font-size: 13px; + padding: 13px 0; +} + +hr { + height: 1px; + background-color: var(--color-separator); + border: none; + outline: none; + margin: 1rem 0px; +} diff --git a/src/components/proxies/Settings.tsx b/src/components/proxies/Settings.tsx new file mode 100644 index 0000000..b2ec192 --- /dev/null +++ b/src/components/proxies/Settings.tsx @@ -0,0 +1,92 @@ +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import Select from '~/components/shared/Select'; + +import { getAutoCloseOldConns, getHideUnavailableProxies, getProxySortBy } from '../../store/app'; +import { connect, useStoreActions } from '../StateProvider'; +import Switch from '../SwitchThemed'; +import s from './Settings.module.scss'; + +const options = [ + ['Natural', 'order_natural'], + ['LatencyAsc', 'order_latency_asc'], + ['LatencyDesc', 'order_latency_desc'], + ['NameAsc', 'order_name_asc'], + ['NameDesc', 'order_name_desc'], +]; + +const { useCallback } = React; + +function Settings({ appConfig }) { + const { + app: { updateAppConfig }, + } = useStoreActions(); + + const handleProxySortByOnChange = useCallback( + (e) => { + updateAppConfig('proxySortBy', e.target.value); + }, + [updateAppConfig] + ); + + const handleHideUnavailablesSwitchOnChange = useCallback( + (v) => { + updateAppConfig('hideUnavailableProxies', v); + }, + [updateAppConfig] + ); + const { t } = useTranslation(); + return ( + <> +
+ {t('sort_in_grp')} +
+ + {options.map(([value, name]) => ( + + ))} + + ); +} diff --git a/src/components/shared/Styled.module.scss b/src/components/shared/Styled.module.scss new file mode 100644 index 0000000..88b84ad --- /dev/null +++ b/src/components/shared/Styled.module.scss @@ -0,0 +1,5 @@ +.FlexCenter { + display: flex; + justify-content: center; + align-items: center; +} diff --git a/src/components/shared/Styled.tsx b/src/components/shared/Styled.tsx new file mode 100644 index 0000000..86d87ca --- /dev/null +++ b/src/components/shared/Styled.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +import s from './Styled.module.scss'; + +export function FlexCenter({ children }: { children: React.ReactNode }) { + return
{children}
; +} diff --git a/src/components/shared/TextFitler.module.scss b/src/components/shared/TextFitler.module.scss new file mode 100644 index 0000000..7d7ba9b --- /dev/null +++ b/src/components/shared/TextFitler.module.scss @@ -0,0 +1,19 @@ +.input { + -webkit-appearance: none; + background-color: var(--color-input-bg); + background-image: none; + border-radius: 20px; + border: 1px solid var(--color-input-border); + box-sizing: border-box; + color: #c1c1c1; + display: inline-block; + font-size: inherit; + outline: none; + padding: 8px 15px; + transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); + width: 100%; + + &:focus { + border: 1px solid var(--color-focus-blue); + } +} diff --git a/src/components/shared/TextFitler.tsx b/src/components/shared/TextFitler.tsx new file mode 100644 index 0000000..1a78ca2 --- /dev/null +++ b/src/components/shared/TextFitler.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; +import type { RecoilState } from 'recoil'; + +import { useTextInut } from '~/hooks/useTextInput'; + +import s from './TextFitler.module.scss'; + +export function TextFilter(props: { textAtom: RecoilState; placeholder?: string }) { + const [onChange, text] = useTextInut(props.textAtom); + return ( + + ); +} diff --git a/src/components/shared/ThemeSwitcher.module.scss b/src/components/shared/ThemeSwitcher.module.scss new file mode 100644 index 0000000..d2f296a --- /dev/null +++ b/src/components/shared/ThemeSwitcher.module.scss @@ -0,0 +1,55 @@ +.iconWrapper { + --sz: 40px; + + width: var(--sz); + height: var(--sz); + display: flex; + justify-content: center; + align-items: center; + + outline: none; + padding: 5px; + color: var(--color-text); +} +.iconWrapper:hover { + opacity: 0.6; +} +.iconWrapper:focus { + border-color: var(--color-focus-blue); +} + +.themeSwitchContainer { + --sz: 40px; + + position: relative; + display: flex; + align-items: center; + height: var(--sz); + select { + cursor: pointer; + padding-left: var(--sz); + width: var(--sz); + height: var(--sz); + appearance: none; + outline: none; + border-radius: 100%; + border: 1px solid transparent; + background: var(--color-bg-sidebar); + &:focus { + border-color: var(--color-focus-blue); + } + option { + // this has effect in Firefox + // Chrome and Safari use the native menu + background: var(--color-bg-sidebar); + } + } + .iconWrapper { + pointer-events: none; + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + } +} diff --git a/src/components/shared/ThemeSwitcher.tsx b/src/components/shared/ThemeSwitcher.tsx new file mode 100644 index 0000000..363d422 --- /dev/null +++ b/src/components/shared/ThemeSwitcher.tsx @@ -0,0 +1,138 @@ +import { Tooltip } from '@reach/tooltip'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { connect } from '~/components/StateProvider'; +import { framerMotionResouce } from '~/misc/motion'; +import { getTheme, switchTheme } from '~/store/app'; +import { State } from '~/store/types'; + +import s from './ThemeSwitcher.module.scss'; + +export function ThemeSwitcherImpl({ theme, dispatch }) { + const { t } = useTranslation(); + + const themeIcon = React.useMemo(() => { + switch (theme) { + case 'dark': + return ; + case 'auto': + return ; + case 'light': + return ; + default: + console.assert(false, 'Unknown theme'); + return ; + } + }, [theme]); + + const onChange = React.useCallback( + (e: React.ChangeEvent) => dispatch(switchTheme(e.target.value)), + [dispatch] + ); + + return ( + +
+ {themeIcon} + +
+
+ ); +} + +function MoonA() { + const module = framerMotionResouce.read(); + const motion = module.motion; + return ( + + + + ); +} + +function Sun() { + const module = framerMotionResouce.read(); + const motion = module.motion; + + return ( + + + + + + + + + + + + + + ); +} + +function Auto() { + const module = framerMotionResouce.read(); + const motion = module.motion; + + return ( + + + + + + + + ); +} + +const mapState = (s: State) => ({ theme: getTheme(s) }); +export const ThemeSwitcher = connect(mapState)(ThemeSwitcherImpl); diff --git a/src/components/shared/rtf.css b/src/components/shared/rtf.css new file mode 100644 index 0000000..574aad1 --- /dev/null +++ b/src/components/shared/rtf.css @@ -0,0 +1,233 @@ +/* + * for react-tiny-fab + * based on react-tiny-fab/dist/styles.css + */ +.rtf { + box-sizing: border-box; + margin: 25px; + position: fixed; + white-space: nowrap; + z-index: 9998; + padding-left: 0; + list-style: none; +} +.rtf.open .rtf--mb { + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), + 0px 3px 14px 2px rgba(0, 0, 0, 0.12); +} + +.rtf.open .rtf--mb > ul { + list-style: none; + margin: 0; + padding: 0; +} + +.rtf.open .rtf--ab__c:hover > span { + transition: ease-in-out opacity 0.2s; + opacity: 0.9; +} +.rtf.open .rtf--ab__c > span.always-show { + transition: ease-in-out opacity 0.2s; + opacity: 0.9; +} +.rtf.open .rtf--ab__c:nth-child(1) { + transform: translateY(-60px) scale(1); + transition-delay: 0.03s; +} +.rtf.open .rtf--ab__c:nth-child(1).top { + transform: translateY(60px) scale(1); +} +.rtf.open .rtf--ab__c:nth-child(2) { + transform: translateY(-120px) scale(1); + transition-delay: 0.09s; +} +.rtf.open .rtf--ab__c:nth-child(2).top { + transform: translateY(120px) scale(1); +} +.rtf.open .rtf--ab__c:nth-child(3) { + transform: translateY(-180px) scale(1); + transition-delay: 0.12s; +} +.rtf.open .rtf--ab__c:nth-child(3).top { + transform: translateY(180px) scale(1); +} +.rtf.open .rtf--ab__c:nth-child(4) { + transform: translateY(-240px) scale(1); + transition-delay: 0.15s; +} +.rtf.open .rtf--ab__c:nth-child(4).top { + transform: translateY(240px) scale(1); +} +.rtf.open .rtf--ab__c:nth-child(5) { + transform: translateY(-300px) scale(1); + transition-delay: 0.18s; +} +.rtf.open .rtf--ab__c:nth-child(5).top { + transform: translateY(300px) scale(1); +} +.rtf.open .rtf--ab__c:nth-child(6) { + transform: translateY(-360px) scale(1); + transition-delay: 0.21s; +} +.rtf.open .rtf--ab__c:nth-child(6).top { + transform: translateY(360px) scale(1); +} + +.rtf--mb__c { + padding: 25px; + margin: -25px; +} +.rtf--mb__c *:last-child { + margin-bottom: 0; +} +.rtf--mb__c:hover > span { + transition: ease-in-out opacity 0.2s; + opacity: 0.9; +} +.rtf--mb__c > span.always-show { + transition: ease-in-out opacity 0.2s; + opacity: 0.9; +} +.rtf--mb__c > span { + opacity: 0; + transition: ease-in-out opacity 0.2s; + position: absolute; + top: 50%; + transform: translateY(-50%); + margin-right: 6px; + margin-left: 4px; + background: rgba(0, 0, 0, 0.75); + padding: 2px 4px; + border-radius: 2px; + color: white; + font-size: 13px; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.28); +} +.rtf--mb__c > span.right { + right: 100%; +} + +.rtf--mb { + width: 48px; + height: 48px; + background: var(--btn-bg); + z-index: 9999; + display: inline-flex; + justify-content: center; + align-items: center; + position: relative; + border: none; + border-radius: 50%; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.28); + cursor: pointer; + outline: none; + padding: 0; + -webkit-user-drag: none; + font-weight: bold; + color: #f1f1f1; + font-size: 18px; +} +.rtf--mb > * { + transition: ease-in-out transform 0.2s; +} + +.rtf--ab__c { + display: block; + position: absolute; + top: 0; + right: 1px; + padding: 10px 0; + margin: -10px 0; + transition: ease-in-out transform 0.2s; +} +.rtf--ab__c > span { + opacity: 0; + transition: ease-in-out opacity 0.2s; + position: absolute; + top: 50%; + transform: translateY(-50%); + margin-right: 6px; + background: rgba(0, 0, 0, 0.75); + padding: 2px 4px; + border-radius: 2px; + color: white; + font-size: 13px; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.28); +} +.rtf--ab__c > span.right { + right: 100%; +} +.rtf--ab__c:nth-child(1) { + transform: translateY(-60px) scale(0); + transition-delay: 0.21s; +} +.rtf--ab__c:nth-child(1).top { + transform: translateY(60px) scale(0); +} +.rtf--ab__c:nth-child(2) { + transform: translateY(-120px) scale(0); + transition-delay: 0.18s; +} +.rtf--ab__c:nth-child(2).top { + transform: translateY(120px) scale(0); +} +.rtf--ab__c:nth-child(3) { + transform: translateY(-180px) scale(0); + transition-delay: 0.15s; +} +.rtf--ab__c:nth-child(3).top { + transform: translateY(180px) scale(0); +} +.rtf--ab__c:nth-child(4) { + transform: translateY(-240px) scale(0); + transition-delay: 0.12s; +} +.rtf--ab__c:nth-child(4).top { + transform: translateY(240px) scale(0); +} +.rtf--ab__c:nth-child(5) { + transform: translateY(-300px) scale(0); + transition-delay: 0.09s; +} +.rtf--ab__c:nth-child(5).top { + transform: translateY(300px) scale(0); +} +.rtf--ab__c:nth-child(6) { + transform: translateY(-360px) scale(0); + transition-delay: 0.03s; +} +.rtf--ab__c:nth-child(6).top { + transform: translateY(360px) scale(0); +} + +.rtf--ab { + height: 40px; + width: 40px; + margin-right: 4px; + background-color: #aaaaaa; + display: inline-flex; + justify-content: center; + align-items: center; + position: relative; + border: none; + border-radius: 50%; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.28); + cursor: pointer; + outline: none; + padding: 0; + -webkit-user-drag: none; + font-weight: bold; + color: #f1f1f1; + font-size: 16px; + z-index: 10000; +} + +.rtf--ab:hover { + background: #387cec; + border: 1px solid #387cec; + color: #fff; +} + +.rtf--ab:focus { + border-color: var(--color-focus-blue); +} diff --git a/src/components/svg/Equalizer.tsx b/src/components/svg/Equalizer.tsx new file mode 100644 index 0000000..ae3c858 --- /dev/null +++ b/src/components/svg/Equalizer.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; + +type Props = { + size?: number; + color?: string; +}; + +export default function Equalizer({ color = 'currentColor', size = 24 }: Props) { + return ( + + + + + + + ); +} diff --git a/src/custom.d.ts b/src/custom.d.ts new file mode 100644 index 0000000..8e12742 --- /dev/null +++ b/src/custom.d.ts @@ -0,0 +1,69 @@ +/// +/// + +// for css modules +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; +} +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; +} + +interface Window { + i18n: any; +} + +// webpack definePlugin replacing variables +declare const __VERSION__: string; +declare const process = { + env: { + NODE_ENV: string, + PUBLIC_URL: string, + }, +}; + +declare module 'react-table' { + interface TableOptions {} + + interface Empty {} + + interface SortByToggleProps {} + + interface Header { + getHeaderProps(p: SortByToggleProps): { role?: string }; + getSortByToggleProps(): SortByToggleProps; + render(x: string): string; + isSorted: boolean; + isSortedDesc: boolean; + } + + interface HeaderGroup { + getHeaderGroupProps(): { role?: string }; + headers: Header[]; + } + + interface Cell { + getCellProps(): { role?: string }; + + column: { id: string }; + value: number; + } + + interface Row { + cells: Cell[]; + } + + export function useTable( + options: TableOptions, + useSortBy: useSortBy + ): { + headerGroups: HeaderGroup[]; + getTableProps(): { role?: string }; + rows: Row[]; + prepareRow(r: Row): void; + }; + + export function useSortBy(): Empty; +} diff --git a/src/hooks/basic.ts b/src/hooks/basic.ts new file mode 100644 index 0000000..587d92d --- /dev/null +++ b/src/hooks/basic.ts @@ -0,0 +1,9 @@ +import React from 'react'; + +const { useState, useCallback } = React; + +export function useToggle(initialValue = false) { + const [isOn, setState] = useState(initialValue); + const toggle = useCallback(() => setState((x) => !x), []); + return [isOn, toggle]; +} diff --git a/src/hooks/useLineChart.ts b/src/hooks/useLineChart.ts new file mode 100644 index 0000000..88ee660 --- /dev/null +++ b/src/hooks/useLineChart.ts @@ -0,0 +1,25 @@ +import type { ChartConfiguration } from 'chart.js'; +import React from 'react'; + +import { commonChartOptions } from '~/misc/chart'; + +const { useEffect } = React; + +export default function useLineChart( + chart: typeof import('chart.js').Chart, + elementId: string, + data: ChartConfiguration['data'], + subscription: any, + extraChartOptions = {} +) { + useEffect(() => { + const ctx = (document.getElementById(elementId) as HTMLCanvasElement).getContext('2d'); + const options = { ...commonChartOptions, ...extraChartOptions }; + const c = new chart(ctx, { type: 'line', data, options }); + const unsubscribe = subscription && subscription.subscribe(() => c.update()); + return () => { + unsubscribe && unsubscribe(); + c.destroy(); + }; + }, [chart, elementId, data, subscription, extraChartOptions]); +} diff --git a/src/hooks/useRemainingViewPortHeight.ts b/src/hooks/useRemainingViewPortHeight.ts new file mode 100644 index 0000000..2c920c2 --- /dev/null +++ b/src/hooks/useRemainingViewPortHeight.ts @@ -0,0 +1,32 @@ +import * as React from 'react'; + +const { useState, useRef, useCallback, useLayoutEffect } = React; + +/** + * cosnt [ref, remainingHeight] = useRemainingViewPortHeight(); + * + * return a reference, and the remaining height of the referenced dom node + * to the bottom of the view port + * + */ +export default function useRemainingViewPortHeight(): [ + React.MutableRefObject, + number +] { + const ref = useRef(null); + const [containerHeight, setContainerHeight] = useState(200); + const updateContainerHeight = useCallback(() => { + const { top } = ref.current.getBoundingClientRect(); + setContainerHeight(window.innerHeight - top); + }, []); + + useLayoutEffect(() => { + updateContainerHeight(); + window.addEventListener('resize', updateContainerHeight); + return () => { + window.removeEventListener('resize', updateContainerHeight); + }; + }, [updateContainerHeight]); + + return [ref, containerHeight]; +} diff --git a/src/hooks/useTextInput.ts b/src/hooks/useTextInput.ts new file mode 100644 index 0000000..853044c --- /dev/null +++ b/src/hooks/useTextInput.ts @@ -0,0 +1,21 @@ +import debounce from 'lodash-es/debounce'; +import * as React from 'react'; +import { RecoilState, useRecoilState } from 'recoil'; + +const { useCallback, useState, useMemo } = React; + +export function useTextInut( + x: RecoilState +): [(e: React.ChangeEvent) => void, string] { + const [, setTextGlobal] = useRecoilState(x); + const [text, setText] = useState(''); + const setTextDebounced = useMemo(() => debounce(setTextGlobal, 300), [setTextGlobal]); + const onChange = useCallback( + (e: React.ChangeEvent) => { + setText(e.target.value); + setTextDebounced(e.target.value); + }, + [setTextDebounced] + ); + return [onChange, text]; +} diff --git a/src/i18n/en.ts b/src/i18n/en.ts new file mode 100644 index 0000000..8126195 --- /dev/null +++ b/src/i18n/en.ts @@ -0,0 +1,60 @@ +export const data = { + Overview: 'Overview', + Proxies: 'Proxies', + Rules: 'Rules', + Conns: 'Conns', + Config: 'Config', + Logs: 'Logs', + Upload: 'Upload', + Download: 'Download', + 'Upload Total': 'Upload Total', + 'Download Total': 'Download Total', + 'Active Connections': 'Active Connections', + 'Pause Refresh': 'Pause Refresh', + 'Resume Refresh': 'Resume Refresh', + close_all_connections: 'Close All Connections', + Search: 'Search', + Up: 'Up', + Down: 'Down', + 'Test Latency': 'Test Latency', + settings: 'settings', + sort_in_grp: 'Sorting in group', + hide_unavail_proxies: 'Hide unavailable proxies', + auto_close_conns: 'Automatically close old connections', + order_natural: 'Original order in config file', + order_latency_asc: 'By latency from small to big', + order_latency_desc: 'By latency from big to small', + order_name_asc: 'By name alphabetically (A-Z)', + order_name_desc: 'By name alphabetically (Z-A)', + Connections: 'Connections', + Active: 'Active', + Closed: 'Closed', + switch_theme: 'Switch theme', + theme: 'theme', + about: 'about', + no_logs: 'No logs yet, hang tight...', + chart_style: 'Chart Style', + latency_test_url: 'Latency Test URL', + lang: 'Language', + update_all_rule_provider: 'Update all rule providers', + update_all_proxy_provider: 'Update all proxy providers', + reload_config_file: 'Reload config file', + update_geo_databases_file: 'Update GEO Databases ', + flush_fake_ip_pool: 'Flush fake-ip data', + enable_tun_device: 'Enable TUN Device', + allow_lan: 'Allow LAN', + tls_sniffing: 'Sniffer', + c_host: 'Host', + c_sni: 'Sniff Host', + c_process: 'Process', + c_dl: 'DL', + c_ul: 'UL', + c_dl_speed: 'DL Speed', + c_ul_speed: 'UP Speed', + c_chains: 'Chains', + c_rule: 'Rule', + c_time: 'Time', + c_source: 'Source', + c_destination_ip: 'Destination IP', + c_type: 'Type', +}; diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts new file mode 100644 index 0000000..3356b6e --- /dev/null +++ b/src/i18n/zh.ts @@ -0,0 +1,60 @@ +export const data = { + Overview: '概览', + Proxies: '代理', + Rules: '规则', + Conns: '连接', + Config: '配置', + Logs: '日志', + Upload: '上传', + Download: '下载', + 'Upload Total': '上传总量', + 'Download Total': '下载总量', + 'Active Connections': '活动连接', + 'Pause Refresh': '暂停刷新', + 'Resume Refresh': '继续刷新', + close_all_connections: '关闭所有连接', + Search: '查找', + Up: '上传', + Down: '下载', + 'Test Latency': '延迟测速', + settings: '设置', + sort_in_grp: '代理组条目排序', + hide_unavail_proxies: '隐藏不可用代理', + auto_close_conns: '切换代理时自动断开旧连接', + order_natural: '原 config 文件中的排序', + order_latency_asc: '按延迟从小到大', + order_latency_desc: '按延迟从大到小', + order_name_asc: '按名称字母排序 (A-Z)', + order_name_desc: '按名称字母排序 (Z-A)', + Connections: '连接', + Active: '活动', + Closed: '已断开', + switch_theme: '切换主题', + theme: '主题', + about: '关于', + no_logs: '暂无日志...', + chart_style: '流量图样式', + latency_test_url: '延迟测速 URL', + lang: '语言', + update_all_rule_provider: '更新所有 rule provider', + update_all_proxy_provider: '更新所有 proxy provider', + reload_config_file: '重载配置文件', + update_geo_databases_file: '更新 GEO 数据库文件', + flush_fake_ip_pool: '清空 FakeIP 数据库', + enable_tun_device: '开启 TUN 转发', + allow_lan: '允许局域网连接', + tls_sniffing: 'SNI 嗅探', + c_host: '域名', + c_sni: '嗅探域名', + c_process: '进程', + c_dl: '下载', + c_ul: '上传', + c_dl_speed: '下载速率', + c_ul_speed: '上传速率', + c_chains: '节点链', + c_rule: '规则', + c_time: '连接时间', + c_source: '来源', + c_destination_ip: '目标IP', + c_type: '类型', +}; diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..34a8f17 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,76 @@ +import '~/styles/main.scss'; +import './misc/i18n'; + +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import Modal from 'react-modal'; + +import App from './App'; +import * as swRegistration from './swRegistration'; + +const rootEl = document.getElementById('app'); +const root = createRoot(rootEl); + +Modal.setAppElement(rootEl); + +root.render(); + +swRegistration.register(); + +// eslint-disable-next-line no-console +console.log('Checkout the repo: https://github.com/MetaCubeX/yacd'); +// eslint-disable-next-line no-console +console.log('Version:', __VERSION__); + +window.onload = function startup() { + const el = document.getElementById('app'); + el.addEventListener('touchstart', onTouchStart, { passive: true }); + el.addEventListener('touchmove', onTouchMove, false); + el.addEventListener('touchend', onTouchEnd, false); +}; + +const touchData = { touching: false, trace: [] }; + +function onTouchStart(evt) { + if (evt.touches.length !== 1) { + touchData.touching = false; + touchData.trace = []; + return; + } + touchData.touching = true; + touchData.trace = [{ x: evt.touches[0].screenX, y: evt.touches[0].screenY }]; +} + +function onTouchMove(evt) { + if (!touchData.touching) return; + touchData.trace.push({ + x: evt.touches[0].screenX, + y: evt.touches[0].screenY, + }); +} + +function onTouchEnd() { + if (!touchData.touching) return; + const trace = touchData.trace; + touchData.touching = false; + touchData.trace = []; + handleTouch(trace); //判断touch类型并调用适当回调 +} + +function handleTouch(trace) { + const tags = ['/', '/proxies', '/rules', '/connections', '/configs', '/logs']; + const start = trace[0]; + const end = trace[trace.length - 1]; + const tag = window.location.hash.slice(1); + const index = tags.indexOf(tag); + console.log(index, tag, tags.length); + if (index === 3) return; + if (end.x - start.x > 200 && index > 0) { + window.location.hash = tags[index - 1]; + } else if (end.x - start.x < -200 && index < tags.length - 1) { + window.location.hash = tags[index + 1]; + if (index === -1) { + window.location.hash = tags[index + 2]; + } + } +} diff --git a/src/misc/chart-lib.ts b/src/misc/chart-lib.ts new file mode 100644 index 0000000..9a2bf35 --- /dev/null +++ b/src/misc/chart-lib.ts @@ -0,0 +1,23 @@ +import { + CategoryScale, + Chart, + Filler, + Legend, + LinearScale, + LineController, + LineElement, + PointElement, +} from 'chart.js'; + +// see https://www.chartjs.org/docs/latest/getting-started/integration.html#bundlers-webpack-rollup-etc +Chart.register( + LineElement, + PointElement, + LineController, + CategoryScale, + LinearScale, + Filler, + Legend +); + +export { Chart }; diff --git a/src/misc/chart.ts b/src/misc/chart.ts new file mode 100644 index 0000000..56ffe87 --- /dev/null +++ b/src/misc/chart.ts @@ -0,0 +1,79 @@ +import { createAsset } from 'use-asset'; + +import prettyBytes from './pretty-bytes'; +export const chartJSResource = createAsset(() => { + return import('~/misc/chart-lib'); +}); + +export const commonDataSetProps = { borderWidth: 1, pointRadius: 0, tension: 0.2, fill: true }; + +export const commonChartOptions: import('chart.js').ChartOptions<'line'> = { + responsive: true, + maintainAspectRatio: true, + plugins: { + legend: { labels: { boxWidth: 20 } }, + }, + scales: { + x: { display: false, type: 'category' }, + y: { + type: 'linear', + display: true, + grid: { + display: true, + color: '#555', + drawTicks: false, + }, + border: { + dash: [3, 6], + }, + ticks: { + callback(value: number) { + return prettyBytes(value) + '/s '; + }, + }, + }, + }, +}; + +export const chartStyles = [ + { + down: { + backgroundColor: 'rgba(176, 209, 132, 0.8)', + borderColor: 'rgb(176, 209, 132)', + }, + up: { + backgroundColor: 'rgba(181, 220, 231, 0.8)', + borderColor: 'rgb(181, 220, 231)', + }, + }, + { + up: { + backgroundColor: 'rgb(98, 190, 100)', + borderColor: 'rgb(78,146,79)', + }, + down: { + backgroundColor: 'rgb(160, 230, 66)', + borderColor: 'rgb(110, 156, 44)', + }, + }, + { + up: { + backgroundColor: 'rgba(94, 175, 223, 0.3)', + borderColor: 'rgb(94, 175, 223)', + }, + down: { + backgroundColor: 'rgba(139, 227, 195, 0.3)', + borderColor: 'rgb(139, 227, 195)', + }, + }, + { + up: { + backgroundColor: 'rgba(242, 174, 62, 0.3)', + borderColor: 'rgb(242, 174, 62)', + }, + down: { + backgroundColor: 'rgba(69, 154, 248, 0.3)', + borderColor: 'rgb(69, 154, 248)', + }, + }, +]; diff --git a/src/misc/createResource.ts b/src/misc/createResource.ts new file mode 100644 index 0000000..9ff57e5 --- /dev/null +++ b/src/misc/createResource.ts @@ -0,0 +1,45 @@ +// from https://gist.github.com/ryanflorence/e10cc9dbc0e259759ec942ba82e5b57c +export function createResource(getPromise: (key: string) => Promise) { + let cache = {}; + const inflight = {}; + const errors = {}; + + function load(key = 'default') { + inflight[key] = getPromise(key) + .then((val) => { + delete inflight[key]; + cache[key] = val; + }) + .catch((error) => { + errors[key] = error; + }); + return inflight[key]; + } + + function preload(key = 'default') { + if (cache[key] !== undefined || inflight[key]) return; + load(key); + } + + function read(key = 'default') { + if (cache[key] !== undefined) { + return cache[key]; + } else if (errors[key]) { + throw errors[key]; + } else if (inflight[key]) { + throw inflight[key]; + } else { + throw load(key); + } + } + + function clear(key: 'default') { + if (key) { + delete cache[key]; + } else { + cache = {}; + } + } + + return { preload, read, clear }; +} diff --git a/src/misc/errors.ts b/src/misc/errors.ts new file mode 100644 index 0000000..1bc369a --- /dev/null +++ b/src/misc/errors.ts @@ -0,0 +1,21 @@ +export const DOES_NOT_SUPPORT_FETCH = 0; + +export const errors = { + [DOES_NOT_SUPPORT_FETCH]: { + message: 'Browser not supported!', + detail: 'This browser does not support "fetch", please choose another one.', + }, + default: { + message: 'Oops, something went wrong!', + }, +}; + +export type Err = { code: number }; + +export function deriveMessageFromError(err: Err) { + const { code } = err; + if (typeof code === 'number') { + return errors[code]; + } + return errors.default; +} diff --git a/src/misc/i18n.ts b/src/misc/i18n.ts new file mode 100644 index 0000000..bbae42b --- /dev/null +++ b/src/misc/i18n.ts @@ -0,0 +1,61 @@ +import i18next from 'i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; +import HttpBackend from 'i18next-http-backend'; +import { initReactI18next } from 'react-i18next'; + +const allLocales = { + zh: import('~/i18n/zh'), + en: import('~/i18n/en'), +}; + +type BackendRequestCallback = (err: null, result: { status: number; data: any }) => void; + +i18next + .use(HttpBackend) + .use(initReactI18next) + .use(LanguageDetector) + .init({ + debug: process.env.NODE_ENV === 'development', + // resources, + backend: { + loadPath: '/__{{lng}}/{{ns}}.json', + request: function ( + _options: any, + url: string, + _payload: any, + callback: BackendRequestCallback + ) { + let p: PromiseLike<{ data: any }>; + + switch (url) { + case '/__zh/translation.json': + case '/__zh-CN/translation.json': + p = allLocales.zh; + break; + case '/__en/translation.json': + p = allLocales.en; + break; + default: + p = allLocales.zh; + break; + } + + if (p) { + p.then((mod) => { + callback(null, { status: 200, data: mod.data }); + }); + } + }, + }, + supportedLngs: ['en', 'zh'], + fallbackLng: 'en', + interpolation: { + escapeValue: false, + }, + }); + +if (process.env.NODE_ENV === 'development') { + window.i18n = i18next; +} + +export default i18next; diff --git a/src/misc/keycode.ts b/src/misc/keycode.ts new file mode 100644 index 0000000..d1dd935 --- /dev/null +++ b/src/misc/keycode.ts @@ -0,0 +1,6 @@ +export const keyCodes = { + Right: 39, + Left: 37, + Enter: 13, + Space: 32, +}; diff --git a/src/misc/motion.ts b/src/misc/motion.ts new file mode 100644 index 0000000..7fac864 --- /dev/null +++ b/src/misc/motion.ts @@ -0,0 +1,3 @@ +import { createResource } from './createResource'; + +export const framerMotionResouce = createResource(() => import('framer-motion')); diff --git a/src/misc/pretty-bytes.ts b/src/misc/pretty-bytes.ts new file mode 100644 index 0000000..68b6776 --- /dev/null +++ b/src/misc/pretty-bytes.ts @@ -0,0 +1,13 @@ +// steal from https://github.com/sindresorhus/pretty-bytes/blob/master/index.js + +const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + +export default function prettyBytes(n: number) { + if (n < 1000) { + return n + ' B'; + } + const exponent = Math.min(Math.floor(Math.log10(n) / 3), UNITS.length - 1); + n = Number((n / Math.pow(1000, exponent)).toPrecision(3)); + const unit = UNITS[exponent]; + return n + ' ' + unit; +} diff --git a/src/misc/query.ts b/src/misc/query.ts new file mode 100644 index 0000000..4c2a89d --- /dev/null +++ b/src/misc/query.ts @@ -0,0 +1,11 @@ +import { QueryCache, QueryClient } from 'react-query'; + +const queryCache = new QueryCache(); +export const queryClient = new QueryClient({ + queryCache, + defaultOptions: { + queries: { + suspense: true, + }, + }, +}); diff --git a/src/misc/request-helper.ts b/src/misc/request-helper.ts new file mode 100644 index 0000000..db28cde --- /dev/null +++ b/src/misc/request-helper.ts @@ -0,0 +1,45 @@ +import { trimTrailingSlash } from '~/misc/utils'; +import { ClashAPIConfig, LogsAPIConfig } from '~/types'; + +const headersCommon = { 'Content-Type': 'application/json' }; + +function genCommonHeaders({ secret }: { secret?: string }) { + const h = { ...headersCommon }; + if (secret) { + h['Authorization'] = `Bearer ${secret}`; + } + return h; +} +function buildWebSocketURLBase(baseURL: string, params: URLSearchParams, endpoint: string) { + const qs = '?' + params.toString(); + const url = new URL(baseURL); + url.protocol === 'https:' ? (url.protocol = 'wss:') : (url.protocol = 'ws:'); + return `${trimTrailingSlash(url.href)}${endpoint}${qs}`; +} + +export function getURLAndInit({ baseURL, secret }: ClashAPIConfig) { + const headers = genCommonHeaders({ secret }); + return { + url: baseURL, + init: { headers }, + }; +} + +export function buildWebSocketURL(apiConfig: ClashAPIConfig, endpoint: string) { + const { baseURL, secret } = apiConfig; + const params = new URLSearchParams({ + token: secret, + }); + + return buildWebSocketURLBase(baseURL, params, endpoint); +} + +export function buildLogsWebSocketURL(apiConfig: LogsAPIConfig, endpoint: string) { + const { baseURL, secret, logLevel } = apiConfig; + const params = new URLSearchParams({ + token: secret, + level: logLevel, + }); + + return buildWebSocketURLBase(baseURL, params, endpoint); +} diff --git a/src/misc/shallowEqual.ts b/src/misc/shallowEqual.ts new file mode 100644 index 0000000..937bc27 --- /dev/null +++ b/src/misc/shallowEqual.ts @@ -0,0 +1,31 @@ +const hasOwn = Object.prototype.hasOwnProperty; + +function is(x, y) { + if (x === y) { + return x !== 0 || y !== 0 || 1 / x === 1 / y; + } else { + // eslint-disable-next-line no-self-compare + return x !== x && y !== y; + } +} + +export default function shallowEqual(objA, objB) { + if (is(objA, objB)) return true; + + if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { + return false; + } + + const keysA = Object.keys(objA); + const keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) return false; + + for (let i = 0; i < keysA.length; i++) { + if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { + return false; + } + } + + return true; +} diff --git a/src/misc/storage.ts b/src/misc/storage.ts new file mode 100644 index 0000000..15d85d3 --- /dev/null +++ b/src/misc/storage.ts @@ -0,0 +1,32 @@ +// manage localStorage + +const StorageKey = 'yacd.metacubex.one'; + +function loadState() { + try { + const serialized = localStorage.getItem(StorageKey); + if (!serialized) return undefined; + return JSON.parse(serialized); + } catch (err) { + return undefined; + } +} + +function saveState(state) { + try { + const serialized = JSON.stringify(state); + localStorage.setItem(StorageKey, serialized); + } catch (err) { + // ignore + } +} + +function clearState() { + try { + localStorage.removeItem(StorageKey); + } catch (err) { + // ignore + } +} + +export { loadState, saveState, clearState }; diff --git a/src/misc/utils.ts b/src/misc/utils.ts new file mode 100644 index 0000000..9497026 --- /dev/null +++ b/src/misc/utils.ts @@ -0,0 +1,35 @@ +export function throttle(fn: (...args: T) => unknown, timeout: number) { + let pending = false; + + return (...args: T) => { + if (!pending) { + pending = true; + fn(...args); + setTimeout(() => { + pending = false; + }, timeout); + } + }; +} + +export function debounce(fn: (...args: T) => unknown, timeout: number) { + let timeoutId: ReturnType; + return (...args: T) => { + if (timeoutId) clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + fn(...args); + }, timeout); + }; +} + +export function trimTrailingSlash(s: string) { + return s.replace(/\/$/, ''); +} + +export function pad0(number: number | string, len: number): string { + let output = String(number); + while (output.length < len) { + output = '0' + output; + } + return output; +} diff --git a/src/store/app.ts b/src/store/app.ts new file mode 100644 index 0000000..f6110de --- /dev/null +++ b/src/store/app.ts @@ -0,0 +1,219 @@ +import { DispatchFn, GetStateFn, State, StateApp } from '~/store/types'; + +import { loadState, saveState } from '../misc/storage'; +import { debounce, trimTrailingSlash } from '../misc/utils'; +import { fetchConfigs } from './configs'; +import { closeModal } from './modals'; + +export const getClashAPIConfig = (s: State) => { + const idx = s.app.selectedClashAPIConfigIndex; + return s.app.clashAPIConfigs[idx]; +}; +export const getSelectedClashAPIConfigIndex = (s: State) => s.app.selectedClashAPIConfigIndex; +export const getClashAPIConfigs = (s: State) => s.app.clashAPIConfigs; +export const getTheme = (s: State) => s.app.theme; +export const getSelectedChartStyleIndex = (s: State) => s.app.selectedChartStyleIndex; +export const getLatencyTestUrl = (s: State) => s.app.latencyTestUrl; +export const getCollapsibleIsOpen = (s: State) => s.app.collapsibleIsOpen; +export const getProxySortBy = (s: State) => s.app.proxySortBy; +export const getHideUnavailableProxies = (s: State) => s.app.hideUnavailableProxies; +export const getAutoCloseOldConns = (s: State) => s.app.autoCloseOldConns; +export const getLogStreamingPaused = (s: State) => s.app.logStreamingPaused; + +const saveStateDebounced = debounce(saveState, 600); + +function findClashAPIConfigIndex(getState: GetStateFn, { baseURL, secret }) { + const arr = getClashAPIConfigs(getState()); + for (let i = 0; i < arr.length; i++) { + const x = arr[i]; + if (x.baseURL === baseURL && x.secret === secret) return i; + } +} + +export function addClashAPIConfig({ baseURL, secret }) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const idx = findClashAPIConfigIndex(getState, { baseURL, secret }); + // already exists + if (idx) return; + + const clashAPIConfig = { baseURL, secret, addedAt: Date.now() }; + dispatch('addClashAPIConfig', (s) => { + s.app.clashAPIConfigs.push(clashAPIConfig); + }); + // side effect + saveState(getState().app); + }; +} + +export function removeClashAPIConfig({ baseURL, secret }) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const idx = findClashAPIConfigIndex(getState, { baseURL, secret }); + dispatch('removeClashAPIConfig', (s) => { + s.app.clashAPIConfigs.splice(idx, 1); + }); + // side effect + saveState(getState().app); + }; +} + +export function selectClashAPIConfig({ baseURL, secret }) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const idx = findClashAPIConfigIndex(getState, { baseURL, secret }); + const curr = getSelectedClashAPIConfigIndex(getState()); + if (curr !== idx) { + dispatch('selectClashAPIConfig', (s) => { + s.app.selectedClashAPIConfigIndex = idx; + }); + } + // side effect + saveState(getState().app); + + // manual clean up is too complex + // we just reload the app + try { + window.location.reload(); + } catch (err) { + // ignore + } + }; +} + +// unused +export function updateClashAPIConfig({ baseURL, secret }) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const clashAPIConfig = { baseURL, secret }; + dispatch('appUpdateClashAPIConfig', (s) => { + s.app.clashAPIConfigs[0] = clashAPIConfig; + }); + // side effect + saveState(getState().app); + dispatch(closeModal('apiConfig')); + dispatch(fetchConfigs(clashAPIConfig)); + }; +} + +const rootEl = document.querySelector('html'); +type ThemeType = 'dark' | 'light' | 'auto'; + +function setTheme(theme: ThemeType = 'dark') { + if (theme === 'auto') { + rootEl.setAttribute('data-theme', 'auto'); + } else if (theme === 'dark') { + rootEl.setAttribute('data-theme', 'dark'); + } else { + rootEl.setAttribute('data-theme', 'light'); + } +} + +export function switchTheme(nextTheme = 'auto') { + return (dispatch: DispatchFn, getState: GetStateFn) => { + const currentTheme = getTheme(getState()); + if (currentTheme === nextTheme) return; + // side effect + setTheme(nextTheme as ThemeType); + dispatch('storeSwitchTheme', (s) => { + s.app.theme = nextTheme; + }); + // side effect + saveState(getState().app); + }; +} + +export function selectChartStyleIndex(selectedChartStyleIndex: number | string) { + return (dispatch: DispatchFn, getState: GetStateFn) => { + dispatch('appSelectChartStyleIndex', (s) => { + s.app.selectedChartStyleIndex = Number(selectedChartStyleIndex); + }); + // side effect + saveState(getState().app); + }; +} + +export function updateAppConfig(name: string, value: unknown) { + return (dispatch: DispatchFn, getState: GetStateFn) => { + dispatch('appUpdateAppConfig', (s) => { + s.app[name] = value; + }); + // side effect + saveState(getState().app); + }; +} + +export function updateCollapsibleIsOpen(prefix: string, name: string, v: boolean) { + return (dispatch: DispatchFn, getState: GetStateFn) => { + dispatch('updateCollapsibleIsOpen', (s: State) => { + s.app.collapsibleIsOpen[`${prefix}:${name}`] = v; + }); + // side effect + saveStateDebounced(getState().app); + }; +} + +const defaultClashAPIConfig = { + baseURL: document.getElementById('app')?.getAttribute('data-base-url') ?? 'http://127.0.0.1:9090', + secret: '', + addedAt: 0, +}; +// type Theme = 'light' | 'dark'; +const defaultState: StateApp = { + selectedClashAPIConfigIndex: 0, + clashAPIConfigs: [defaultClashAPIConfig], + + latencyTestUrl: 'http://www.gstatic.com/generate_204', + selectedChartStyleIndex: 0, + theme: 'dark', + + // type { [string]: boolean } + collapsibleIsOpen: {}, + // how proxies are sorted in a group or provider + proxySortBy: 'Natural', + hideUnavailableProxies: false, + autoCloseOldConns: false, + logStreamingPaused: false, +}; + +function parseConfigQueryString() { + const { search } = window.location; + const collector: Record = {}; + if (typeof search !== 'string' || search === '') return collector; + const qs = search.replace(/^\?/, '').split('&'); + for (let i = 0; i < qs.length; i++) { + const [k, v] = qs[i].split('='); + collector[k] = encodeURIComponent(v); + } + return collector; +} + +export function initialState() { + let s = loadState(); + s = { ...defaultState, ...s }; + const query = parseConfigQueryString(); + + const conf = s.clashAPIConfigs[s.selectedClashAPIConfigIndex]; + if (conf) { + const url = new URL(conf.baseURL); + if (query.hostname) { + if (query.hostname.indexOf('http') === 0) { + url.href = decodeURIComponent(query.hostname); + } else { + url.hostname = query.hostname; + } + } + if (query.port) { + url.port = query.port; + } + // url.href is a stringifier and it appends a trailing slash + // that is not we want + conf.baseURL = trimTrailingSlash(url.href); + if (query.secret) { + conf.secret = query.secret; + } + } + + if (query.theme === 'dark' || query.theme === 'light') { + s.theme = query.theme; + } + // set initial theme + setTheme(s.theme); + return s; +} diff --git a/src/store/configs.ts b/src/store/configs.ts new file mode 100644 index 0000000..1d697dd --- /dev/null +++ b/src/store/configs.ts @@ -0,0 +1,185 @@ +import { + ClashGeneralConfig, + DispatchFn, + GetStateFn, + State, + StateConfigs, + TunPartial, +} from '~/store/types'; +import { ClashAPIConfig } from '~/types'; + +import * as configsAPI from '../api/configs'; +import * as trafficAPI from '../api/traffic'; +import { openModal } from './modals'; + +export const getConfigs = (s: State) => s.configs.configs; +export const getHaveFetched = (s: State) => s.configs.haveFetchedConfig; +export const getLogLevel = (s: State) => s.configs.configs['log-level']; + +export function fetchConfigs(apiConfig: ClashAPIConfig) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + let res: Response; + try { + res = await configsAPI.fetchConfigs(apiConfig); + } catch (err) { + // TypeError and AbortError + dispatch(openModal('apiConfig')); + return; + } + + if (!res.ok) { + console.log('Error fetch configs', res.statusText); + dispatch(openModal('apiConfig')); + return; + } + + const payload = await res.json(); + + dispatch('store/configs#fetchConfigs', (s) => { + s.configs.configs = payload; + }); + + const haveFetchedConfig = getHaveFetched(getState()); + + if (haveFetchedConfig) { + // normally user will land on the "traffic chart" page first + // calling this here will let the data start streaming + // the traffic chart should already subscribed to the streaming + trafficAPI.fetchData(apiConfig); + } else { + dispatch(markHaveFetchedConfig()); + } + }; +} + +function markHaveFetchedConfig() { + return (dispatch: DispatchFn) => { + dispatch('store/configs#markHaveFetchedConfig', (s: State) => { + s.configs.haveFetchedConfig = true; + }); + }; +} + +type generalConfig = Omit; + +export function updateConfigs( + apiConfig: ClashAPIConfig, + partialConfg: TunPartial +) { + return async (dispatch: DispatchFn) => { + configsAPI + .updateConfigs(apiConfig, partialConfg) + .then( + (res) => { + if (res.ok === false) { + // eslint-disable-next-line no-console + console.log('Error update configs', res.statusText); + } + }, + (err) => { + // eslint-disable-next-line no-console + console.log('Error update configs', err); + throw err; + } + ) + .then(() => { + dispatch(fetchConfigs(apiConfig)); + }); + + dispatch('storeConfigsOptimisticUpdateConfigs', (s) => { + s.configs.configs = { ...s.configs.configs, ...partialConfg } as generalConfig; + }); + }; +} + +export function reloadConfigFile(apiConfig: ClashAPIConfig) { + return async (dispatch: DispatchFn) => { + configsAPI + .reloadConfigFile(apiConfig) + .then( + (res) => { + if (res.ok === false) { + // eslint-disable-next-line no-console + console.log('Error reload config file', res.statusText); + } + }, + (err) => { + // eslint-disable-next-line no-console + console.log('Error reload config file', err); + throw err; + } + ) + .then(() => { + dispatch(fetchConfigs(apiConfig)); + }); + }; +} + +export function updateGeoDatabasesFile(apiConfig: ClashAPIConfig) { + return async (dispatch: DispatchFn) => { + configsAPI + .updateGeoDatabasesFile(apiConfig) + .then( + (res) => { + if (res.ok === false) { + // eslint-disable-next-line no-console + console.log('Error update geo databases file', res.statusText); + } + }, + (err) => { + // eslint-disable-next-line no-console + console.log('Error update geo databases file', err); + throw err; + } + ) + .then(() => { + dispatch(fetchConfigs(apiConfig)); + }); + }; +} + +export function flushFakeIPPool(apiConfig: ClashAPIConfig) { + return async (dispatch: DispatchFn) => { + configsAPI + .flushFakeIPPool(apiConfig) + .then( + (res) => { + if (res.ok === false) { + // eslint-disable-next-line no-console + console.log('Error flush FakeIP pool', res.statusText); + } + }, + (err) => { + // eslint-disable-next-line no-console + console.log('Error flush FakeIP pool', err); + throw err; + } + ) + .then(() => { + dispatch(fetchConfigs(apiConfig)); + }); + }; +} + +export const initialState: StateConfigs = { + configs: { + port: 7890, + 'socks-port': 7891, + 'mixed-port': 0, + 'redir-port': 0, + 'tproxy-port': 0, + 'mitm-port': 0, + 'allow-lan': false, + mode: 'rule', + 'log-level': 'uninit', + sniffing: false, + tun: { + enable: false, + device: '', + stack: '', + 'dns-hijack': [], + 'auto-route': false, + }, + }, + haveFetchedConfig: false, +}; diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..4fc8e4c --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,33 @@ +import { + initialState as app, + removeClashAPIConfig, + selectChartStyleIndex, + selectClashAPIConfig, + updateAppConfig, + updateCollapsibleIsOpen, +} from './app'; +import { initialState as configs } from './configs'; +import { initialState as logs } from './logs'; +import { initialState as modals } from './modals'; +import { actions as proxiesActions, initialState as proxies } from './proxies'; + +export const initialState = { + app: app(), + modals, + configs, + proxies, + logs, +}; + +export const actions = { + selectChartStyleIndex, + updateAppConfig, + + app: { + updateCollapsibleIsOpen, + updateAppConfig, + removeClashAPIConfig, + selectClashAPIConfig, + }, + proxies: proxiesActions, +}; diff --git a/src/store/logs.ts b/src/store/logs.ts new file mode 100644 index 0000000..f5711ef --- /dev/null +++ b/src/store/logs.ts @@ -0,0 +1,58 @@ +import { createSelector } from 'reselect'; + +import { DispatchFn, GetStateFn, Log, State } from '~/store/types'; + +const LogSize = 300; + +const getLogs = (s: State) => s.logs.logs; +const getTail = (s: State) => s.logs.tail; +export const getSearchText = (s: State) => s.logs.searchText; +export const getLogsForDisplay = createSelector( + getLogs, + getTail, + getSearchText, + (logs, tail, searchText) => { + const x = []; + for (let i = tail; i >= 0; i--) { + x.push(logs[i]); + } + if (logs.length === LogSize) { + for (let i = LogSize - 1; i > tail; i--) { + x.push(logs[i]); + } + } + + if (searchText === '') return x; + return x.filter((r) => r.payload.toLowerCase().indexOf(searchText) >= 0); + } +); + +export function updateSearchText(text: string) { + return (dispatch: DispatchFn) => { + dispatch('logsUpdateSearchText', (s) => { + s.logs.searchText = text.toLowerCase(); + }); + }; +} + +export function appendLog(log: Log) { + return (dispatch: DispatchFn, getState: GetStateFn) => { + const s = getState(); + const logs = getLogs(s); + const tailCurr = getTail(s); + const tail = tailCurr >= LogSize - 1 ? 0 : tailCurr + 1; + // mutate intentionally for performance + logs[tail] = log; + + dispatch('logsAppendLog', (s: State) => { + s.logs.tail = tail; + }); + }; +} + +export const initialState = { + searchText: '', + logs: [], + // tail's initial value must be -1 + tail: -1, +}; diff --git a/src/store/modals.ts b/src/store/modals.ts new file mode 100644 index 0000000..0b27ce9 --- /dev/null +++ b/src/store/modals.ts @@ -0,0 +1,19 @@ +import { DispatchFn } from './types'; + +export function openModal(modalName: string) { + return (dispatch: DispatchFn) => { + dispatch(`openModal:${modalName}`, (s) => { + s.modals[modalName] = true; + }); + }; +} + +export function closeModal(modalName: string) { + return (dispatch: DispatchFn) => { + dispatch(`closeModal:${modalName}`, (s) => { + s.modals[modalName] = false; + }); + }; +} + +export const initialState = { apiConfig: false }; diff --git a/src/store/proxies.tsx b/src/store/proxies.tsx new file mode 100644 index 0000000..1075d29 --- /dev/null +++ b/src/store/proxies.tsx @@ -0,0 +1,397 @@ +import { atom } from 'recoil'; + +/* import { ProxyItem, ProxiesMapping, DelayMapping } from '~/store/types'; */ +import { + DispatchFn, + FormattedProxyProvider, + GetStateFn, + ProxiesMapping, + ProxyItem, + ProxyProvider, + State, + StateProxies, + SwitchProxyCtxItem, +} from '~/store/types'; +import { ClashAPIConfig } from '~/types'; + +import * as connAPI from '../api/connections'; +import * as proxiesAPI from '../api/proxies'; +import { getAutoCloseOldConns, getLatencyTestUrl } from './app'; + +export const initialState: StateProxies = { + proxies: {}, + delay: {}, + groupNames: [], + showModalClosePrevConns: false, +}; + +const noop = () => null; + +// see all types: +// https://github.com/Dreamacro/clash/blob/master/constant/adapters.go + +// const ProxyTypeBuiltin = ['DIRECT', 'GLOBAL', 'REJECT']; +// const ProxyGroupTypes = ['Fallback', 'URLTest', 'Selector', 'LoadBalance']; +// const ProxyTypes = ['Shadowsocks', 'Snell', 'Socks5', 'Http', 'Vmess']; + +export const NonProxyTypes = [ + 'Direct', + 'Fallback', + 'Reject', + 'Pass', + 'Selector', + 'URLTest', + 'LoadBalance', + 'Unknown', +]; + +export const getProxies = (s: State) => s.proxies.proxies; +export const getDelay = (s: State) => s.proxies.delay; +export const getProxyGroupNames = (s: State) => s.proxies.groupNames; +export const getProxyProviders = (s: State) => s.proxies.proxyProviders || []; +export const getDangleProxyNames = (s: State) => s.proxies.dangleProxyNames; +export const getShowModalClosePrevConns = (s: State) => s.proxies.showModalClosePrevConns; + +export function fetchProxies(apiConfig: ClashAPIConfig) { + return async (dispatch: any, getState: any) => { + const [proxiesData, providersData] = await Promise.all([ + proxiesAPI.fetchProxies(apiConfig), + proxiesAPI.fetchProviderProxies(apiConfig), + ]); + + const { providers: proxyProviders, proxies: providerProxies } = formatProxyProviders( + providersData.providers + ); + const proxies = { ...providerProxies, ...proxiesData.proxies }; + const [groupNames, proxyNames] = retrieveGroupNamesFrom(proxies); + + const delayPrev = getDelay(getState()); + const delayNext = { ...delayPrev }; + + for (let i = 0; i < proxyNames.length; i++) { + const name = proxyNames[i]; + const { history } = proxies[name] || { history: [] }; + const h = history[history.length - 1]; + if (h && typeof h.delay === 'number') { + delayNext[name] = { number: h.delay }; + } + } + + // proxies that are not from a provider + const dangleProxyNames = []; + for (const v of proxyNames) { + if (!providerProxies[v]) dangleProxyNames.push(v); + } + + dispatch('store/proxies#fetchProxies', (s: State) => { + s.proxies.proxies = proxies; + s.proxies.groupNames = groupNames; + s.proxies.delay = delayNext; + s.proxies.proxyProviders = proxyProviders; + s.proxies.dangleProxyNames = dangleProxyNames; + }); + }; +} + +export function updateProviderByName(apiConfig: ClashAPIConfig, name: string) { + return async (dispatch: DispatchFn) => { + try { + await proxiesAPI.updateProviderByName(apiConfig, name); + } catch (x) { + // ignore + } + // should be optimized + // but ¯\_(ツ)_/¯ + dispatch(fetchProxies(apiConfig)); + }; +} + +export function updateProviders(apiConfig: ClashAPIConfig, names: string[]) { + return async (dispatch: DispatchFn) => { + for (let i = 0; i < names.length; i++) { + try { + await proxiesAPI.updateProviderByName(apiConfig, names[i]); + } catch (x) { + // ignore + } + } + // should be optimized + // but ¯\_(ツ)_/¯ + dispatch(fetchProxies(apiConfig)); + }; +} + +async function healthcheckProviderByNameInternal(apiConfig: ClashAPIConfig, name: string) { + try { + await proxiesAPI.healthcheckProviderByName(apiConfig, name); + } catch (x) { + // ignore + } +} + +export function healthcheckProviderByName(apiConfig: ClashAPIConfig, name: string) { + return async (dispatch: DispatchFn) => { + await healthcheckProviderByNameInternal(apiConfig, name); + // should be optimized + // but ¯\_(ツ)_/¯ + await dispatch(fetchProxies(apiConfig)); + }; +} + +async function closeGroupConns( + apiConfig: ClashAPIConfig, + groupName: string, + exceptionItemName: string +) { + const res = await connAPI.fetchConns(apiConfig); + if (!res.ok) { + console.log('unable to fetch all connections', res.statusText); + /* throw new Error(); */ + } + const json = await res.json(); + const connections = json.connections; + const idsToClose = []; + for (const conn of connections) { + if ( + // include the groupName + conn.chains.indexOf(groupName) > -1 && + // but not include the itemName + conn.chains.indexOf(exceptionItemName) < 0 + ) { + idsToClose.push(conn.id); + } + } + + await Promise.all(idsToClose.map((id) => connAPI.closeConnById(apiConfig, id).catch(noop))); +} + +function resolveChain(proxies: ProxiesMapping, groupName: string, itemName: string) { + const chain = [itemName, groupName]; + + let child: ProxyItem; + let childKey = itemName; + while ((child = proxies[childKey]) && child.now) { + chain.unshift(child.now); + childKey = child.now; + } + return chain; +} + +async function switchProxyImpl( + dispatch: DispatchFn, + getState: GetStateFn, + apiConfig: ClashAPIConfig, + groupName: string, + itemName: string +) { + try { + const res = await proxiesAPI.requestToSwitchProxy(apiConfig, groupName, itemName); + if (res.ok === false) { + throw new Error(`failed to switch proxy: res.statusText`); + } + } catch (err) { + // eslint-disable-next-line no-console + console.log(err, 'failed to swith proxy'); + throw err; + } + + dispatch(fetchProxies(apiConfig)); + const autoCloseOldConns = getAutoCloseOldConns(getState()); + if (autoCloseOldConns) { + // use fresh state + const proxies = getProxies(getState()); + // no wait + closePrevConns(apiConfig, proxies, { groupName, itemName }); + } + + /* dispatch('showModalClosePrevConns', (s: GlobalState) => { */ + /* s.proxies.showModalClosePrevConns = true; */ + /* s.proxies.switchProxyCtx = { to: { groupName, itemName } }; */ + /* }); */ +} + +function closeModalClosePrevConns() { + return (dispatch: DispatchFn) => { + dispatch('closeModalClosePrevConns', (s: State) => { + s.proxies.showModalClosePrevConns = false; + }); + }; +} + +function closePrevConns( + apiConfig: ClashAPIConfig, + proxies: ProxiesMapping, + switchTo: SwitchProxyCtxItem +) { + // we must have fetched the proxies before + // so the proxies here is fresh + /* const proxies = s.proxies.proxies; */ + const chain = resolveChain(proxies, switchTo.groupName, switchTo.itemName); + closeGroupConns(apiConfig, switchTo.groupName, chain[0]); +} + +function closePrevConnsAndTheModal(apiConfig: ClashAPIConfig) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const s = getState(); + const switchTo = s.proxies.switchProxyCtx?.to; + if (!switchTo) { + dispatch(closeModalClosePrevConns()); + return; + } + + // we must have fetched the proxies before + // so the proxies here is fresh + const proxies = s.proxies.proxies; + closePrevConns(apiConfig, proxies, switchTo); + + dispatch('closePrevConnsAndTheModal', (s: State) => { + s.proxies.showModalClosePrevConns = false; + s.proxies.switchProxyCtx = undefined; + }); + }; +} + +export function switchProxy(apiConfig: ClashAPIConfig, groupName: string, itemName: string) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + // switch proxy asynchronously + switchProxyImpl(dispatch, getState, apiConfig, groupName, itemName).catch(noop); + + // optimistic UI update + dispatch('store/proxies#switchProxy', (s) => { + const proxies = s.proxies.proxies; + if (proxies[groupName] && proxies[groupName].now) { + proxies[groupName].now = itemName; + } + }); + }; +} + +function requestDelayForProxyOnce(apiConfig: ClashAPIConfig, name: string) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const latencyTestUrl = getLatencyTestUrl(getState()); + const res = await proxiesAPI.requestDelayForProxy(apiConfig, name, latencyTestUrl); + let error = ''; + if (res.ok === false) { + error = res.statusText; + } + const { delay } = await res.json(); + + const delayPrev = getDelay(getState()); + const delayNext = { + ...delayPrev, + [name]: { + error, + number: delay, + }, + }; + + dispatch('requestDelayForProxyOnce', (s) => { + s.proxies.delay = delayNext; + }); + }; +} + +export function requestDelayForProxy(apiConfig: ClashAPIConfig, name: string) { + return async (dispatch: DispatchFn) => { + await dispatch(requestDelayForProxyOnce(apiConfig, name)); + }; +} + +export function requestDelayForProxies(apiConfig: ClashAPIConfig, names: string[]) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const proxyNames = getDangleProxyNames(getState()); + + const works = names + // remove names that are provided by proxy providers + .filter((p) => proxyNames.indexOf(p) > -1) + .map((p) => dispatch(requestDelayForProxy(apiConfig, p))); + await Promise.all(works); + await dispatch(fetchProxies(apiConfig)); + }; +} + +export function requestDelayAll(apiConfig: ClashAPIConfig) { + return async (dispatch: DispatchFn, getState: GetStateFn) => { + const proxyNames = getDangleProxyNames(getState()); + await Promise.all(proxyNames.map((p) => dispatch(requestDelayForProxy(apiConfig, p)))); + const proxyProviders = getProxyProviders(getState()); + // one by one + for (const p of proxyProviders) { + await healthcheckProviderByNameInternal(apiConfig, p.name); + } + await dispatch(fetchProxies(apiConfig)); + }; +} + +function retrieveGroupNamesFrom(proxies: Record) { + let groupNames = []; + let globalAll: string[]; + const proxyNames = []; + for (const prop in proxies) { + const p = proxies[prop]; + if (p.all && Array.isArray(p.all)) { + groupNames.push(prop); + if (prop === 'GLOBAL') { + globalAll = p.all; + } + } else if (NonProxyTypes.indexOf(p.type) < 0) { + proxyNames.push(prop); + } + } + if (globalAll) { + // Put GLOBAL in the end + globalAll.push('GLOBAL'); + // Sort groups according to its index in GLOBAL group + groupNames = groupNames + .map((name) => [globalAll.indexOf(name), name]) + .sort((a, b) => a[0] - b[0]) + .map((group) => group[1]); + } + return [groupNames, proxyNames]; +} + +type ProvidersRaw = { + [key: string]: ProxyProvider; +}; + +function formatProxyProviders(providersInput: ProvidersRaw): { + providers: Array; + proxies: { [key: string]: ProxyItem }; +} { + const keys = Object.keys(providersInput); + const providers = []; + const proxies = {}; + for (let i = 0; i < keys.length; i++) { + const provider: ProxyProvider = providersInput[keys[i]]; + if (provider.name === 'default' || provider.vehicleType === 'Compatible') { + continue; + } + const proxiesArr = provider.proxies; + const names = []; + for (let j = 0; j < proxiesArr.length; j++) { + const proxy = proxiesArr[j]; + proxies[proxy.name] = proxy; + names.push(proxy.name); + } + + // mutate directly + provider.proxies = names; + providers.push(provider); + } + + return { + providers, + proxies, + }; +} + +export const actions = { + requestDelayForProxies, + closeModalClosePrevConns, + closePrevConnsAndTheModal, +}; + +export const proxyFilterText = atom({ + key: 'proxyFilterText', + default: '', +}); diff --git a/src/store/rules.ts b/src/store/rules.ts new file mode 100644 index 0000000..bdd835d --- /dev/null +++ b/src/store/rules.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const ruleFilterText = atom({ + key: 'ruleFilterText', + default: '', +}); diff --git a/src/store/types.ts b/src/store/types.ts new file mode 100644 index 0000000..86a3df3 --- /dev/null +++ b/src/store/types.ts @@ -0,0 +1,144 @@ +import type { ClashAPIConfig } from '~/types'; + +export type ClashAPIConfigWithAddedAt = ClashAPIConfig & { addedAt?: number }; +export type StateApp = { + selectedClashAPIConfigIndex: number; + clashAPIConfigs: ClashAPIConfigWithAddedAt[]; + + latencyTestUrl: string; + selectedChartStyleIndex: number; + theme: string; + + collapsibleIsOpen: Record; + proxySortBy: string; + hideUnavailableProxies: boolean; + autoCloseOldConns: boolean; + logStreamingPaused: boolean; +}; + +export type ClashTunConfig = { + enable: boolean; + device?: string; + stack: string; + 'dns-hijack': string[]; + 'auto-route': boolean; +}; + +export type ClashGeneralConfig = { + port: number; + 'socks-port': number; + 'mixed-port': number; + 'redir-port': number; + 'tproxy-port': number; + 'mitm-port'?: number; + 'allow-lan': boolean; + 'interface-name'?: string; + mode: string; + 'log-level': string; + sniffing?: boolean; + tun?: ClashTunConfig; +}; + +export type TunPartial = { + [P in keyof T]?: T[P] extends ClashTunConfig ? TunPartial : T[P]; +}; + +///// store.proxies + +type LatencyHistory = Array<{ time: string; delay: number }>; +type PrimitiveProxyType = 'Shadowsocks' | 'Snell' | 'Socks5' | 'Http' | 'Vmess'; + +export type SubscriptionInfo = { + Download?: number; + Upload?: number; + Total?: number; + Expire?: number; +}; +export type ProxyItem = { + name: string; + type: PrimitiveProxyType; + udp: boolean; + xudp?: boolean; + tfo: boolean; + history: LatencyHistory; + all?: string[]; + now?: string; +}; +export type ProxiesMapping = Record; +export type DelayMapping = Record; + +export type ProxyProvider = { + name: string; + type: 'Proxy'; + updatedAt: string; + vehicleType: 'HTTP' | 'File' | 'Compatible'; + proxies: Array; + subscriptionInfo?: SubscriptionInfo; +}; + +export type FormattedProxyProvider = Omit & { + proxies: string[]; +}; + +export type SwitchProxyCtxItem = { groupName: string; itemName: string }; +type SwitchProxyCtx = { + to: SwitchProxyCtxItem; +}; +export type StateProxies = { + proxies: ProxiesMapping; + delay: DelayMapping; + groupNames: string[]; + proxyProviders?: FormattedProxyProvider[]; + dangleProxyNames?: string[]; + + showModalClosePrevConns: boolean; + switchProxyCtx?: SwitchProxyCtx; +}; + +///// store.logs + +export type Log = { + time: string; + even: boolean; + payload: string; + type: string; + id: string; +}; + +export type StateLogs = { + searchText: string; + logs: Log[]; + tail: number; +}; + +///// store.configs + +export type StateConfigs = { + configs: ClashGeneralConfig; + haveFetchedConfig: boolean; +}; + +///// store.modals + +export type StateModals = { + apiConfig: boolean; +}; + +////// + +export type State = { + app: StateApp; + configs: StateConfigs; + proxies: StateProxies; + logs: StateLogs; + modals: StateModals; +}; + +export type GetStateFn = () => State; +export interface DispatchFn { + (msg: string, change: (s: State) => void): void; + (action: (dispatch: DispatchFn, getState: GetStateFn) => Promise): ReturnType< + typeof action + >; + (action: (dispatch: DispatchFn, getState: GetStateFn) => void): ReturnType; +} diff --git a/src/styles/main.scss b/src/styles/main.scss new file mode 100644 index 0000000..c447ce5 --- /dev/null +++ b/src/styles/main.scss @@ -0,0 +1,219 @@ +@import '@fontsource/inter/latin-400.css'; +@import '@fontsource/inter/latin-800.css'; +@import '@fontsource/roboto-mono/latin-400.css'; +@import 'modern-normalize/modern-normalize.css'; + +.relative { + position: relative; +} + +.border-left, +.border-top, +.border-bottom { + position: relative; +} + +%border { + position: absolute; + content: ''; + height: 1px; + width: 100%; + transform: scaleY(0.5) translateZ(0); + left: 0; + right: 0; + background: #555; +} + +%border1 { + position: absolute; + content: ''; + height: 100%; + width: 1px; + transform: scaleX(0.5) translateZ(0); + top: 0; + bottom: 0; + background: #555; +} + +.border-top::before { + @extend %border; + top: 0; +} + +.border-bottom::after { + @extend %border; + bottom: 0; +} + +.border-left::before { + @extend %border1; + left: 0; +} + +*, +*:before, +*:after { + box-sizing: border-box; +} + +:root { + --font-mono: 'Roboto Mono', Menlo, monospace; + // prettier-ignore + --font-normal: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, "Twemoji Mozilla", Segoe UI Emoji, Segoe UI Symbol, 'PingFang SC', 'Microsoft YaHei', '\5fae\8f6f\96c5\9ed1', Arial; + --color-focus-blue: #1a73e8; + --btn-bg: #387cec; +} + +body { + font-family: var(--font-normal); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + ::-webkit-scrollbar { + z-index: 11; + background: transparent; + + &-thumb { + border-radius: 5px; + background: #3b5f76; + } + } + + ::-webkit-scrollbar:vertical { + width: 6px; + } + + ::-webkit-scrollbar:horizontal { + height: 6px; + } + + margin: 0; + padding: 0; +} + +@mixin dark { + --color-background: #202020; + --color-background2: rgba(32, 32, 32, 0.3); + --color-bg-card: #2d2d2d; + --card-hover-border-lightness: 30%; + --color-text: #ddd; + --color-text-secondary: #ccc; + --color-text-highlight: #fff; + --color-bg-sidebar: #2d2d30; + --color-sb-active-row-bg: #494b4e; + --color-input-bg: #2d2d30; + --color-input-border: #3f3f3f; + --color-toggle-bg: #353535; + --color-toggle-selected: #181818; + --color-icon: #c7c7c7; + --color-separator: #333; + --color-btn-bg: #232323; + --color-btn-fg: #bebebe; + --color-bg-proxy: #303030; + --color-row-odd: #282828; + --bg-log-info-tag: #454545; + --bg-modal: #1f1f20; + --bg-near-transparent: rgba(255, 255, 255, 0.1); + --bg-tooltip: #111; + --bc-tooltip: #555; + --select-border-color: #040404; + --select-bg-hover: url(data:image/svg+xml,%0A%20%20%20%20%3Csvg%20width%3D%228%22%20height%3D%2224%22%20viewBox%3D%220%200%208%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%207L7%2011H1L4%207Z%22%20fill%3D%22%23ffffff%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%2017L1%2013L7%2013L4%2017Z%22%20fill%3D%22%23ffffff%22%20%2F%3E%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20); + --bg-log-info-card: #262626; +} + +@mixin light { + --color-background: #eee; + --color-background2: rgba(240, 240, 240, 0.3); + --color-bg-card: #fafafa; + --card-hover-border-lightness: 80%; + --color-text: #222; + --color-text-secondary: #646464; + --color-text-highlight: #040404; + --color-bg-sidebar: #f8f8f8; + --color-sb-active-row-bg: #d8d8d8; + --color-input-bg: #f0f0f0; + --color-input-border: #c0c0c0; + --color-toggle-bg: #ffffff; + --color-toggle-selected: #d7d7d7; + --color-icon: #5b5b5b; + --color-separator: #ccc; + --color-btn-bg: #f4f4f4; + --color-btn-fg: #101010; + --color-bg-proxy: #fafafa; + --color-row-odd: #f5f5f5; + --bg-log-info-tag: #888; + --bg-modal: #fbfbfb; + --bg-near-transparent: rgba(0, 0, 0, 0.1); + --bg-tooltip: #f0f0f0; + --bc-tooltip: #ccc; + --select-border-color: #999999; + --select-bg-hover: url(data:image/svg+xml,%0A%20%20%20%20%3Csvg%20width%3D%228%22%20height%3D%2224%22%20viewBox%3D%220%200%208%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%207L7%2011H1L4%207Z%22%20fill%3D%22%23222222%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%2017L1%2013L7%2013L4%2017Z%22%20fill%3D%22%23222222%22%20%2F%3E%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20); + --bg-log-info-card: #f5f5f5; +} + +:root[data-theme='auto'] { + @media (prefers-color-scheme: dark) { + @include dark; + color-scheme: dark; + } + + @media (prefers-color-scheme: light) { + @include light; + color-scheme: light; + } +} + +:root[data-theme='dark'] { + @include dark; + color-scheme: dark; +} + +:root[data-theme='light'] { + @include light; + color-scheme: light; +} + +.flexCenter { + display: flex; + align-items: center; + justify-content: center; +} + +.fabgrp { + position: fixed; + z-index: 3; + right: 20px; + bottom: 20px; +} + +.visually-hidden { + position: absolute; + overflow: hidden; + clip: rect(0 0 0 0); + width: 1px; + height: 1px; + margin: -1px; + border: 0; + padding: 0; +} + +/**** @reach/tooltip/styles.css ****/ +:root { + --reach-tooltip: 1; +} + +[data-reach-tooltip] { + z-index: 1; + pointer-events: none; + position: absolute; + padding: 0.25em 0.5em; + box-shadow: 2px 2px 10px hsla(0, 0%, 0%, 0.1); + white-space: nowrap; + font-size: 85%; + background: var(--bg-tooltip); + color: var(--color-text); + border: solid 1px var(--bc-tooltip); + border-radius: 4px; +} diff --git a/src/styles/utils/custom-media.scss b/src/styles/utils/custom-media.scss new file mode 100644 index 0000000..f53ece0 --- /dev/null +++ b/src/styles/utils/custom-media.scss @@ -0,0 +1,3 @@ +@custom-media --breakpoint-not-small screen and (min-width: 30em); +@custom-media --breakpoint-medium screen and (min-width: 30em) and (max-width: 60em); +@custom-media --breakpoint-large screen and (min-width: 60em); diff --git a/src/sw.ts b/src/sw.ts new file mode 100644 index 0000000..f577677 --- /dev/null +++ b/src/sw.ts @@ -0,0 +1,74 @@ +/// +/* eslint-disable no-restricted-globals */ + +// This service worker can be customized! +// See https://developers.google.com/web/tools/workbox/modules +// for the list of available Workbox modules, or add any other +// code you'd like. +// You can also remove this file if you'd prefer not to use a +// service worker, and the Workbox build step will be skipped. + +import { clientsClaim } from 'workbox-core'; +import { ExpirationPlugin } from 'workbox-expiration'; +import { createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'; +import { registerRoute } from 'workbox-routing'; +import { StaleWhileRevalidate } from 'workbox-strategies'; + +declare const self: ServiceWorkerGlobalScope; + +clientsClaim(); + +precacheAndRoute(self.__WB_MANIFEST); + +// Set up App Shell-style routing, so that all navigation requests +// are fulfilled with your index.html shell. Learn more at +// https://developers.google.com/web/fundamentals/architecture/app-shell +const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); +registerRoute( + // Return false to exempt requests from being fulfilled by index.html. + ({ request, url }: { request: Request; url: URL }) => { + // If this isn't a navigation, skip. + if (request.mode !== 'navigate') { + return false; + } + + // If this is a URL that starts with /_, skip. + if (url.pathname.startsWith('/_')) { + return false; + } + + // If this looks like a URL for a resource, because it contains + // a file extension, skip. + if (url.pathname.match(fileExtensionRegexp)) { + return false; + } + + // Return true to signal that we want to use the handler. + return true; + }, + createHandlerBoundToURL('index.html') +); + +// An example runtime caching route for requests that aren't handled by the +// precache, in this case same-origin .png requests like those from in public/ +registerRoute( + // Add in any other file extensions or routing criteria as needed. + ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), + // Customize this strategy as needed, e.g., by changing to CacheFirst. + new StaleWhileRevalidate({ + cacheName: 'images', + plugins: [ + // Ensure that once this runtime cache reaches a maximum size the + // least-recently used images are removed. + new ExpirationPlugin({ maxEntries: 50 }), + ], + }) +); + +// This allows the web app to trigger skipWaiting via +// registration.waiting.postMessage({type: 'SKIP_WAITING'}) +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting(); + } +}); diff --git a/src/swRegistration.ts b/src/swRegistration.ts new file mode 100644 index 0000000..0a684a8 --- /dev/null +++ b/src/swRegistration.ts @@ -0,0 +1,127 @@ +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) +); + +type Config = { + onSuccess?: (registration: ServiceWorkerRegistration) => void; + onUpdate?: (registration: ServiceWorkerRegistration) => void; +}; + +export function register(config?: Config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/sw.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log('This web app is being served cache-first by a service worker'); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl: string, config?: Config) { + navigator.serviceWorker + .register(swUrl) + .then((registration) => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://cra.link/PWA.' + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch((error) => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl: string, config?: Config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { 'Service-Worker': 'script' }, + }) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type'); + if ( + response.status === 404 || + (contentType != null && contentType.indexOf('javascript') === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log('No internet connection found. App is running in offline mode.'); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready + .then((registration) => { + registration.unregister(); + }) + .catch((error) => { + console.error(error.message); + }); + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..8446dfc --- /dev/null +++ b/src/types.ts @@ -0,0 +1,6 @@ +export type ClashAPIConfig = { + baseURL: string; + secret?: string; +}; + +export type LogsAPIConfig = ClashAPIConfig & { logLevel: string }; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f838048 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "~/*": ["src/*"] + }, + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext", "WebWorker"], + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": false, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react" + }, + "include": ["src"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..ef53dca --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,39 @@ +import react from '@vitejs/plugin-react'; +import * as path from 'path'; +import { defineConfig } from 'vite'; +import { VitePWA } from 'vite-plugin-pwa'; + +import pkg from './package.json'; + +// https://vitejs.dev/config/ +export default defineConfig(({ mode }) => ({ + define: { + __VERSION__: JSON.stringify(pkg.version), + 'process.env.NODE_ENV': JSON.stringify(mode), + 'process.env.PUBLIC_URL': JSON.stringify('./'), + }, + base: './', + resolve: { + alias: { + '~': path.resolve(__dirname, './src'), + }, + }, + publicDir: 'assets', + build: { + // sourcemap: true, + // the default value is 'dist' + // which make more sense + // but change this may break other people's tools + outDir: 'public', + }, + plugins: [ + react(), + VitePWA({ + srcDir: 'src', + outDir: 'public', + filename: 'sw.ts', + strategies: 'injectManifest', + base: './', + }), + ], +}));