From 7e784654069d9fdacd66dc4098b01c3e712ea7b5 Mon Sep 17 00:00:00 2001 From: alexsparkes Date: Sat, 24 Feb 2024 20:17:11 +0000 Subject: [PATCH] refactor(widgets): Move to new layout of widgets and options --- .../Elements/AddModal}/AddModal.jsx | 3 +- src/components/Elements/AddModal/index.jsx | 1 + src/components/Elements/index.jsx | 1 + .../modals/main/settings/sections/Navbar.jsx | 6 +- .../main/settings/sections/QuickLinks.jsx | 2 +- .../sections/quicklinks/QuickLink.jsx | 68 ----- src/features/modals/main/tabs/Settings.jsx | 125 ++------ src/features/widgets/greeting/index.jsx | 2 + .../greeting/options/GreetingOptions.jsx | 100 +++++++ .../widgets/greeting/options/index.jsx | 1 + src/features/widgets/message/Message.jsx | 2 +- src/features/widgets/message/index.jsx | 2 + .../widgets/message/message_defaults.json | 0 .../message/options/MessageOptions.jsx} | 4 +- .../widgets/message/options/index.jsx | 1 + .../widgets/quicklinks/QuickLinks.jsx | 4 +- src/features/widgets/quicklinks/index.jsx | 2 + .../quicklinks/options/QuickLinksOptions.jsx | 275 ++++++++++++++++++ .../widgets/quicklinks/options/index.jsx | 1 + src/features/widgets/search/index.jsx | 2 + .../widgets/search/options/SearchOptions.jsx | 174 +++++++++++ src/features/widgets/search/options/index.jsx | 1 + src/features/widgets/weather/Weather.jsx | 4 +- src/features/widgets/weather/index.jsx | 2 + .../weather/options/WeatherOptions.jsx} | 4 +- .../widgets/weather/options/index.jsx | 1 + ....timestamp-1708789619302-8ea1d206b4f95.mjs | 110 +++++++ 27 files changed, 727 insertions(+), 171 deletions(-) rename src/{features/modals/main/settings/sections/quicklinks => components/Elements/AddModal}/AddModal.jsx (96%) create mode 100644 src/components/Elements/AddModal/index.jsx delete mode 100644 src/features/modals/main/settings/sections/quicklinks/QuickLink.jsx create mode 100644 src/features/widgets/greeting/index.jsx create mode 100644 src/features/widgets/greeting/options/GreetingOptions.jsx create mode 100644 src/features/widgets/greeting/options/index.jsx create mode 100644 src/features/widgets/message/index.jsx create mode 100644 src/features/widgets/message/message_defaults.json rename src/features/{modals/main/settings/sections/Message.jsx => widgets/message/options/MessageOptions.jsx} (97%) create mode 100644 src/features/widgets/message/options/index.jsx create mode 100644 src/features/widgets/quicklinks/index.jsx create mode 100644 src/features/widgets/quicklinks/options/QuickLinksOptions.jsx create mode 100644 src/features/widgets/quicklinks/options/index.jsx create mode 100644 src/features/widgets/search/index.jsx create mode 100644 src/features/widgets/search/options/SearchOptions.jsx create mode 100644 src/features/widgets/search/options/index.jsx create mode 100644 src/features/widgets/weather/index.jsx rename src/features/{modals/main/settings/sections/Weather.jsx => widgets/weather/options/WeatherOptions.jsx} (98%) create mode 100644 src/features/widgets/weather/options/index.jsx create mode 100644 vite.config.mjs.timestamp-1708789619302-8ea1d206b4f95.mjs diff --git a/src/features/modals/main/settings/sections/quicklinks/AddModal.jsx b/src/components/Elements/AddModal/AddModal.jsx similarity index 96% rename from src/features/modals/main/settings/sections/quicklinks/AddModal.jsx rename to src/components/Elements/AddModal/AddModal.jsx index fe0c7c12..26b23403 100644 --- a/src/features/modals/main/settings/sections/quicklinks/AddModal.jsx +++ b/src/components/Elements/AddModal/AddModal.jsx @@ -76,4 +76,5 @@ function AddModal({ urlError, iconError, addLink, closeModal, edit, editData, ed ); } -export default memo(AddModal); +const MemoizedAddModal = memo(AddModal); +export { MemoizedAddModal as default, MemoizedAddModal as AddModal} \ No newline at end of file diff --git a/src/components/Elements/AddModal/index.jsx b/src/components/Elements/AddModal/index.jsx new file mode 100644 index 00000000..9d77026e --- /dev/null +++ b/src/components/Elements/AddModal/index.jsx @@ -0,0 +1 @@ +export * from './AddModal'; \ No newline at end of file diff --git a/src/components/Elements/index.jsx b/src/components/Elements/index.jsx index 6821f83a..73e09d1c 100644 --- a/src/components/Elements/index.jsx +++ b/src/components/Elements/index.jsx @@ -1,3 +1,4 @@ export * from './Button'; export * from './Tooltip'; export * from './ShareModal'; +export * from './AddModal'; diff --git a/src/features/modals/main/settings/sections/Navbar.jsx b/src/features/modals/main/settings/sections/Navbar.jsx index 42affcbe..36abfb94 100644 --- a/src/features/modals/main/settings/sections/Navbar.jsx +++ b/src/features/modals/main/settings/sections/Navbar.jsx @@ -5,7 +5,7 @@ import { useState, memo } from 'react'; import Modal from 'react-modal'; import { MdAddLink } from 'react-icons/md'; -import AddModal from './quicklinks/AddModal'; +import { AddModal } from 'components/Elements/AddModal'; import Checkbox from '../../../../../components/Form/Settings/Checkbox/Checkbox'; import Dropdown from '../../../../../components/Form/Settings/Dropdown/Dropdown'; @@ -14,7 +14,7 @@ import { Button } from 'components/Elements'; import { Row, Content, Action } from '../../../../../components/Layout/Settings/Item/SettingsItem'; import { Header } from 'components/Layout/Settings'; import { getTitleFromUrl, isValidUrl } from 'utils/links'; -import QuickLink from './quicklinks/QuickLink'; +import { QuickLinks } from 'features/widgets/quicklinks'; function Navbar() { const [showRefreshOptions, setShowRefreshOptions] = useState( @@ -240,7 +240,7 @@ function Navbar() {
{appsModalInfo.items.map((item, i) => ( - startEditLink(item)} diff --git a/src/features/modals/main/settings/sections/QuickLinks.jsx b/src/features/modals/main/settings/sections/QuickLinks.jsx index 44f330a8..fe7a05f3 100644 --- a/src/features/modals/main/settings/sections/QuickLinks.jsx +++ b/src/features/modals/main/settings/sections/QuickLinks.jsx @@ -270,4 +270,4 @@ export default class QuickLinks extends PureComponent { ); } -} +} \ No newline at end of file diff --git a/src/features/modals/main/settings/sections/quicklinks/QuickLink.jsx b/src/features/modals/main/settings/sections/quicklinks/QuickLink.jsx deleted file mode 100644 index 41b462df..00000000 --- a/src/features/modals/main/settings/sections/quicklinks/QuickLink.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import variables from 'config/variables'; - -import { MdEdit, MdCancel } from 'react-icons/md'; - -const QuickLink = ({ item, deleteLink, startEditLink }) => { - let target, - rel = null; - if (localStorage.getItem('quicklinksnewtab') === 'true') { - target = '_blank'; - rel = 'noopener noreferrer'; - } - - const useText = localStorage.getItem('quicklinksText') === 'true'; - - if (useText) { - return ( - deleteLink(item.key, e)} - href={item.url} - target={target} - rel={rel} - draggable={false} - > - {item.name} - - ); - } - - const img = - item.icon || - 'https://icon.horse/icon/ ' + item.url.replace('https://', '').replace('http://', ''); - - return ( -
-
- {item.name} -
-
-
{item.name}
- -
-
-
- - -
-
-
- ); -}; - -export default QuickLink; diff --git a/src/features/modals/main/tabs/Settings.jsx b/src/features/modals/main/tabs/Settings.jsx index 474ac45d..461c9d75 100644 --- a/src/features/modals/main/tabs/Settings.jsx +++ b/src/features/modals/main/tabs/Settings.jsx @@ -5,15 +5,15 @@ import Tabs from './backend/Tabs'; import Overview from '../settings/sections/Overview'; import Navbar from '../settings/sections/Navbar'; -import Greeting from '../settings/sections/Greeting'; +import { GreetingOptions } from 'features/widgets/greeting'; import Time from '../settings/sections/Time'; -import QuickLinks from '../settings/sections/QuickLinks'; +import { QuickLinksOptions } from 'features/widgets/quicklinks'; import Quote from '../settings/sections/Quote'; import Date from '../settings/sections/Date'; -import Message from '../settings/sections/Message'; +import { MessageOptions } from 'features/widgets/message'; import Background from '../settings/sections/background/Background'; -import Search from '../settings/sections/Search'; -import Weather from '../settings/sections/Weather'; +import { SearchOptions } from 'features/widgets/search'; +import { WeatherOptions } from 'features/widgets/weather'; import Appearance from '../settings/sections/Appearance'; import Language from '../settings/sections/Language'; import Advanced from '../settings/sections/Advanced'; @@ -22,98 +22,37 @@ import Experimental from '../settings/sections/Experimental'; import Changelog from '../settings/sections/Changelog'; import About from '../settings/sections/About'; +const sections = [ + { label: 'modals.main.marketplace.product.overview', name: 'order', component: Overview }, + { label: 'modals.main.settings.sections.appearance.navbar.title', name: 'navbar', component: Navbar }, + { label: 'modals.main.settings.sections.greeting.title', name: 'greeting', component: GreetingOptions }, + { label: 'modals.main.settings.sections.time.title', name: 'time', component: Time }, + { label: 'modals.main.settings.sections.quicklinks.title', name: 'quicklinks', component: QuickLinksOptions }, + { label: 'modals.main.settings.sections.quote.title', name: 'quote', component: Quote }, + { label: 'modals.main.settings.sections.date.title', name: 'date', component: Date }, + { label: 'modals.main.settings.sections.message.title', name: 'message', component: MessageOptions }, + { label: 'modals.main.settings.sections.background.title', name: 'background', component: Background }, + { label: 'modals.main.settings.sections.search.title', name: 'search', component: SearchOptions }, + { label: 'modals.main.settings.sections.weather.title', name: 'weather', component: WeatherOptions }, + { label: 'modals.main.settings.sections.appearance.title', name: 'appearance', component: Appearance }, + { label: 'modals.main.settings.sections.language.title', name: 'language', component: Language }, + { label: 'modals.main.settings.sections.advanced.title', name: 'advanced', component: Advanced }, + { label: 'modals.main.settings.sections.stats.title', name: 'stats', component: Stats }, + { label: 'modals.main.settings.sections.experimental.title', name: 'experimental', component: Experimental }, + { label: 'modals.main.settings.sections.changelog.title', name: 'changelog', component: Changelog }, + { label: 'modals.main.settings.sections.about.title', name: 'about', component: About }, +]; + function Settings(props) { return ( props.changeTab(type)} current="settings"> -
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
+ {sections.map(({ label, name, component: Component }) => ( +
+ +
+ ))}
); } -export default memo(Settings); +export default memo(Settings); \ No newline at end of file diff --git a/src/features/widgets/greeting/index.jsx b/src/features/widgets/greeting/index.jsx new file mode 100644 index 00000000..5a75ab25 --- /dev/null +++ b/src/features/widgets/greeting/index.jsx @@ -0,0 +1,2 @@ +export * from './options'; +export * from './Greeting'; \ No newline at end of file diff --git a/src/features/widgets/greeting/options/GreetingOptions.jsx b/src/features/widgets/greeting/options/GreetingOptions.jsx new file mode 100644 index 00000000..8fe2ec80 --- /dev/null +++ b/src/features/widgets/greeting/options/GreetingOptions.jsx @@ -0,0 +1,100 @@ +import variables from 'config/variables'; +import { useState } from 'react'; + +import { Header, Row, Content, Action, PreferencesWrapper } from 'components/Layout/Settings'; +import { Checkbox, Switch, Text } from 'components/Form/Settings'; + +const GreetingOptions = () => { + const [birthday, setBirthday] = useState( + new Date(localStorage.getItem('birthday')) || new Date(), + ); + + const changeDate = (e) => { + const newDate = e.target.value ? new Date(e.target.value) : new Date(); + localStorage.setItem('birthday', newDate); + setBirthday(newDate); + }; + + const GREETING_SECTION = 'modals.main.settings.sections.greeting'; + + const AdditionalOptions = () => { + return ( + + + + + + + + + ); + }; + + const BirthdayOptions = () => { + return ( + + + + + +

+ {variables.getMessage(`${GREETING_SECTION}.birthday_date`)} +

+ +
+
+ ); + }; + + return ( + <> +
+ + + {BirthdayOptions()} + + + ); +}; + +export { GreetingOptions as default, GreetingOptions }; diff --git a/src/features/widgets/greeting/options/index.jsx b/src/features/widgets/greeting/options/index.jsx new file mode 100644 index 00000000..48a5be47 --- /dev/null +++ b/src/features/widgets/greeting/options/index.jsx @@ -0,0 +1 @@ +export * from './GreetingOptions'; \ No newline at end of file diff --git a/src/features/widgets/message/Message.jsx b/src/features/widgets/message/Message.jsx index adbcae16..d7dd5070 100644 --- a/src/features/widgets/message/Message.jsx +++ b/src/features/widgets/message/Message.jsx @@ -42,4 +42,4 @@ const Message = () => { ); }; -export default Message; +export { Message as default, Message }; diff --git a/src/features/widgets/message/index.jsx b/src/features/widgets/message/index.jsx new file mode 100644 index 00000000..bd85bdff --- /dev/null +++ b/src/features/widgets/message/index.jsx @@ -0,0 +1,2 @@ +export * from './Message'; +export * from './options'; \ No newline at end of file diff --git a/src/features/widgets/message/message_defaults.json b/src/features/widgets/message/message_defaults.json new file mode 100644 index 00000000..e69de29b diff --git a/src/features/modals/main/settings/sections/Message.jsx b/src/features/widgets/message/options/MessageOptions.jsx similarity index 97% rename from src/features/modals/main/settings/sections/Message.jsx rename to src/features/widgets/message/options/MessageOptions.jsx index d85a56da..af1853ef 100644 --- a/src/features/modals/main/settings/sections/Message.jsx +++ b/src/features/widgets/message/options/MessageOptions.jsx @@ -8,7 +8,7 @@ import { Header, Row, Content, Action, PreferencesWrapper } from 'components/Lay import { Button } from 'components/Elements'; import EventBus from 'utils/eventbus'; -export default class Message extends PureComponent { +class MessageOptions extends PureComponent { constructor() { super(); this.state = { @@ -141,3 +141,5 @@ export default class Message extends PureComponent { ); } } + +export { MessageOptions as default, MessageOptions }; \ No newline at end of file diff --git a/src/features/widgets/message/options/index.jsx b/src/features/widgets/message/options/index.jsx new file mode 100644 index 00000000..5c290397 --- /dev/null +++ b/src/features/widgets/message/options/index.jsx @@ -0,0 +1 @@ +export * from './MessageOptions'; \ No newline at end of file diff --git a/src/features/widgets/quicklinks/QuickLinks.jsx b/src/features/widgets/quicklinks/QuickLinks.jsx index 9f75c8be..da988abe 100644 --- a/src/features/widgets/quicklinks/QuickLinks.jsx +++ b/src/features/widgets/quicklinks/QuickLinks.jsx @@ -5,7 +5,7 @@ import EventBus from 'utils/eventbus'; import './quicklinks.scss'; -export default class QuickLinks extends PureComponent { +class QuickLinks extends PureComponent { constructor() { super(); this.state = { @@ -119,3 +119,5 @@ export default class QuickLinks extends PureComponent { ); } } + +export { QuickLinks as default, QuickLinks }; \ No newline at end of file diff --git a/src/features/widgets/quicklinks/index.jsx b/src/features/widgets/quicklinks/index.jsx new file mode 100644 index 00000000..2f7b4883 --- /dev/null +++ b/src/features/widgets/quicklinks/index.jsx @@ -0,0 +1,2 @@ +export * from './options'; +export * from './QuickLinks'; \ No newline at end of file diff --git a/src/features/widgets/quicklinks/options/QuickLinksOptions.jsx b/src/features/widgets/quicklinks/options/QuickLinksOptions.jsx new file mode 100644 index 00000000..2da4b778 --- /dev/null +++ b/src/features/widgets/quicklinks/options/QuickLinksOptions.jsx @@ -0,0 +1,275 @@ +import variables from 'config/variables'; +import { PureComponent, createRef } from 'react'; +import { MdAddLink, MdLinkOff } from 'react-icons/md'; +import { Header, Row, Content, Action, PreferencesWrapper } from 'components/Layout/Settings'; +import { Checkbox, Dropdown } from 'components/Form/Settings'; +import { Button } from 'components/Elements'; +import Modal from 'react-modal'; + +import { AddModal } from 'components/Elements/AddModal'; + +import EventBus from 'utils/eventbus'; +import { QuickLink } from '../QuickLinks'; +import { getTitleFromUrl, isValidUrl } from 'utils/links'; + +class QuickLinksOptions extends PureComponent { + constructor() { + super(); + this.state = { + items: JSON.parse(localStorage.getItem('quicklinks')), + showAddModal: false, + urlError: '', + iconError: '', + edit: false, + editData: '', + }; + this.quicklinksContainer = createRef(); + } + + deleteLink(key, event) { + event.preventDefault(); + + // remove link from array + const data = JSON.parse(localStorage.getItem('quicklinks')).filter((i) => i.key !== key); + + localStorage.setItem('quicklinks', JSON.stringify(data)); + this.setState({ + items: data, + }); + + variables.stats.postEvent('feature', 'Quicklink delete'); + } + + async addLink(name, url, icon) { + const data = JSON.parse(localStorage.getItem('quicklinks')); + + if (!url.startsWith('http://') && !url.startsWith('https://')) { + url = 'http://' + url; + } + + if (url.length <= 0 || isValidUrl(url) === false) { + return this.setState({ + urlError: variables.getMessage('widgets.quicklinks.url_error'), + }); + } + + if (icon.length > 0 && isValidUrl(icon) === false) { + return this.setState({ + iconError: variables.getMessage('widgets.quicklinks.url_error'), + }); + } + + data.push({ + name: name || (await getTitleFromUrl(url)), + url, + icon: icon || '', + key: Math.random().toString(36).substring(7) + 1, + }); + + localStorage.setItem('quicklinks', JSON.stringify(data)); + + this.setState({ + items: data, + showAddModal: false, + urlError: '', + iconError: '', + }); + + variables.stats.postEvent('feature', 'Quicklink add'); + } + + startEditLink(data) { + this.setState({ + edit: true, + editData: data, + showAddModal: true, + }); + } + + async editLink(og, name, url, icon) { + const data = JSON.parse(localStorage.getItem('quicklinks')); + const dataobj = data.find((i) => i.key === og.key); + dataobj.name = name || (await getTitleFromUrl(url)); + dataobj.url = url; + dataobj.icon = icon || ''; + + localStorage.setItem('quicklinks', JSON.stringify(data)); + + this.setState({ + items: data, + showAddModal: false, + edit: false, + }); + } + + componentDidMount() { + EventBus.on('refresh', (data) => { + if (data === 'quicklinks') { + if (localStorage.getItem('quicklinksenabled') === 'false') { + return (this.quicklinksContainer.current.style.display = 'none'); + } + + this.quicklinksContainer.current.style.display = 'block'; + + this.setState({ + items: JSON.parse(localStorage.getItem('quicklinks')), + }); + } + }); + } + + componentWillUnmount() { + EventBus.off('refresh'); + } + + render() { + const QUICKLINKS_SECTION = 'modals.main.settings.sections.quicklinks'; + + const AdditionalSettings = () => { + return ( + + + + + + + + ); + }; + + const StylingOptions = () => { + return ( + + + + + + + ); + }; + + const AddLink = () => { + return ( + + + +
+ + )} + + +
+ {this.state.items.map((item, i) => ( + this.startEditLink(item)} + deleteLink={(key, e) => this.deleteLink(key, e)} + /> + ))} +
+ this.setState({ showAddModal: false, urlError: '', iconError: '' })} + isOpen={this.state.showAddModal} + className="Modal resetmodal mainModal" + overlayClassName="Overlay resetoverlay" + ariaHideApp={false} + > + this.addLink(name, url, icon)} + editLink={(og, name, url, icon) => this.editLink(og, name, url, icon)} + edit={this.state.edit} + editData={this.state.editData} + closeModal={() => + this.setState({ showAddModal: false, urlError: '', iconError: '', edit: false }) + } + /> + + + ); + } +} + +export { QuickLinksOptions as default, QuickLinksOptions }; \ No newline at end of file diff --git a/src/features/widgets/quicklinks/options/index.jsx b/src/features/widgets/quicklinks/options/index.jsx new file mode 100644 index 00000000..3a1a800a --- /dev/null +++ b/src/features/widgets/quicklinks/options/index.jsx @@ -0,0 +1 @@ +export * from './QuickLinksOptions'; \ No newline at end of file diff --git a/src/features/widgets/search/index.jsx b/src/features/widgets/search/index.jsx new file mode 100644 index 00000000..ca5d4651 --- /dev/null +++ b/src/features/widgets/search/index.jsx @@ -0,0 +1,2 @@ +export * from './options'; +export * from './Search'; \ No newline at end of file diff --git a/src/features/widgets/search/options/SearchOptions.jsx b/src/features/widgets/search/options/SearchOptions.jsx new file mode 100644 index 00000000..bb13527c --- /dev/null +++ b/src/features/widgets/search/options/SearchOptions.jsx @@ -0,0 +1,174 @@ +import variables from 'config/variables'; +import { PureComponent } from 'react'; +import { toast } from 'react-toastify'; +import { MenuItem, TextField } from '@mui/material'; + +import { Header, Row, Content, Action, PreferencesWrapper } from 'components/Layout/Settings'; +import { Dropdown, Checkbox } from 'components/Form/Settings'; + +import EventBus from 'utils/eventbus'; + +import searchEngines from 'features/widgets/search/search_engines.json'; + +class SearchOptions extends PureComponent { + constructor() { + super(); + this.state = { + customEnabled: false, + customValue: localStorage.getItem('customSearchEngine') || '', + }; + } + + resetSearch() { + localStorage.removeItem('customSearchEngine'); + this.setState({ + customValue: '', + }); + + toast(variables.getMessage('toasts.reset')); + } + + componentDidMount() { + if (localStorage.getItem('searchEngine') === 'custom') { + this.setState({ + customEnabled: true, + }); + } else { + localStorage.removeItem('customSearchEngine'); + } + } + + componentDidUpdate() { + if (this.state.customEnabled === true && this.state.customValue !== '') { + localStorage.setItem('customSearchEngine', this.state.customValue); + } + + EventBus.emit('refresh', 'search'); + } + + setSearchEngine(input) { + if (input === 'custom') { + this.setState({ + customEnabled: true, + }); + } else { + this.setState({ + customEnabled: false, + }); + localStorage.setItem('searchEngine', input); + } + + EventBus.emit('refresh', 'search'); + } + + render() { + const SEARCH_SECTION = 'modals.main.settings.sections.search'; + + const AdditionalOptions = () => { + return ( + + + + {/* not supported on firefox */} + {navigator.userAgent.includes('Chrome') && typeof InstallTrigger === 'undefined' ? ( + + ) : null} + + + + + + ); + }; + + const SearchEngineSelection = () => { + return ( + + + + this.setSearchEngine(value)} + items={[ + searchEngines.map((engine) => ({ + value: engine.settingsName, + text: engine.name, + })), + { + value: 'custom', + text: variables.getMessage(`${SEARCH_SECTION}.custom`), + }, + ]} + /> + + + ); + }; + + const CustomOptions = () => { + return ( + + + + this.setState({ customValue: e.target.value })} + varient="outlined" + InputLabelProps={{ shrink: true }} + /> +

+ this.resetSearch()}> + {variables.getMessage('modals.main.settings.buttons.reset')} + +

+
+
+ ); + }; + + return ( + <> +
+ + + + {this.state.customEnabled && CustomOptions()} + + + ); + } +} + +export { SearchOptions as default, SearchOptions }; \ No newline at end of file diff --git a/src/features/widgets/search/options/index.jsx b/src/features/widgets/search/options/index.jsx new file mode 100644 index 00000000..5abc490f --- /dev/null +++ b/src/features/widgets/search/options/index.jsx @@ -0,0 +1 @@ +export * from './SearchOptions'; \ No newline at end of file diff --git a/src/features/widgets/weather/Weather.jsx b/src/features/widgets/weather/Weather.jsx index f38278ea..5b11348f 100644 --- a/src/features/widgets/weather/Weather.jsx +++ b/src/features/widgets/weather/Weather.jsx @@ -10,7 +10,7 @@ import { getWeather } from './api/WeatherAPI.js'; import './weather.scss'; -export default class WeatherSettings extends PureComponent { +class WeatherWidget extends PureComponent { constructor() { super(); this.state = { @@ -84,3 +84,5 @@ export default class WeatherSettings extends PureComponent { ); } } + +export { WeatherWidget as default, WeatherWidget }; diff --git a/src/features/widgets/weather/index.jsx b/src/features/widgets/weather/index.jsx new file mode 100644 index 00000000..cf6f77a5 --- /dev/null +++ b/src/features/widgets/weather/index.jsx @@ -0,0 +1,2 @@ +export * from './options'; +export * from './Weather'; \ No newline at end of file diff --git a/src/features/modals/main/settings/sections/Weather.jsx b/src/features/widgets/weather/options/WeatherOptions.jsx similarity index 98% rename from src/features/modals/main/settings/sections/Weather.jsx rename to src/features/widgets/weather/options/WeatherOptions.jsx index 951b9bd8..b4d13829 100644 --- a/src/features/modals/main/settings/sections/Weather.jsx +++ b/src/features/widgets/weather/options/WeatherOptions.jsx @@ -7,7 +7,7 @@ import { Header, Row, Content, Action, PreferencesWrapper } from 'components/Lay import { Radio, Dropdown, Checkbox } from 'components/Form/Settings'; import { TextField } from '@mui/material'; -export default class WeatherSettings extends PureComponent { +class WeatherOptions extends PureComponent { constructor() { super(); this.state = { @@ -220,3 +220,5 @@ export default class WeatherSettings extends PureComponent { ); } } + +export { WeatherOptions as default, WeatherOptions }; \ No newline at end of file diff --git a/src/features/widgets/weather/options/index.jsx b/src/features/widgets/weather/options/index.jsx new file mode 100644 index 00000000..75c185e1 --- /dev/null +++ b/src/features/widgets/weather/options/index.jsx @@ -0,0 +1 @@ +export * from './WeatherOptions'; \ No newline at end of file diff --git a/vite.config.mjs.timestamp-1708789619302-8ea1d206b4f95.mjs b/vite.config.mjs.timestamp-1708789619302-8ea1d206b4f95.mjs new file mode 100644 index 00000000..dc1b340a --- /dev/null +++ b/vite.config.mjs.timestamp-1708789619302-8ea1d206b4f95.mjs @@ -0,0 +1,110 @@ +// vite.config.mjs +import { defineConfig, loadEnv } from "file:///F:/Programming/mue/node_modules/.pnpm/vite@5.1.3_@types+node@20.11.19_sass@1.71.0/node_modules/vite/dist/node/index.js"; +import react from "file:///F:/Programming/mue/node_modules/.pnpm/@vitejs+plugin-react-swc@3.6.0_vite@5.1.3/node_modules/@vitejs/plugin-react-swc/index.mjs"; +import path from "path"; +import fs from "fs"; +import ADMZip from "file:///F:/Programming/mue/node_modules/.pnpm/adm-zip@0.5.10/node_modules/adm-zip/adm-zip.js"; + +// package.json +var version = "7.0.1"; + +// vite.config.mjs +import progress from "file:///F:/Programming/mue/node_modules/.pnpm/vite-plugin-progress@0.0.7_vite@5.1.3/node_modules/vite-plugin-progress/dist/index.mjs"; +var __vite_injected_original_dirname = "F:\\Programming\\mue"; +var isProd = process.env.NODE_ENV === "production"; +var prepareBuilds = () => ({ + name: "prepareBuilds", + buildEnd() { + if (isProd) { + fs.mkdirSync(path.resolve(__vite_injected_original_dirname, "./build"), { recursive: true }); + fs.mkdirSync(path.resolve(__vite_injected_original_dirname, "./dist"), { recursive: true }); + fs.mkdirSync(path.resolve(__vite_injected_original_dirname, "./build/chrome"), { recursive: true }); + fs.copyFileSync( + path.resolve(__vite_injected_original_dirname, "./manifest/chrome.json"), + path.resolve(__vite_injected_original_dirname, "./build/chrome/manifest.json") + ); + fs.copyFileSync( + path.resolve(__vite_injected_original_dirname, "./manifest/background-chrome.js"), + path.resolve(__vite_injected_original_dirname, "./build/chrome/background.js") + ); + fs.cpSync( + path.resolve(__vite_injected_original_dirname, "./manifest/_locales"), + path.resolve(__vite_injected_original_dirname, "./build/chrome/_locales"), + { + recursive: true + } + ); + fs.cpSync(path.resolve(__vite_injected_original_dirname, "./dist"), path.resolve(__vite_injected_original_dirname, "./build/chrome/"), { + recursive: true + }); + fs.mkdirSync(path.resolve(__vite_injected_original_dirname, "./build/firefox"), { recursive: true }); + fs.copyFileSync( + path.resolve(__vite_injected_original_dirname, "./manifest/firefox.json"), + path.resolve(__vite_injected_original_dirname, "./build/firefox/manifest.json") + ); + fs.copyFileSync( + path.resolve(__vite_injected_original_dirname, "./manifest/background-firefox.js"), + path.resolve(__vite_injected_original_dirname, "./build/firefox/background.js") + ); + fs.cpSync(path.resolve(__vite_injected_original_dirname, "./dist"), path.resolve(__vite_injected_original_dirname, "./build/firefox/"), { + recursive: true + }); + const zip = new ADMZip(); + zip.addLocalFolder(path.resolve(__vite_injected_original_dirname, "./build/chrome")); + zip.writeZip(path.resolve(__vite_injected_original_dirname, `./build/chrome-${version}.zip`)); + const zip2 = new ADMZip(); + zip2.addLocalFolder(path.resolve(__vite_injected_original_dirname, "./build/firefox")); + zip2.writeZip(path.resolve(__vite_injected_original_dirname, `./build/firefox-${version}.zip`)); + } + } +}); +var vite_config_default = defineConfig(({ command, mode }) => { + const env = loadEnv(mode, process.cwd(), ""); + return { + define: { + __APP_ENV__: JSON.stringify(env.APP_ENV) + }, + plugins: [react(), prepareBuilds(), progress()], + server: { + open: true, + hmr: { + protocol: "ws", + host: "localhost" + } + }, + build: { + minify: isProd ? "esbuild" : false, + sourcemap: !isProd, + rollupOptions: { + output: { + manualChunks(id) { + if (id.includes("node_modules")) { + if (id.includes("@mui")) { + return "vendor_mui"; + } + return "vendor"; + } + } + } + } + }, + resolve: { + extensions: [".js", ".jsx"], + alias: { + "@": path.resolve(__vite_injected_original_dirname, "./src"), + i18n: path.resolve(__vite_injected_original_dirname, "./src/i18n"), + components: path.resolve(__vite_injected_original_dirname, "./src/components"), + config: path.resolve(__vite_injected_original_dirname, "./src/config"), + features: path.resolve(__vite_injected_original_dirname, "./src/features"), + lib: path.resolve(__vite_injected_original_dirname, "./src/lib"), + scss: path.resolve(__vite_injected_original_dirname, "./src/scss"), + translations: path.resolve(__vite_injected_original_dirname, "./src/i18n/locales"), + utils: path.resolve(__vite_injected_original_dirname, "./src/utils") + } + } + }; +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcubWpzIiwgInBhY2thZ2UuanNvbiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIkY6XFxcXFByb2dyYW1taW5nXFxcXG11ZVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRjpcXFxcUHJvZ3JhbW1pbmdcXFxcbXVlXFxcXHZpdGUuY29uZmlnLm1qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRjovUHJvZ3JhbW1pbmcvbXVlL3ZpdGUuY29uZmlnLm1qc1wiO2ltcG9ydCB7IGRlZmluZUNvbmZpZywgbG9hZEVudiB9IGZyb20gJ3ZpdGUnO1xyXG5pbXBvcnQgcmVhY3QgZnJvbSAnQHZpdGVqcy9wbHVnaW4tcmVhY3Qtc3djJztcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XHJcbmltcG9ydCBmcyBmcm9tICdmcyc7XHJcbmltcG9ydCBBRE1aaXAgZnJvbSAnYWRtLXppcCc7XHJcbmltcG9ydCAqIGFzIHBrZyBmcm9tICcuL3BhY2thZ2UuanNvbic7XHJcbmltcG9ydCBwcm9ncmVzcyBmcm9tICd2aXRlLXBsdWdpbi1wcm9ncmVzcyc7XHJcblxyXG5jb25zdCBpc1Byb2QgPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nO1xyXG5cclxuY29uc3QgcHJlcGFyZUJ1aWxkcyA9ICgpID0+ICh7XHJcbiAgbmFtZTogJ3ByZXBhcmVCdWlsZHMnLFxyXG4gIGJ1aWxkRW5kKCkge1xyXG4gICAgaWYgKGlzUHJvZCkge1xyXG4gICAgICAvLyBtYWtlIGRpcmVjdG9yaWVzIGlmIG5vdCBleGlzdFxyXG4gICAgICBmcy5ta2RpclN5bmMocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vYnVpbGQnKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XHJcbiAgICAgIGZzLm1rZGlyU3luYyhwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9kaXN0JyksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xyXG5cclxuICAgICAgLy8gY2hyb21lXHJcbiAgICAgIGZzLm1rZGlyU3luYyhwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9idWlsZC9jaHJvbWUnKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XHJcbiAgICAgIGZzLmNvcHlGaWxlU3luYyhcclxuICAgICAgICBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9tYW5pZmVzdC9jaHJvbWUuanNvbicpLFxyXG4gICAgICAgIHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2J1aWxkL2Nocm9tZS9tYW5pZmVzdC5qc29uJyksXHJcbiAgICAgICk7XHJcbiAgICAgIGZzLmNvcHlGaWxlU3luYyhcclxuICAgICAgICBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9tYW5pZmVzdC9iYWNrZ3JvdW5kLWNocm9tZS5qcycpLFxyXG4gICAgICAgIHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2J1aWxkL2Nocm9tZS9iYWNrZ3JvdW5kLmpzJyksXHJcbiAgICAgICk7XHJcbiAgICAgIGZzLmNwU3luYyhcclxuICAgICAgICBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9tYW5pZmVzdC9fbG9jYWxlcycpLFxyXG4gICAgICAgIHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2J1aWxkL2Nocm9tZS9fbG9jYWxlcycpLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHJlY3Vyc2l2ZTogdHJ1ZSxcclxuICAgICAgICB9LFxyXG4gICAgICApO1xyXG4gICAgICBmcy5jcFN5bmMocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vZGlzdCcpLCBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9idWlsZC9jaHJvbWUvJyksIHtcclxuICAgICAgICByZWN1cnNpdmU6IHRydWUsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gZmlyZWZveFxyXG4gICAgICBmcy5ta2RpclN5bmMocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vYnVpbGQvZmlyZWZveCcpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcclxuICAgICAgZnMuY29weUZpbGVTeW5jKFxyXG4gICAgICAgIHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL21hbmlmZXN0L2ZpcmVmb3guanNvbicpLFxyXG4gICAgICAgIHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2J1aWxkL2ZpcmVmb3gvbWFuaWZlc3QuanNvbicpLFxyXG4gICAgICApO1xyXG4gICAgICBmcy5jb3B5RmlsZVN5bmMoXHJcbiAgICAgICAgcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vbWFuaWZlc3QvYmFja2dyb3VuZC1maXJlZm94LmpzJyksXHJcbiAgICAgICAgcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vYnVpbGQvZmlyZWZveC9iYWNrZ3JvdW5kLmpzJyksXHJcbiAgICAgICk7XHJcbiAgICAgIGZzLmNwU3luYyhwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9kaXN0JyksIHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2J1aWxkL2ZpcmVmb3gvJyksIHtcclxuICAgICAgICByZWN1cnNpdmU6IHRydWUsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gY3JlYXRlIHppcFxyXG4gICAgICBjb25zdCB6aXAgPSBuZXcgQURNWmlwKCk7XHJcbiAgICAgIHppcC5hZGRMb2NhbEZvbGRlcihwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9idWlsZC9jaHJvbWUnKSk7XHJcbiAgICAgIHppcC53cml0ZVppcChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBgLi9idWlsZC9jaHJvbWUtJHtwa2cudmVyc2lvbn0uemlwYCkpO1xyXG5cclxuICAgICAgY29uc3QgemlwMiA9IG5ldyBBRE1aaXAoKTtcclxuICAgICAgemlwMi5hZGRMb2NhbEZvbGRlcihwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9idWlsZC9maXJlZm94JykpO1xyXG4gICAgICB6aXAyLndyaXRlWmlwKHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIGAuL2J1aWxkL2ZpcmVmb3gtJHtwa2cudmVyc2lvbn0uemlwYCkpO1xyXG4gICAgfVxyXG4gIH0sXHJcbn0pO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKCh7IGNvbW1hbmQsIG1vZGUgfSkgPT4ge1xyXG4gIGNvbnN0IGVudiA9IGxvYWRFbnYobW9kZSwgcHJvY2Vzcy5jd2QoKSwgJycpO1xyXG4gIHJldHVybiB7XHJcbiAgICBkZWZpbmU6IHtcclxuICAgICAgX19BUFBfRU5WX186IEpTT04uc3RyaW5naWZ5KGVudi5BUFBfRU5WKSxcclxuICAgIH0sXHJcbiAgICBwbHVnaW5zOiBbcmVhY3QoKSwgcHJlcGFyZUJ1aWxkcygpLCBwcm9ncmVzcygpXSxcclxuICAgIHNlcnZlcjoge1xyXG4gICAgICBvcGVuOiB0cnVlLFxyXG4gICAgICBobXI6IHtcclxuICAgICAgICBwcm90b2NvbDogJ3dzJyxcclxuICAgICAgICBob3N0OiAnbG9jYWxob3N0JyxcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgICBidWlsZDoge1xyXG4gICAgICBtaW5pZnk6IGlzUHJvZCA/ICdlc2J1aWxkJyA6IGZhbHNlLFxyXG4gICAgICBzb3VyY2VtYXA6ICFpc1Byb2QsXHJcbiAgICAgIHJvbGx1cE9wdGlvbnM6IHtcclxuICAgICAgICBvdXRwdXQ6IHtcclxuICAgICAgICAgIG1hbnVhbENodW5rcyhpZCkge1xyXG4gICAgICAgICAgICBpZiAoaWQuaW5jbHVkZXMoJ25vZGVfbW9kdWxlcycpKSB7XHJcbiAgICAgICAgICAgICAgaWYgKGlkLmluY2x1ZGVzKCdAbXVpJykpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAndmVuZG9yX211aSc7XHJcbiAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICByZXR1cm4gJ3ZlbmRvcic7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgICByZXNvbHZlOiB7XHJcbiAgICAgIGV4dGVuc2lvbnM6IFsnLmpzJywgJy5qc3gnXSxcclxuICAgICAgYWxpYXM6IHtcclxuICAgICAgICAnQCc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYycpLFxyXG4gICAgICAgIGkxOG46IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9pMThuJyksXHJcbiAgICAgICAgY29tcG9uZW50czogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vc3JjL2NvbXBvbmVudHMnKSxcclxuICAgICAgICBjb25maWc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9jb25maWcnKSxcclxuICAgICAgICBmZWF0dXJlczogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vc3JjL2ZlYXR1cmVzJyksXHJcbiAgICAgICAgbGliOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9zcmMvbGliJyksXHJcbiAgICAgICAgc2NzczogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vc3JjL3Njc3MnKSxcclxuICAgICAgICB0cmFuc2xhdGlvbnM6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYy9pMThuL2xvY2FsZXMnKSxcclxuICAgICAgICB1dGlsczogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4vc3JjL3V0aWxzJyksXHJcbiAgICAgIH0sXHJcbiAgICB9LFxyXG4gIH07XHJcbn0pO1xyXG4iLCAie1xyXG4gIFwibmFtZVwiOiBcIm11ZVwiLFxyXG4gIFwicHJpdmF0ZVwiOiB0cnVlLFxyXG4gIFwiYXV0aG9yXCI6IFwiVGhlIE11ZSBBdXRob3JzIChodHRwczovL2dpdGh1Yi5jb20vbXVlL211ZS9ncmFwaHMvY29udHJpYnV0b3JzKVwiLFxyXG4gIFwiZGVzY3JpcHRpb25cIjogXCJGYXN0LCBvcGVuIGFuZCBmcmVlLXRvLXVzZSBuZXcgdGFiIHBhZ2UgZm9yIG1vZGVybiBicm93c2Vycy5cIixcclxuICBcInJlcG9zaXRvcnlcIjoge1xyXG4gICAgXCJ1cmxcIjogXCJnaXRodWI6bXVlL211ZVwiXHJcbiAgfSxcclxuICBcImhvbWVwYWdlXCI6IFwiaHR0cHM6Ly9tdWV0YWIuY29tXCIsXHJcbiAgXCJidWdzXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL211ZS9tdWUvaXNzdWVzL25ldz9hc3NpZ25lZXM9JmxhYmVscz1idWcmdGVtcGxhdGU9YnVnLXJlcG9ydC5tZCZ0aXRsZT0lNUJCVUclNURcIixcclxuICBcImxpY2Vuc2VcIjogXCJCU0QtMy1DbGF1c2VcIixcclxuICBcInZlcnNpb25cIjogXCI3LjAuMVwiLFxyXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHtcclxuICAgIFwiQGVhcnRoYXJvaWQvaTE4blwiOiBcIjEuMi4xXCIsXHJcbiAgICBcIkBlbW90aW9uL3JlYWN0XCI6IFwiXjExLjExLjNcIixcclxuICAgIFwiQGVtb3Rpb24vc3R5bGVkXCI6IFwiXjExLjExLjBcIixcclxuICAgIFwiQGZsb2F0aW5nLXVpL3JlYWN0LWRvbVwiOiBcIjIuMC44XCIsXHJcbiAgICBcIkBmb250c291cmNlL2xleGVuZC1kZWNhXCI6IFwiNS4wLjhcIixcclxuICAgIFwiQGZvbnRzb3VyY2UvbW9udHNlcnJhdFwiOiBcIjUuMC4xNlwiLFxyXG4gICAgXCJAbXVldGFiL3JlYWN0LWNvbG9yLWdyYWRpZW50LXBpY2tlclwiOiBcIjAuMS4yXCIsXHJcbiAgICBcIkBtdWV0YWIvcmVhY3Qtc29ydGFibGUtaG9jXCI6IFwiXjIuMC4xXCIsXHJcbiAgICBcIkBtdWkvbWF0ZXJpYWxcIjogXCI1LjE1LjEwXCIsXHJcbiAgICBcIkBzZW50cnkvcmVhY3RcIjogXCJeNy4xMDEuMVwiLFxyXG4gICAgXCJlbWJsYS1jYXJvdXNlbC1hdXRvcGxheVwiOiBcIjguMC4wLXJjMjNcIixcclxuICAgIFwiZW1ibGEtY2Fyb3VzZWwtcmVhY3RcIjogXCI4LjAuMC1yYzIzXCIsXHJcbiAgICBcImZhc3QtYmx1cmhhc2hcIjogXCJeMS4xLjJcIixcclxuICAgIFwiaW1hZ2UtY29udmVyc2lvblwiOiBcIl4yLjEuMVwiLFxyXG4gICAgXCJyZWFjdFwiOiBcIl4xOC4yLjBcIixcclxuICAgIFwicmVhY3QtY2xvY2tcIjogXCI0LjYuMFwiLFxyXG4gICAgXCJyZWFjdC1kb21cIjogXCJeMTguMi4wXCIsXHJcbiAgICBcInJlYWN0LWljb25zXCI6IFwiXjUuMC4xXCIsXHJcbiAgICBcInJlYWN0LW1vZGFsXCI6IFwiMy4xNi4xXCIsXHJcbiAgICBcInJlYWN0LXRvYXN0aWZ5XCI6IFwiMTAuMC40XCJcclxuICB9LFxyXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcclxuICAgIFwiQGNvbW1pdGxpbnQvY2xpXCI6IFwiXjE4LjYuMVwiLFxyXG4gICAgXCJAY29tbWl0bGludC9jb25maWctY29udmVudGlvbmFsXCI6IFwiXjE4LjYuMlwiLFxyXG4gICAgXCJAZWFydGhhcm9pZC9kZWVwLW1lcmdlXCI6IFwiXjAuMC4yXCIsXHJcbiAgICBcIkB2aXRlanMvcGx1Z2luLXJlYWN0LXN3Y1wiOiBcIl4zLjYuMFwiLFxyXG4gICAgXCJhZG0temlwXCI6IFwiXjAuNS4xMFwiLFxyXG4gICAgXCJlc2xpbnRcIjogXCJeOC41Ni4wXCIsXHJcbiAgICBcImVzbGludC1jb25maWctcHJldHRpZXJcIjogXCJeOS4xLjBcIixcclxuICAgIFwiZXNsaW50LWNvbmZpZy1yZWFjdC1hcHBcIjogXCJeNy4wLjFcIixcclxuICAgIFwiaHVza3lcIjogXCJeOS4wLjExXCIsXHJcbiAgICBcInByZXR0aWVyXCI6IFwiXjMuMi41XCIsXHJcbiAgICBcInNhc3NcIjogXCJeMS43MS4wXCIsXHJcbiAgICBcInN0eWxlbGludFwiOiBcIl4xNi4yLjFcIixcclxuICAgIFwic3R5bGVsaW50LWNvbmZpZy1zdGFuZGFyZC1zY3NzXCI6IFwiXjEzLjAuMFwiLFxyXG4gICAgXCJzdHlsZWxpbnQtc2Nzc1wiOiBcIl42LjEuMFwiLFxyXG4gICAgXCJ2aXRlXCI6IFwiNS4xLjNcIixcclxuICAgIFwidml0ZS1wbHVnaW4tcHJvZ3Jlc3NcIjogXCJeMC4wLjdcIlxyXG4gIH0sXHJcbiAgXCJzY3JpcHRzXCI6IHtcclxuICAgIFwiZGV2XCI6IFwidml0ZVwiLFxyXG4gICAgXCJkZXY6aG9zdFwiOiBcInZpdGUgLS1ob3N0XCIsXHJcbiAgICBcInRyYW5zbGF0aW9uc1wiOiBcImNkIHNjcmlwdHMgJiYgbm9kZSB1cGRhdGV0cmFuc2xhdGlvbnMuanNcIixcclxuICAgIFwiYnVpbGRcIjogXCJ2aXRlIGJ1aWxkXCIsXHJcbiAgICBcInByZXR0eVwiOiBcInByZXR0aWVyIC0td3JpdGUgXFxcIi4vKiovKi57anMsanN4LGpzb24sc2Nzcyxjc3N9XFxcIlwiLFxyXG4gICAgXCJsaW50XCI6IFwiZXNsaW50IFxcXCIuL3NyYy8qKi8qLntqcyxqc3h9XFxcIiAmJiBzdHlsZWxpbnQgXFxcIi4vc3JjLyoqLyoue3Njc3MsY3NzfVxcXCJcIixcclxuICAgIFwibGludDpmaXhcIjogXCJlc2xpbnQgXFxcIi4vc3JjLyoqLyoue2pzLGpzeH1cXFwiIC0tZml4ICYmIHN0eWxlbGludCBcXFwiLi9zcmMvKiovKi57c2Nzcyxjc3N9XFxcIiAtLWZpeFwiLFxyXG4gICAgXCJwb3N0aW5zdGFsbFwiOiBcImh1c2t5IGluc3RhbGxcIlxyXG4gIH1cclxufVxyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQWdQLFNBQVMsY0FBYyxlQUFlO0FBQ3RSLE9BQU8sV0FBVztBQUNsQixPQUFPLFVBQVU7QUFDakIsT0FBTyxRQUFRO0FBQ2YsT0FBTyxZQUFZOzs7QUNPakIsY0FBVzs7O0FETGIsT0FBTyxjQUFjO0FBTnJCLElBQU0sbUNBQW1DO0FBUXpDLElBQU0sU0FBUyxRQUFRLElBQUksYUFBYTtBQUV4QyxJQUFNLGdCQUFnQixPQUFPO0FBQUEsRUFDM0IsTUFBTTtBQUFBLEVBQ04sV0FBVztBQUNULFFBQUksUUFBUTtBQUVWLFNBQUcsVUFB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