From 2d869ec6facdf278c4336358c6e198a001ddca73 Mon Sep 17 00:00:00 2001 From: Aaron Klinker Date: Mon, 19 Aug 2024 23:15:01 -0500 Subject: [PATCH 01/23] Add placeholder redirects for all pages that are changing --- docs/public/_redirects | 67 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/public/_redirects b/docs/public/_redirects index efd947624..2ba0d9650 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -34,3 +34,70 @@ # 0.19.0 /guide/go-further/entrypoint-side-effects.html /guide/go-further/entrypoint-loaders.html + +# https://github.com/wxt-dev/wxt/issues/704 +# Generated via `find docs/.vitepress/dist -type f -name "*.html"` +/guide/i18n/build-integrations.html /TODO +/guide/i18n/introduction.html /TODO +/guide/i18n/messages-file-format.html /TODO +/guide/i18n/editor-support.html /TODO +/guide/i18n/installation.html /TODO +/guide/key-concepts/content-script-ui.html /TODO +/guide/key-concepts/manifest.html /TODO +/guide/key-concepts/wxt-submit.html /TODO +/guide/key-concepts/auto-imports.html /TODO +/guide/key-concepts/web-extension-polyfill.html /TODO +/guide/key-concepts/frontend-frameworks.html /TODO +/guide/key-concepts/multiple-browsers.html /TODO +/guide/go-further/entrypoint-loaders.html /TODO +/guide/go-further/es-modules.html /TODO +/guide/go-further/handling-updates.html /TODO +/guide/go-further/custom-events.html /TODO +/guide/go-further/debugging.html /TODO +/guide/go-further/remote-code.html /TODO +/guide/go-further/vite.html /TODO +/guide/go-further/testing.html /TODO +/guide/go-further/how-wxt-works.html /TODO +/guide/go-further/reusable-modules.html /TODO +/guide/extension-apis/messaging.html /TODO +/guide/extension-apis/i18n.html /TODO +/guide/extension-apis/storage.html /TODO +/guide/extension-apis/scripting.html /TODO +/guide/extension-apis/others.html /TODO +/guide/upgrade-guide/wxt.html /TODO +/guide/directory-structure/components.html /TODO +/guide/directory-structure/hooks.html /TODO +/guide/directory-structure/assets.html /TODO +/guide/directory-structure/package.html /TODO +/guide/directory-structure/env.html /TODO +/guide/directory-structure/wxt-config.html /TODO +/guide/directory-structure/wxt.html /TODO +/guide/directory-structure/public/locales.html /TODO +/guide/directory-structure/public/index.html /TODO +/guide/directory-structure/entrypoints/devtools.html /TODO +/guide/directory-structure/entrypoints/sidepanel.html /TODO +/guide/directory-structure/entrypoints/content-scripts.html /TODO +/guide/directory-structure/entrypoints/newtab.html /TODO +/guide/directory-structure/entrypoints/bookmarks.html /TODO +/guide/directory-structure/entrypoints/unlisted-pages.html /TODO +/guide/directory-structure/entrypoints/unlisted-scripts.html /TODO +/guide/directory-structure/entrypoints/options.html /TODO +/guide/directory-structure/entrypoints/background.html /TODO +/guide/directory-structure/entrypoints/popup.html /TODO +/guide/directory-structure/entrypoints/history.html /TODO +/guide/directory-structure/entrypoints/sandbox.html /TODO +/guide/directory-structure/entrypoints/css.html /TODO +/guide/directory-structure/web-ext-config.html /TODO +/guide/directory-structure/tsconfig.html /TODO +/guide/directory-structure/utils.html /TODO +/guide/directory-structure/app-config.html /TODO +/guide/directory-structure/composables.html /TODO +/guide/directory-structure/output.html /TODO +/get-started/assets.html /TODO +/get-started/introduction.html /TODO +/get-started/configuration.html /TODO +/get-started/publishing.html /TODO +/get-started/migrate-to-wxt.html /TODO +/get-started/compare.html /TODO +/get-started/entrypoints.html /TODO +/get-started/installation.html /TODO From 2b94887dcf6eda37cdf1ab26fe9104b37b92ac92 Mon Sep 17 00:00:00 2001 From: Aaron Klinker Date: Mon, 19 Aug 2024 23:16:22 -0500 Subject: [PATCH 02/23] Move files around, write missing docs --- docs/.old/development.md | 116 ---- .../components/EntrypointPatterns.vue | 6 +- docs/.vitepress/config.ts | 168 +++--- docs/.vitepress/theme/custom.css | 8 +- docs/.vitepress/utils/menus.ts | 45 +- .../entrypoints/unlisted-pages.md | 0 .../entrypoints/unlisted-scripts.md | 0 docs/auto-icons.md | 1 + docs/get-started/assets.md | 33 -- docs/get-started/compare.md | 47 -- docs/get-started/configuration.md | 57 -- docs/get-started/entrypoints.md | 60 -- docs/get-started/installation.md | 116 ---- docs/get-started/introduction.md | 47 -- docs/guide/directory-structure/app-config.md | 61 -- docs/guide/directory-structure/assets.md | 42 -- docs/guide/directory-structure/components.md | 5 - docs/guide/directory-structure/composables.md | 5 - .../entrypoints/background.md | 47 -- .../entrypoints/bookmarks.md | 31 - .../entrypoints/content-scripts.md | 107 ---- .../directory-structure/entrypoints/css.md | 44 -- .../entrypoints/devtools.md | 40 -- .../entrypoints/history.md | 31 - .../directory-structure/entrypoints/newtab.md | 31 - .../entrypoints/options.md | 36 -- .../directory-structure/entrypoints/popup.md | 43 -- .../entrypoints/sandbox.md | 37 -- .../entrypoints/sidepanel.md | 49 -- docs/guide/directory-structure/env.md | 5 - docs/guide/directory-structure/hooks.md | 5 - docs/guide/directory-structure/output.md | 5 - docs/guide/directory-structure/package.md | 5 - .../guide/directory-structure/public/index.md | 35 -- .../directory-structure/public/locales.md | 5 - docs/guide/directory-structure/tsconfig.md | 5 - docs/guide/directory-structure/utils.md | 5 - .../directory-structure/web-ext-config.md | 65 --- docs/guide/directory-structure/wxt-config.md | 5 - docs/guide/directory-structure/wxt.md | 5 - docs/guide/essentials/assets.md | 80 +++ .../essentials/config/browser-startup.md | 68 +++ docs/guide/essentials/config/manifest.md | 255 +++++++++ docs/guide/essentials/config/runtime.md | 79 +++ docs/guide/essentials/config/typescript.md | 40 ++ docs/guide/essentials/config/vite.md | 82 +++ docs/guide/essentials/config/wxt.md | 172 ++++++ .../content-scripts.md} | 230 +++++++- docs/guide/essentials/e2e-testing.md | 9 + docs/guide/essentials/entrypoints.md | 532 ++++++++++++++++++ docs/guide/essentials/extension-apis.md | 92 +++ .../frontend-frameworks.md | 41 +- docs/guide/essentials/i18n.md | 78 +++ docs/guide/essentials/messaging.md | 16 + docs/guide/essentials/project-structure.md | 50 ++ .../essentials}/publishing.md | 32 +- .../{go-further => essentials}/remote-code.md | 0 .../scripting.md | 8 +- docs/guide/essentials/storage.md | 15 + .../essentials/target-different-browsers.md | 69 +++ docs/guide/essentials/testing-updates.md | 27 + docs/guide/essentials/unit-testing.md | 80 +++ docs/guide/essentials/wxt-modules.md | 242 ++++++++ docs/guide/extension-apis/i18n.md | 56 -- docs/guide/extension-apis/messaging.md | 36 -- docs/guide/extension-apis/others.md | 5 - docs/guide/get-started/installation.md | 119 ++++ docs/guide/get-started/introduction.md | 26 + docs/guide/go-further/custom-events.md | 5 - docs/guide/go-further/debugging.md | 5 - docs/guide/go-further/entrypoint-loaders.md | 120 ---- docs/guide/go-further/es-modules.md | 40 -- docs/guide/go-further/handling-updates.md | 76 --- docs/guide/go-further/reusable-modules.md | 186 ------ docs/guide/go-further/testing.md | 27 - docs/guide/go-further/vite.md | 39 -- docs/guide/i18n/build-integrations.md | 82 --- docs/guide/i18n/editor-support.md | 48 -- docs/guide/i18n/installation.md | 81 --- docs/guide/i18n/introduction.md | 22 - docs/guide/i18n/messages-file-format.md | 170 ------ docs/guide/key-concepts/auto-imports.md | 117 ---- docs/guide/key-concepts/manifest.md | 249 -------- docs/guide/key-concepts/multiple-browsers.md | 133 ----- .../key-concepts/web-extension-polyfill.md | 108 ---- docs/guide/key-concepts/wxt-submit.md | 9 - docs/guide/resources/compare.md | 53 ++ docs/guide/resources/faq.md | 19 + .../how-wxt-works.md | 0 .../resources/migrate.md} | 38 +- .../wxt.md => resources/upgrading.md} | 0 docs/i18n.md | 5 + docs/index.md | 4 +- docs/public/_redirects | 132 ++--- docs/{guide/extension-apis => }/storage.md | 27 +- packages/i18n/README.md | 367 +++++++++++- packages/wxt/src/browser/chrome.ts | 2 + .../src/client/content-scripts/ui/index.ts | 6 +- 98 files changed, 3039 insertions(+), 3128 deletions(-) delete mode 100644 docs/.old/development.md rename docs/{guide/directory-structure => api}/entrypoints/unlisted-pages.md (100%) rename docs/{guide/directory-structure => api}/entrypoints/unlisted-scripts.md (100%) create mode 100644 docs/auto-icons.md delete mode 100644 docs/get-started/assets.md delete mode 100644 docs/get-started/compare.md delete mode 100644 docs/get-started/configuration.md delete mode 100644 docs/get-started/entrypoints.md delete mode 100644 docs/get-started/installation.md delete mode 100644 docs/get-started/introduction.md delete mode 100644 docs/guide/directory-structure/app-config.md delete mode 100644 docs/guide/directory-structure/assets.md delete mode 100644 docs/guide/directory-structure/components.md delete mode 100644 docs/guide/directory-structure/composables.md delete mode 100644 docs/guide/directory-structure/entrypoints/background.md delete mode 100644 docs/guide/directory-structure/entrypoints/bookmarks.md delete mode 100644 docs/guide/directory-structure/entrypoints/content-scripts.md delete mode 100644 docs/guide/directory-structure/entrypoints/css.md delete mode 100644 docs/guide/directory-structure/entrypoints/devtools.md delete mode 100644 docs/guide/directory-structure/entrypoints/history.md delete mode 100644 docs/guide/directory-structure/entrypoints/newtab.md delete mode 100644 docs/guide/directory-structure/entrypoints/options.md delete mode 100644 docs/guide/directory-structure/entrypoints/popup.md delete mode 100644 docs/guide/directory-structure/entrypoints/sandbox.md delete mode 100644 docs/guide/directory-structure/entrypoints/sidepanel.md delete mode 100644 docs/guide/directory-structure/env.md delete mode 100644 docs/guide/directory-structure/hooks.md delete mode 100644 docs/guide/directory-structure/output.md delete mode 100644 docs/guide/directory-structure/package.md delete mode 100644 docs/guide/directory-structure/public/index.md delete mode 100644 docs/guide/directory-structure/public/locales.md delete mode 100644 docs/guide/directory-structure/tsconfig.md delete mode 100644 docs/guide/directory-structure/utils.md delete mode 100644 docs/guide/directory-structure/web-ext-config.md delete mode 100644 docs/guide/directory-structure/wxt-config.md delete mode 100644 docs/guide/directory-structure/wxt.md create mode 100644 docs/guide/essentials/assets.md create mode 100644 docs/guide/essentials/config/browser-startup.md create mode 100644 docs/guide/essentials/config/manifest.md create mode 100644 docs/guide/essentials/config/runtime.md create mode 100644 docs/guide/essentials/config/typescript.md create mode 100644 docs/guide/essentials/config/vite.md create mode 100644 docs/guide/essentials/config/wxt.md rename docs/guide/{key-concepts/content-script-ui.md => essentials/content-scripts.md} (58%) create mode 100644 docs/guide/essentials/e2e-testing.md create mode 100644 docs/guide/essentials/entrypoints.md create mode 100644 docs/guide/essentials/extension-apis.md rename docs/guide/{key-concepts => essentials}/frontend-frameworks.md (59%) create mode 100644 docs/guide/essentials/i18n.md create mode 100644 docs/guide/essentials/messaging.md create mode 100644 docs/guide/essentials/project-structure.md rename docs/{get-started => guide/essentials}/publishing.md (85%) rename docs/guide/{go-further => essentials}/remote-code.md (100%) rename docs/guide/{extension-apis => essentials}/scripting.md (70%) create mode 100644 docs/guide/essentials/storage.md create mode 100644 docs/guide/essentials/target-different-browsers.md create mode 100644 docs/guide/essentials/testing-updates.md create mode 100644 docs/guide/essentials/unit-testing.md create mode 100644 docs/guide/essentials/wxt-modules.md delete mode 100644 docs/guide/extension-apis/i18n.md delete mode 100644 docs/guide/extension-apis/messaging.md delete mode 100644 docs/guide/extension-apis/others.md create mode 100644 docs/guide/get-started/installation.md create mode 100644 docs/guide/get-started/introduction.md delete mode 100644 docs/guide/go-further/custom-events.md delete mode 100644 docs/guide/go-further/debugging.md delete mode 100644 docs/guide/go-further/entrypoint-loaders.md delete mode 100644 docs/guide/go-further/es-modules.md delete mode 100644 docs/guide/go-further/handling-updates.md delete mode 100644 docs/guide/go-further/reusable-modules.md delete mode 100644 docs/guide/go-further/testing.md delete mode 100644 docs/guide/go-further/vite.md delete mode 100644 docs/guide/i18n/build-integrations.md delete mode 100644 docs/guide/i18n/editor-support.md delete mode 100644 docs/guide/i18n/installation.md delete mode 100644 docs/guide/i18n/introduction.md delete mode 100644 docs/guide/i18n/messages-file-format.md delete mode 100644 docs/guide/key-concepts/auto-imports.md delete mode 100644 docs/guide/key-concepts/manifest.md delete mode 100644 docs/guide/key-concepts/multiple-browsers.md delete mode 100644 docs/guide/key-concepts/web-extension-polyfill.md delete mode 100644 docs/guide/key-concepts/wxt-submit.md create mode 100644 docs/guide/resources/compare.md create mode 100644 docs/guide/resources/faq.md rename docs/guide/{go-further => resources}/how-wxt-works.md (100%) rename docs/{get-started/migrate-to-wxt.md => guide/resources/migrate.md} (80%) rename docs/guide/{upgrade-guide/wxt.md => resources/upgrading.md} (100%) create mode 100644 docs/i18n.md rename docs/{guide/extension-apis => }/storage.md (96%) diff --git a/docs/.old/development.md b/docs/.old/development.md deleted file mode 100644 index 50098add9..000000000 --- a/docs/.old/development.md +++ /dev/null @@ -1,116 +0,0 @@ -# Development - -WXT's main goal is providing the best DX it possibly can. When running your extension in dev mode, each part of your extension is reloaded separately when possible. - -| | HMR | Reloaded individually | Reload extension | Restart browser | -| ------------------- | :-: | :-------------------: | :--------------: | :----------------------------------------------------: | -| HTML File | | ✅ | -| HTML Dependency | ✅ | -| MV3 Content Script | | ✅ | -| MV2 Content Script | | | ✅ | -| Background | | | ✅ | -| manifest.json | | | | 🟡 See [#16](https://github.com/wxt-dev/wxt/issues/16) | -| `wxt.config.ts` | | | | 🟡 See [#10](https://github.com/wxt-dev/wxt/issues/10) | -| `web-ext.config.ts` | | | | 🟡 See [#10](https://github.com/wxt-dev/wxt/issues/10) | - -## Dev Mode vs Production Builds - -There are some notable differences between the development and production versions of an extension. During development: - -1. **Content scripts are not listed in the `manifest.json`** when targeting MV3. Instead, the [`scripting`](https://developer.chrome.com/docs/extensions/reference/api/scripting) permission is used to register content scripts at runtime so they can be reloaded individually. - - To get the list of content scripts during development, run the following in the background's console: - - ```ts - await chrome.scripting.getRegisteredContentScripts(); - ``` - -2. **The CSP is modified to allow loading scripts from the dev server**. Make sure you're using Chrome v110 or above for HMR to work. - -3. If you don't include a background script/service worker, one will be created to perform various tasks in dev mode, mostly related to reloading different parts of the extension on change. - -For production builds, none of the above modifications will be applied, and you're extension/manifest will only include what you have defined. - -## Configure Browser Startup - -WXT uses [`web-ext` by Mozilla](https://github.com/mozilla/web-ext) to automatically open a browser with the extension installed. You can configure the runner's behavior via the [`runner`](/api/reference/wxt/interfaces/InlineConfig#runner) option, or in a separate gitignored file, `web-ext.config.ts`. - -:::code-group - -```ts [wxt.config.ts] -import { defineConfig } from 'wxt'; - -export default defineConfig({ - runner: { - // Runner config - }, -}); -``` - -```ts [web-ext.config.ts] -import { defineRunnerConfig } from 'wxt'; - -export default defineRunnerConfig({ - // Runner config -}); -``` - -::: - -### Browser Binaries - -`web-ext`'s browser discovery is very limited. By default, it only guesses at where Chrome and Firefox are installed. If you've customized your install locations, you may need to tell `web-ext` where the binaries/executables are located using the [`binaries` option](/api/reference/wxt/interfaces/ExtensionRunnerConfig#binaries). For other Chromium based browsers, like Edge or Opera, you'll need to explicitly list them in the `binaries` option as well, otherwise they will open in Chrome by default. - -```ts -// ~/web-ext.config.ts -import { defineRunnerConfig } from 'wxt'; - -export default defineRunnerConfig({ - binaries: { - chrome: '/path/to/chrome-beta', // Use Chrome Beta instead of regular Chrome - firefox: 'firefoxdeveloperedition', // Use Firefox Developer Edition instead of regular Firefox - edge: '/path/to/edge', // Open MS Edge when running "wxt -b edge" - }, -}); -``` - -:::tip -When configuring browser binaries, it's helpful to put them in `~/web-ext.config.ts` instead of the project directory's `web-ext.config.ts` file. When placed in your home directory (`~/`), this config will be used by all WXT projects, so you only need to configure the binaries once. -::: - -### Other options - -You can customize other options as well, like startup URLs, profiles, or additional command line arguments: - -```ts -// web-ext.config.ts -import { defineRunnerConfig } from 'wxt'; - -export default defineRunnerConfig({ - startUrls: ['https://google.com', 'https://duckduckgo.com'], - chromiumProfile: '/path/to/profile/to/use', - chromiumArgs: ['--window-size=400,300'], -}); -``` - -For a full list of options, see the [API Reference](/api/reference/wxt/interfaces/ExtensionRunnerConfig). - -## Reload the Extension - -Normally, to manually reload an extension, you have to visit `chrome://extensions` and click the reload button for your extension. - -When running `wxt` command to start the dev server, WXT adds a keyboard shortcut `Alt+R`, that reloads the extension when pressed, without visiting `chrome://extensions`. This can also be customized or disabled: - -```ts [wxt.config.ts] -import { defineConfig } from 'wxt'; - -export default defineConfig({ - dev: { - reloadCommand: 'Alt+T', // false, to disable - }, -}); -``` - -:::info -This shortcut is only available during development, and is not be added to your extension when running `wxt build` or `wxt-zip`. -::: diff --git a/docs/.vitepress/components/EntrypointPatterns.vue b/docs/.vitepress/components/EntrypointPatterns.vue index 0600a0660..8f73d7c28 100644 --- a/docs/.vitepress/components/EntrypointPatterns.vue +++ b/docs/.vitepress/components/EntrypointPatterns.vue @@ -8,14 +8,14 @@ const props = defineProps<{ - + - - diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 33a975369..93ba6d090 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -8,6 +8,8 @@ import { prepareTypedocSidebar, } from './utils/menus'; import { meta, script } from './utils/head'; +import { version as wxtVersion } from '../../packages/wxt/package.json'; +import { version as i18nVersion } from '../../packages/i18n/package.json'; const title = 'Next-gen Web Extension Framework'; const titleSuffix = ' – WXT'; @@ -64,92 +66,75 @@ export default defineConfig({ ], nav: [ - navItem('Get Started', '/get-started/introduction'), - navItem('Guide', '/guide/key-concepts/manifest'), - navItem('API', '/api/reference/wxt'), + navItem('Guide', '/guide/get-started/installation'), navItem('Examples', '/examples'), + navItem('API', '/api/reference/wxt'), + navItem('---', [ + navItem('wxt', [ + navItem(`v${wxtVersion}`, '/'), + navItem( + `Changelog`, + 'https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md', + ), + ]), + navItem('@wxt-dev/i18n', [ + navItem(`v${i18nVersion}`, '/i18n'), + navItem( + `Changelog`, + 'https://github.com/wxt-dev/wxt/blob/main/packages/i18n/CHANGELOG.md', + ), + ]), + ]), ], sidebar: { - '/get-started/': menuRoot([ - menuGroup('Get Started', '/get-started/', [ - menuItem('Introduction', 'introduction'), - menuItem('Installation', 'installation'), - menuItem('Configuration', 'configuration'), - menuItem('Entrypoints', 'entrypoints'), - menuItem('Assets', 'assets'), - menuItem('Publishing', 'publishing'), - menuItem('Migrate to WXT', 'migrate-to-wxt'), - menuItem('Compare', 'compare'), - ]), - ]), '/guide/': menuRoot([ - menuGroup('Key Concepts', '/guide/key-concepts/', [ - menuItem('Manifest', 'manifest'), - menuItem('Auto-imports', 'auto-imports'), - menuItem('Web Extension Polyfill', 'web-extension-polyfill'), - menuItem('Frontend Frameworks', 'frontend-frameworks'), - menuItem('Content Script UI', 'content-script-ui'), - ]), - menuGroup('Directory Structure', '/guide/directory-structure/', [ - // Folders - menuItem('.output/', 'output'), - menuItem('.wxt/', 'wxt'), - menuItem('assets/', 'assets'), - menuItem('components/', 'components'), - menuItem('composables/', 'composables'), - menuGroup('entrypoints/', '/guide/directory-structure/entrypoints/', [ - menuItem('background', 'background.md'), - menuItem('bookmarks', 'bookmarks.md'), - menuItem('*.content.ts', 'content-scripts.md'), - menuItem('*.css', 'css.md'), - menuItem('devtools', 'devtools.md'), - menuItem('history', 'history.md'), - menuItem('newtab', 'newtab.md'), - menuItem('options', 'options.md'), - menuItem('popup', 'popup.md'), - menuItem('sandbox', 'sandbox.md'), - menuItem('sidepanel', 'sidepanel.md'), - menuItem('*.html', 'unlisted-pages.md'), - menuItem('*.ts', 'unlisted-scripts.md'), - ]), - menuItem('hooks/', 'hooks'), - menuItem('public/', 'public/', [ - menuItem('_locales/', 'public/locales'), - ]), - menuItem('utils/', 'utils'), - - // Files - menuItem('.env', 'env'), - menuItem('app.config.ts', 'app-config'), - menuItem('package.json', 'package'), - menuItem('tsconfig.json', 'tsconfig'), - menuItem('web-ext.config.ts', 'web-ext-config'), - menuItem('wxt.config.ts', 'wxt-config'), - ]), - menuGroup('Extension APIs', '/guide/extension-apis/', [ - menuItem('Storage', 'storage'), - menuItem('Messaging', 'messaging'), - menuItem('I18n', 'i18n'), - menuItem('Scripting', 'scripting'), - menuItem('Others', 'others'), + menuGroup('Get Started', '/guide/get-started/', [ + menuItem('Introduction', 'introduction.md'), + menuItem('Installation', 'installation.md'), ]), - menuGroup('Go Further', '/guide/go-further/', [ - menuItem('Testing', 'testing'), - menuItem('ES Modules', 'es-modules'), - menuItem('Debugging', 'debugging'), - menuItem('Handling Updates', 'handling-updates'), - menuItem('Vite', 'vite'), - menuItem('Custom Events', 'custom-events'), - menuItem('Reusable Modules', 'reusable-modules'), - menuItem('Remote Code', 'remote-code'), - menuItem('Entrypoint Loaders', 'entrypoint-loaders'), - menuItem('How WXT Works', 'how-wxt-works'), + menuGroup('Essentials', '/guide/essentials/', [ + menuItem('Project Structure', 'project-structure.md'), + menuItem('Entrypoints', 'entrypoints.md'), + menuGroup( + 'Configuration', + '/guide/essentials/config/', + [ + menuItem('wxt.config.ts', 'wxt.md'), + menuItem('Manifest', 'manifest.md'), + menuItem('Browser Startup', 'browser-startup.md'), + menuItem('Runtime Config', 'runtime.md'), + menuItem('TypeScript', 'typescript.md'), + menuItem('Vite', 'vite.md'), + ], + true, + ), + menuItem('Extension APIs', 'extension-apis.md'), + menuItem('Assets', 'assets.md'), + menuItem('Target Different Browsers', 'target-different-browsers.md'), + menuItem('Content Scripts', 'content-scripts.md'), + menuItem('Storage', 'storage.md'), + menuItem('Messaging', 'messaging.md'), + menuItem('I18n', 'i18n.md'), + menuItem('Scripting', 'scripting.md'), + menuItem('WXT Modules', 'wxt-modules.md'), + menuItem('Frontend Frameworks', 'frontend-frameworks.md'), + menuItem('Remote Code', 'remote-code.md'), + menuItem('Unit Testing', 'unit-testing.md'), + menuItem('E2E Testing', 'e2e-testing.md'), + menuItem('Publishing', 'publishing.md'), + menuItem('Testing Updates', 'testing-updates.md'), ]), - menuGroup('Upgrade Guide', '/guide/upgrade-guide/', [ - menuItem('wxt', 'wxt'), + menuGroup('Resources', '/guide/resources/', [ + menuItem('Compare', 'compare.md'), + menuItem('FAQ', 'faq.md'), + menuItem('Upgrading WXT', 'upgrading.md'), + menuItem('Migrate to WXT', 'migrate.md'), + menuItem('How WXT Works', 'how-wxt-works.md'), ]), - menuGroup('@wxt-dev/i18n', '/guide/i18n/', [ + ]), + '/i18n/': menuRoot([ + menuGroup('@wxt-dev/i18n', '/i18n/', [ menuItem('Introduction', 'introduction.md'), menuItem('Installation', 'installation.md'), menuItem('Messages File Format', 'messages-file-format.md'), @@ -158,17 +143,22 @@ export default defineConfig({ ]), ]), '/api/': menuRoot([ - menuGroup('CLI', '/api/cli/', [ - menuItem('wxt', 'wxt.md'), - menuItem('wxt build', 'wxt-build.md'), - menuItem('wxt zip', 'wxt-zip.md'), - menuItem('wxt prepare', 'wxt-prepare.md'), - menuItem('wxt clean', 'wxt-clean.md'), - menuItem('wxt init', 'wxt-init.md'), - menuItem('wxt submit', 'wxt-submit.md'), - menuItem('wxt submit init', 'wxt-submit-init.md'), - ]), - menuGroup('API Reference', prepareTypedocSidebar(typedocSidebar)), + menuGroup( + 'CLI Reference', + '/api/cli/', + [ + menuItem('wxt', 'wxt.md'), + menuItem('wxt build', 'wxt-build.md'), + menuItem('wxt zip', 'wxt-zip.md'), + menuItem('wxt prepare', 'wxt-prepare.md'), + menuItem('wxt clean', 'wxt-clean.md'), + menuItem('wxt init', 'wxt-init.md'), + menuItem('wxt submit', 'wxt-submit.md'), + menuItem('wxt submit init', 'wxt-submit-init.md'), + ], + true, + ), + menuGroup('API Reference', prepareTypedocSidebar(typedocSidebar), true), ]), }, }, diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index 1d249f5ad..8089da934 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -85,14 +85,10 @@ body { user-select: none; } -.VPSidebarItem.level-0.collapsible { +/* .VPSidebarItem.level-0.collapsible { padding-bottom: 0.5rem; } -.VPSidebarItem.level-0.collapsible .items { - /*border-left: 1px solid var(--vp-c-divider);*/ -} - .VPSidebarItem.level-1 { padding-left: 0.75rem; } @@ -113,4 +109,4 @@ body { text-align: center; vertical-align: middle; background-color: var(--vp-c-default-2); -} +} */ diff --git a/docs/.vitepress/utils/menus.ts b/docs/.vitepress/utils/menus.ts index aad00c56b..63d2b3e1c 100644 --- a/docs/.vitepress/utils/menus.ts +++ b/docs/.vitepress/utils/menus.ts @@ -2,9 +2,20 @@ import { DefaultTheme } from 'vitepress'; type SidebarItem = DefaultTheme.SidebarItem; type NavItem = DefaultTheme.NavItem; +type NavItemWithLink = DefaultTheme.NavItemWithLink; +type NavItemWithChildren = DefaultTheme.NavItemWithChildren; +type NavItemChildren = DefaultTheme.NavItemChildren; -export function navItem(text: string, link: string): NavItem { - return { text, link }; +export function navItem(text: string): NavItemChildren; +export function navItem(text: string, link: string): NavItemChildren; +export function navItem(text: string, items: any[]): NavItemWithChildren; +export function navItem(text: string, arg2?: unknown): any { + if (typeof arg2 === 'string') { + return { text, link: arg2 }; + } else if (Array.isArray(arg2)) { + return { text, items: arg2 }; + } + return { text }; } export function menuRoot(items: SidebarItem[]) { @@ -14,31 +25,39 @@ export function menuRoot(items: SidebarItem[]) { }); } -export function menuGroup(text: string, items: SidebarItem[]): SidebarItem; +export function menuGroup( + text: string, + items: SidebarItem[], + collapsable?: boolean, +): SidebarItem; export function menuGroup( text: string, base: string, items: SidebarItem[], + collapsable?: boolean, ): SidebarItem; export function menuGroup( text: string, a: string | SidebarItem[], - b?: SidebarItem[], + b?: SidebarItem[] | boolean, + c?: boolean, ): SidebarItem { - const collapsed = true; - if (typeof a === 'string') { + if (typeof a === 'string' && Array.isArray(b)) { return { text, base: a, items: b, - collapsed, + collapsed: c, }; } - return { - text, - items: a, - collapsed, - }; + if (typeof a !== 'string' && !Array.isArray(b)) + return { + text, + items: a, + collapsed: b, + }; + + throw Error('Unknown overload'); } export function menuItems(items: SidebarItem[]) { @@ -49,7 +68,7 @@ export function menuItems(items: SidebarItem[]) { export function menuItem( text: string, - link: string, + link?: string, items?: SidebarItem[], ): SidebarItem { if (items) { diff --git a/docs/guide/directory-structure/entrypoints/unlisted-pages.md b/docs/api/entrypoints/unlisted-pages.md similarity index 100% rename from docs/guide/directory-structure/entrypoints/unlisted-pages.md rename to docs/api/entrypoints/unlisted-pages.md diff --git a/docs/guide/directory-structure/entrypoints/unlisted-scripts.md b/docs/api/entrypoints/unlisted-scripts.md similarity index 100% rename from docs/guide/directory-structure/entrypoints/unlisted-scripts.md rename to docs/api/entrypoints/unlisted-scripts.md diff --git a/docs/auto-icons.md b/docs/auto-icons.md new file mode 100644 index 000000000..474e842c3 --- /dev/null +++ b/docs/auto-icons.md @@ -0,0 +1 @@ + diff --git a/docs/get-started/assets.md b/docs/get-started/assets.md deleted file mode 100644 index f8ef639a1..000000000 --- a/docs/get-started/assets.md +++ /dev/null @@ -1,33 +0,0 @@ -# Assets - -WXT has two directories for storing assets like CSS, images, or fonts. - -- [public directory](/guide/directory-structure/public/): Store files that will be copied into the output directory as-is -- [assets directory](/guide/directory-structure/assets): Store files that will be processed by Vite during the build process - -To learn more about how to use assets at runtime from either of these directories, visit their guides linked above. - -## Public Directory - -Place static files like the extension icon or `_locales/` directory here. These files will be copied over to the output directory without being transformed by Vite. - -``` - -└─ public/ - ├─ icon-16.png - ├─ icon-32.png - ├─ icon-48.png - ├─ icon-96.png - └─ icon-128.png -``` - -## Assets Directory - -Files in the assets directory will be processed by Vite. They are imported in your source code, and will be transformed or renamed in the output directory. - -``` - -└─ assets/ - ├─ tailwind.css - └─ illustration.svg -``` diff --git a/docs/get-started/compare.md b/docs/get-started/compare.md deleted file mode 100644 index 37e9e9eaf..000000000 --- a/docs/get-started/compare.md +++ /dev/null @@ -1,47 +0,0 @@ -# Compare - -Lets compare the features of WXT vs [Plasmo](https://docs.plasmo.com/framework) (another framework) and [CRXJS](https://crxjs.dev/vite-plugin) (a bundler plugin). - -## Overview - -| Features | WXT | Plasmo | CRXJS | -| ---------------------------------------------------- | :--------------: | :-------------: | :--------------: | -| Supports all browsers | ✅ | ✅ | 🟡 10 | -| MV2 Support | ✅ | ✅ | 🟡 1 | -| MV3 Support | ✅ | ✅ | 🟡 1 | -| Create Extension ZIPs | ✅ | ✅ | ❌ | -| Create Firefox Sources ZIP | ✅ | ❌ | ❌ | -| First-class TypeScript support | ✅ | ✅ | ✅ | -| Entrypoint discovery | ✅ 2 | ✅ 2 | ❌ | -| Inline entrypoint config | ✅ | ✅ | ❌ 9 | -| Auto-imports | ✅ | ❌ | ❌ | -| Supports all frontend frameworks | ✅ | 🟡 3 | ✅ | -| Framework specific entrypoints (like `Popup.tsx`) | 🟡 4 | ✅ 5 | ❌ | -| Automated publishing | ✅ | ✅ | ❌ | -| Remote Code Bundling (Google Analytics) | ✅ | ✅ | ❌ | -| Dev Mode | | | -| `.env` Files | ✅ | ✅ | ✅ | -| Opens browser with extension installed | ✅ | ❌ | ❌ | -| HMR for UIs | ✅ | 🟡 6 | ✅ | -| Reload HTML Files on Change | ✅ | 🟡 7 | ✅ | -| Reload Content Scripts on Change | ✅ | 🟡 7 | ✅ | -| Reload Background on Change | 🟡 7 | 🟡 7 | 🟡 7 | -| Respects Content Script `run_at` | ✅ | ✅ | ❌ 8 | -| Built-in Utils | | | | -| Storage | ✅ | ✅ | ❌ 11 | -| Messaging | ❌ 11 | ✅ | ❌ 11 | -| Content Script UI | ✅ | ✅ | ❌ 11 | - - - 1: Either MV2 or MV3, not both. -
2: File based. -
3: Only React, Vue, and Svelte. -
4: .html .ts .tsx. -
5: .html .ts .tsx. .vue .svelte. -
6: React only. -
7: Reloads entire extension. -
8: ESM-style loaders run asynchronously. -
9: Entrypoint options all configured in `manifest.json`. -
10: As of v2.0.0-beta.23, but v2 stable hasn't been released yet. -
11: There is no built-in wrapper around this API. However, you can still access the standard APIs via chrome/browser globals or use any 3rd party NPM package. -
diff --git a/docs/get-started/configuration.md b/docs/get-started/configuration.md deleted file mode 100644 index 04cb62efb..000000000 --- a/docs/get-started/configuration.md +++ /dev/null @@ -1,57 +0,0 @@ -# Configuration - -By default, WXT provides sensible configuration for bundling web extensions with Vite. - -## Config File - -To configure WXT, create a `wxt.config.ts` file in your project root. It should have the following contents: - -```ts -import { defineConfig } from 'wxt'; - -export default defineConfig({ - // My WXT config -}); -``` - -:::info -For more information on configuring WXT via the `wxt.config.ts` file, read the dedicated [`wxt.config.ts` guide](/guide/directory-structure/wxt-config). -::: - -## Manifest.json - -WXT generates your extension's `manifest.json` based on the project structure. To add additional properties, like permissions, use the [`manifest` property](/api/reference/wxt/interfaces/InlineConfig#manifest). - -```ts -import { defineConfig } from 'wxt'; - -export default defineConfig({ - manifest: { - permissions: ['storage'], - }, -}); -``` - -:::info -For more information on configuring the manifest, read the dedicated [Manifest guide](/guide/key-concepts/manifest). -::: - -## Environment - -WXT can read `.env` files, and variables are accessible via `import.meta.env.*`. - -:::code-group - -```sh [.env] -VITE_OAUTH_CLIENT_ID=abc123 -``` - -```ts [JS] -import.meta.env.VITE_OAUTH_CLIENT_ID; -``` - -::: - -:::info -For more information on using .env files, read the dedicated [`.env` guide](/guide/directory-structure/env). -::: diff --git a/docs/get-started/entrypoints.md b/docs/get-started/entrypoints.md deleted file mode 100644 index 65b7bf08d..000000000 --- a/docs/get-started/entrypoints.md +++ /dev/null @@ -1,60 +0,0 @@ -# Entrypoints - -An "entrypoint" is any HTML, JS, or CSS file that needs to be bundled and included with your extension, which will be loaded and executed by the browser. - -## Defining Entrypoints - -In WXT, you create an entrypoint by adding a file to the `entrypoints/` directory. - -``` - -└─ entrypoints/ - ├─ background.ts - ├─ content.ts - ├─ injected.ts - └─ popup.html -``` - -Some entrypoint filesname patterns are reserved by WXT and effect how the manifest is generated. - -- `popup` adds an `action` to the manifest -- `background` adds a background script/service worker -- `*.content.ts` adds a content script -- ... - -> For a full list of recognized filenames, see the the [Entrypoints Directory guide](/guide/directory-structure/entrypoints/background). - -Any other files, whether JS, CSS, or HTML, is considered "unlisted". Unlisted files, like `injected.ts` from above, are just bundled to the output directory and not added to the manifest. You can still access or load them at runtime. - -## Entrypoint Options - -Most entrypoints allow customizing their options in the file you define them in. This differs from regular web extension development, where all options are placed in the `manifest.json`. - -WXT looks for custom options in the entrypoint, and adds them to the manifest when generated. - -In HTML files, options are listed as `meta` tags: - -```html - - - - - - -``` - -In TS files, options are apart of the file's default export: - -```ts -export default defineContentScript({ - matches: ['*://*.google.com/*'], - runAt: 'document_start', - main() { - // ... - }, -}); -``` - -:::info -All options for each entrypoint type is listed in the [entrypoints directory docs](/guide/directory-structure/entrypoints/background). -::: diff --git a/docs/get-started/installation.md b/docs/get-started/installation.md deleted file mode 100644 index 5159f3fd2..000000000 --- a/docs/get-started/installation.md +++ /dev/null @@ -1,116 +0,0 @@ -# Installation - -Bootstrap a new project, start from scratch, or [migrate an existing project](/get-started/migrate-to-wxt). - -## Bootstrap Project - -:::code-group - -```sh [pnpm] -pnpm dlx wxt@latest init -``` - -```sh [npm] -npx wxt@latest init -``` - -```sh [bun] -# The "wxt init" command currently fails when ran with bunx. -# Use NPX as a workaround, and select "bun" as your package -# manager. To stay up to date with this issue, follow -# https://github.com/wxt-dev/wxt/issues/707 -# -# bunx wxt@latest init - -npx wxt@latest init -``` - -::: - -There are several starting templates available. - -| TypeScript | -| ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`vanilla`](https://github.com/wxt-dev/wxt/tree/main/templates/vanilla) | -| [`vue`](https://github.com/wxt-dev/wxt/tree/main/templates/vue) | -| [`react`](https://github.com/wxt-dev/wxt/tree/main/templates/react) | -| [`svelte`](https://github.com/wxt-dev/wxt/tree/main/templates/svelte) | -| [`solid`](https://github.com/wxt-dev/wxt/tree/main/templates/solid) | - -:::info -All templates default to TypeScript. Rename the file extensions to `.js` to use JavaScript instead. -::: - -## From Scratch - -Initialize a project and install `wxt`: - -:::code-group - -```sh [pnpm] -pnpm init -pnpm add -D wxt -``` - -```sh [npm] -npm init -npm i --save-dev wxt -``` - -```sh [yarn] -yarn init -yarn add --dev wxt -``` - -```sh [bun] -bun init -bun add --dev wxt -``` - -::: - -Add your first entrypoint: - -```ts -// entrypoints/background.ts -export default defineBackground(() => { - console.log(`Hello from ${browser.runtime.id}!`); -}); -``` - -And add scripts to your `package.json`: - -```json -{ - "scripts": { - "dev": "wxt", // [!code ++] - "dev:firefox": "wxt --browser firefox", // [!code ++] - "build": "wxt build", // [!code ++] - "build:firefox": "wxt build --browser firefox", // [!code ++] - "zip": "wxt zip", // [!code ++] - "zip:firefox": "wxt zip --browser firefox", // [!code ++] - "postinstall": "wxt prepare" // [!code ++] - } -} -``` - -## Development - -Once the project is setup, you can start the development server using the `dev` script. - -```sh -pnpm dev -``` - -:::tip 🎉 Well done! -The dev command will build the extension for development, open the browser, and reload the different parts of the extension when you save changes. -::: - -## Next Steps - -You're ready to build your web extension! - -- Read the rest of the "Get Started" pages for a high-overview of what WXT can do -- Read the [Guide](/guide/key-concepts/manifest) to learn in-depth about each feature WXT supports -- [Configure WXT](./configuration) by creating a `wxt.config.ts` file -- Checkout [example projects](https://github.com/wxt-dev/examples) to see how to perform common tasks with WXT diff --git a/docs/get-started/introduction.md b/docs/get-started/introduction.md deleted file mode 100644 index a1d196a7d..000000000 --- a/docs/get-started/introduction.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -head: - - - link - - rel: canonical - href: https://wxt.dev ---- - -# Introduction - -## Overview - -WXT is a free and open source framework for building web extensions in an conventional, intuitive, and safe way **_for all browsers_**. - -WXT is based on [Nuxt](https://nuxt.com), and aims to provide the same great DX with TypeScript, auto-imports, and an opinionated project structure. - -![Example build output](../assets/cli-output.png) - -## Conventions - -WXT is an opinionated framework. This helps keep projects consistent and easy to pick up. - -- **Generated manifest**: Based on your project's file structure -- **Entrypoint configuration**: Configure entrypoints from the same file they're declare in -- **Type-safety is a priority**: Out-of-the-box TypeScript support with improved browser API typing -- **Simple output file structure**: Output file paths minimize the path at runtime - -## Development - -WXT's dev server supports modern features like HMR to provide a lighting fast dev mode. - -When changes can't be hot-reloaded, like content scripts or background scripts, they're reloaded individually to prevent reloading the entire extension and slowing down your development cycle. - -## Production-ready - -Production builds are optimized for store review, changing as few files as possible between builds. - -In addition, WXT fully supports Firefox's source code requirements when using a bundler. It will automatically create and upload a ZIP file of your source code. - -:::info -See [Publishing](./publishing) for more info around production builds. -::: - -## New to Extension Development? - -Most of these docs assume you have a basic understanding of how to write a chrome or web extension. - -If you've never written a web extension before or need a refresher, follow Google's ["Hello, World!" tutorial](https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world) to understand the basics. diff --git a/docs/guide/directory-structure/app-config.md b/docs/guide/directory-structure/app-config.md deleted file mode 100644 index e5c2582ce..000000000 --- a/docs/guide/directory-structure/app-config.md +++ /dev/null @@ -1,61 +0,0 @@ -# `/app.config.ts` - -:::warning Nuxt Users -If you're familiar with Nuxt, this file is meant to be a direct equivalent to Nuxt's `app.config.ts` file. - -However, some of Nuxt's features, like overriding the app config based on a `.env` file or automatically generating the config's types, are not implemented. They are planned, just not implemented yet. Feel free to open a PR! -::: - -## Overview - -Define runtime configuration in a single place. - -```ts -// /app.config.ts -import { defineAppConfig } from 'wxt/sandbox'; - -// Define types for your config -declare module 'wxt/sandbox' { - export interface WxtAppConfig { - theme?: 'light' | 'dark'; - } -} - -export default defineAppConfig({ - theme: 'dark', -}); -``` - -Then access the config in your extension by calling `useAppConfig`: - -```ts -console.log(useAppConfig()); // { theme: "dark" } -``` - -## Environment Variables - -If you have a `.env` file, you can access any variables defined in it here. You can convert them to better types (like booleans), add types for them, or leave them as is. - -```txt -# .env -VITE_BUG_REPORTING_DISABLED=true -VITE_API_KEY=... -``` - -```ts -// /app.config.ts - -declare module 'wxt/sandbox' { - export interface WxtAppConfig { - bugReportingDisabled: boolean; - apiKey?: string; - } -} - -export default defineAppConfig({ - bugReportingDisabled: import.meta.env.VITE_BUG_REPORTING_DISABLED === 'true', - apiKey: import.meta.env.VITE_API_KEY, -}); -``` - -> You don't have to do this, you can use `import.meta.env.VITE_*` anywhere in your runtime code, but putting them here consolidates them to one place and defines what variables are expected. diff --git a/docs/guide/directory-structure/assets.md b/docs/guide/directory-structure/assets.md deleted file mode 100644 index f28bac1ae..000000000 --- a/docs/guide/directory-structure/assets.md +++ /dev/null @@ -1,42 +0,0 @@ -# `/assets` - -Files in the assets directory will be processed by Vite. They are imported in your source code, and will be transformed or renamed in the output directory. - -``` - -└─ assets/ - ├─ style.css - └─ illustration.svg -``` - -### Example - -:::code-group - -```html [popup.html] - - - - - - - - - - -``` - -```ts [content.ts] -import '~/assets/style.css'; -import illustration from '~/assets/style.svg'; - -defineContentScript({ - main() { - const image = document.createElement('img'); - image.src = illustration; - document.body.append(image); - }, -}); -``` - -::: diff --git a/docs/guide/directory-structure/components.md b/docs/guide/directory-structure/components.md deleted file mode 100644 index 0bb2f0b20..000000000 --- a/docs/guide/directory-structure/components.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/components` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/composables.md b/docs/guide/directory-structure/composables.md deleted file mode 100644 index c1ada3ec5..000000000 --- a/docs/guide/directory-structure/composables.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/composables` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/entrypoints/background.md b/docs/guide/directory-structure/entrypoints/background.md deleted file mode 100644 index b5df3dd92..000000000 --- a/docs/guide/directory-structure/entrypoints/background.md +++ /dev/null @@ -1,47 +0,0 @@ -# Background - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/background/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background) - -For MV2, the background is added as a script to the background page. For MV3, the background becomes a service worker. - -## Filenames - - - -## Definition - -:::warning -The main function of the background **_CANNOT BE ASYNC_**. Event listeners must be added synchronously on background startup. If your main function returns a promise, WXT will log an error. -::: - -```ts -export default defineBackground(() => { - // Executed when background is loaded -}); -``` - -or - -```ts -export default defineBackground({ - // Set manifest options - persistent: undefined | true | false, - type: undefined | 'module', - - // Set include/exclude if the background should be removed from some builds - include: undefined | string[], - exclude: undefined | string[], - - // Executed when background is loaded - main() { - // ... - }, -}); -``` - -> All manifest options default to `undefined`. diff --git a/docs/guide/directory-structure/entrypoints/bookmarks.md b/docs/guide/directory-structure/entrypoints/bookmarks.md deleted file mode 100644 index 10434f3cd..000000000 --- a/docs/guide/directory-structure/entrypoints/bookmarks.md +++ /dev/null @@ -1,31 +0,0 @@ -# Bookmarks - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/override/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides) - -## Filenames - - - -## Definition - -```html - - - - - - Title - - - - - - - - -``` diff --git a/docs/guide/directory-structure/entrypoints/content-scripts.md b/docs/guide/directory-structure/entrypoints/content-scripts.md deleted file mode 100644 index 41982076c..000000000 --- a/docs/guide/directory-structure/entrypoints/content-scripts.md +++ /dev/null @@ -1,107 +0,0 @@ -# Content Scripts - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/content_scripts/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts) - -When creating content script entrypoints, they are automatically included in the `manifest.json` along with any CSS files they import. - -## Filenames - - - -## Definition - -```ts -export default defineContentScript({ - // Set manifest options - matches: string[], - excludeMatches: undefined | [], - includeGlobs: undefined | [], - excludeGlobs: undefined | [], - allFrames: undefined | [], - runAt: undefined | 'document_start' | 'document_end' | 'document_idle', - matchAboutBlank: undefined | true | false, - matchOriginAsFallback: undefined | true | false, - world: undefined | 'ISOLATED' | 'MAIN', - - // Set include/exclude if the background should be removed from some builds - include: undefined | string[], - exclude: undefined | string[], - - // Configure how CSS is injected onto the page - cssInjectionMode: undefined | "manifest" | "manual" | "ui", - - // Configure how/when content script will be registered - registration: undefined | "manifest" | "runtime", - - main(ctx: ContentScriptContext) { - // Executed when content script is loaded - }, -}); -``` - -> All manifest options default to `undefined`. - -When defining multiple content scripts, content script entrypoints that have the same set of options will be merged into a single `content_script` item in the manifest. - -## CSS - -To include CSS with your content script, import the CSS file at the top of your entrypoint. - -``` - -/ -└─ entrypoints/ - └─ overlay.content/ - ├─ index.ts - └─ style.css -``` - -```ts -// entrypoints/overlay.content/index.ts -import './style.css'; - -export default defineContentScript({ - matches: ['*://google.com/*', '*://duckduckgo.com/*'], - - main(ctx) { - // ... - }, -}); -``` - -Any styles imported in your content script will be added to that content script's `css` array in your `manifest.json`: - -```json -// .output/chrome-mv3/manifest.json -{ - "content_scripts": [ - { - "matches": ["*://google.com/*", "*://duckduckgo.com/*"], - "js": ["content-scripts/overlay.js"], - "css": ["content-scripts/overlay.css"] - } - ] -} -``` - -To disable this behavior, set `cssInjectionMode` to `"manual"` or `"ui"`. - -```ts -export default defineContentScript({ - matches: ['*://google.com/*', '*://duckduckgo.com/*'], - cssInjectionMode: 'manual', - - main(ctx) { - // ... - }, -}); -``` - -See [Content Script UI](/guide/key-concepts/content-script-ui) for more info on creating UIs and including CSS in content scripts. diff --git a/docs/guide/directory-structure/entrypoints/css.md b/docs/guide/directory-structure/entrypoints/css.md deleted file mode 100644 index 0e38c46c6..000000000 --- a/docs/guide/directory-structure/entrypoints/css.md +++ /dev/null @@ -1,44 +0,0 @@ -# CSS - -WXT can build CSS entrypoints individually. CSS entrypoints are always unlisted. - -See [Content Script CSS](/guide/directory-structure/entrypoints/content-scripts#css) documentation for the recommended approach to include CSS with a content script. - -:::info -If the recommended approach doesn't work for your use case, you can use any of the filename patterns below to build the styles separate from the JS and use the [`transformManifest` hook](/api/reference/wxt/interfaces/InlineConfig#transformmanifest) to manually add your CSS file to the manifest. -::: - -## Filenames - - - -## Definition - -```css -body { - /* Plain CSS file */ -} -``` - -Follow Vite's guide to setup a preprocessor: https://vitejs.dev/guide/features.html#css-pre-processors - -```sh -pnpm i sass -``` - -```scss -body { - h1 { - /* ...*/ - } -} -``` diff --git a/docs/guide/directory-structure/entrypoints/devtools.md b/docs/guide/directory-structure/entrypoints/devtools.md deleted file mode 100644 index da3cda04a..000000000 --- a/docs/guide/directory-structure/entrypoints/devtools.md +++ /dev/null @@ -1,40 +0,0 @@ -# Devtools - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/devtools/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/devtools_page) - -## Filenames - - - -## Definition - -```html - - - - - - - - - - - - - -``` - -## Adding UI Elements - -Chrome extensions allow you to add panels and side panes to the devtools window. - -![DevTools window showing Elements panel and Styles sidebar pane.](https://developer.chrome.com/static/docs/extensions/how-to/devtools/extend-devtools/image/devtools-window-showing-e-9051f7f0347cd_1920.png) - -See the WXT's examples for a full walkthrough of extending the devtools window: - -- [Devtools Setup](https://github.com/wxt-dev/wxt-examples/tree/main/examples/vanilla-devtools#readme) diff --git a/docs/guide/directory-structure/entrypoints/history.md b/docs/guide/directory-structure/entrypoints/history.md deleted file mode 100644 index 9fc11a1b6..000000000 --- a/docs/guide/directory-structure/entrypoints/history.md +++ /dev/null @@ -1,31 +0,0 @@ -# History - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/override/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides) - -## Filenames - - - -## Definition - -```html - - - - - - Title - - - - - - - - -``` diff --git a/docs/guide/directory-structure/entrypoints/newtab.md b/docs/guide/directory-structure/entrypoints/newtab.md deleted file mode 100644 index e15dcb2b6..000000000 --- a/docs/guide/directory-structure/entrypoints/newtab.md +++ /dev/null @@ -1,31 +0,0 @@ -# Newtab - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/override/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides) - -## Filenames - - - -## Definition - -```html - - - - - - Title - - - - - - - - -``` diff --git a/docs/guide/directory-structure/entrypoints/options.md b/docs/guide/directory-structure/entrypoints/options.md deleted file mode 100644 index f4af0271c..000000000 --- a/docs/guide/directory-structure/entrypoints/options.md +++ /dev/null @@ -1,36 +0,0 @@ -# Options - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/options/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_ui) - -## Filenames - - - -## Definition - -```html - - - - - - Options Title - - - - - - - - - - - -``` - -> All manifest options default to `undefined` when the `meta` tag is not present. diff --git a/docs/guide/directory-structure/entrypoints/popup.md b/docs/guide/directory-structure/entrypoints/popup.md deleted file mode 100644 index 536742e42..000000000 --- a/docs/guide/directory-structure/entrypoints/popup.md +++ /dev/null @@ -1,43 +0,0 @@ -# Popup - -[Chrome Docs](https://developer.chrome.com/docs/extensions/reference/action/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/action) - -## Filenames - - - -## Definition - -```html - - - - - - Default Popup Title - - - - - - - - - - - -``` - -> All manifest options default to `undefined` when the `meta` tag is not present. diff --git a/docs/guide/directory-structure/entrypoints/sandbox.md b/docs/guide/directory-structure/entrypoints/sandbox.md deleted file mode 100644 index 886c64dce..000000000 --- a/docs/guide/directory-structure/entrypoints/sandbox.md +++ /dev/null @@ -1,37 +0,0 @@ -# Sandbox - -[Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/sandbox/) - -:::tip Chromium Only -Firefox does not support sandboxed pages. -::: - -## Filenames - - - -## Definition - -```html - - - - - - Title - - - - - - - - -``` diff --git a/docs/guide/directory-structure/entrypoints/sidepanel.md b/docs/guide/directory-structure/entrypoints/sidepanel.md deleted file mode 100644 index 8e61a07ca..000000000 --- a/docs/guide/directory-structure/entrypoints/sidepanel.md +++ /dev/null @@ -1,49 +0,0 @@ -# Side Panel - -[Chrome Docs](https://developer.chrome.com/docs/extensions/reference/sidePanel/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars) - -In Chrome, side panels use the "side_panel" API, while Firefox uses the "sidebar_action" API. - -:::warning -Chrome added support for sidepanels in Manifest V3, they are not available in Manifest V2. -::: - -## Filenames - - - -## Definition - -```html - - - - - - Default Side Panel Title - - - - - - - - - - - -``` diff --git a/docs/guide/directory-structure/env.md b/docs/guide/directory-structure/env.md deleted file mode 100644 index 6a17fbce2..000000000 --- a/docs/guide/directory-structure/env.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/.env` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/hooks.md b/docs/guide/directory-structure/hooks.md deleted file mode 100644 index e6e19836c..000000000 --- a/docs/guide/directory-structure/hooks.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/hooks` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/output.md b/docs/guide/directory-structure/output.md deleted file mode 100644 index bb5ef4176..000000000 --- a/docs/guide/directory-structure/output.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/.output` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/package.md b/docs/guide/directory-structure/package.md deleted file mode 100644 index 79f23b570..000000000 --- a/docs/guide/directory-structure/package.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/package.json` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/public/index.md b/docs/guide/directory-structure/public/index.md deleted file mode 100644 index 765e1a44a..000000000 --- a/docs/guide/directory-structure/public/index.md +++ /dev/null @@ -1,35 +0,0 @@ -# `public/` - -Place static files like the extension icon or `_locales/` directory here. These files will be copied over to the output directory without being transformed by Vite. - -``` - -└─ public/ - ├─ icon-16.png - ├─ icon-32.png - ├─ icon-48.png - ├─ icon-96.png - └─ icon-128.png -``` - -### Example - -You can reference these files by using absolute paths in HTML files or `browser.runtime.getURL` in content scripts. - -:::code-group - -```html [popup.html] - -``` - -```ts [content.ts] -defineContentScript({ - main() { - const image = document.createElement('img'); - image.src = browser.runtime.getURL('/icon-128.png'); - document.body.append(image); - }, -}); -``` - -::: diff --git a/docs/guide/directory-structure/public/locales.md b/docs/guide/directory-structure/public/locales.md deleted file mode 100644 index 36a573031..000000000 --- a/docs/guide/directory-structure/public/locales.md +++ /dev/null @@ -1,5 +0,0 @@ -# `public/_locales/` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/tsconfig.md b/docs/guide/directory-structure/tsconfig.md deleted file mode 100644 index 81220e425..000000000 --- a/docs/guide/directory-structure/tsconfig.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/tsconfig.json` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/utils.md b/docs/guide/directory-structure/utils.md deleted file mode 100644 index 54cd86e50..000000000 --- a/docs/guide/directory-structure/utils.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/utils` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/web-ext-config.md b/docs/guide/directory-structure/web-ext-config.md deleted file mode 100644 index 88b33744c..000000000 --- a/docs/guide/directory-structure/web-ext-config.md +++ /dev/null @@ -1,65 +0,0 @@ -# `web-ext.config.ts` - -This file lets you configure the browser startup when running `wxt dev`. - -```ts -import { defineRunnerConfig } from 'wxt'; - -export default defineRunnerConfig({ - startUrls: ['https://google.com', 'https://youtube.com'], -}); -``` - -There are three places you can customize the runner: - -- `/wxt.config.ts` - Use the `runner` option. Changes here will be committed and shared with everyone developing the project. -- `/web-ext.config.ts` - A gitignored file for you to customize the startup behavior to your liking without effecting others -- `$HOME/web-ext.config.ts` - Stores system-wide config effecting all projects running on your machine. - -See below examples on how to accomplish common configuration: - -[[toc]] - -## Configuring Binaries - -`web-ext`'s browser discovery is very limited. By default, it only guesses at where Chrome and Firefox are installed. If you've customized your install locations, you may need to tell `web-ext` where the binaries/executables are located using the [`binaries` option](/api/reference/wxt/interfaces/ExtensionRunnerConfig#binaries). For other Chromium based browsers, like Edge or Opera, you'll need to explicitly list them in the `binaries` option as well, otherwise they will open in Chrome by default. - -```ts -import { defineRunnerConfig } from 'wxt'; - -export default defineRunnerConfig({ - binaries: { - chrome: '/path/to/chrome-beta', // Use Chrome Beta instead of regular Chrome - firefox: 'firefoxdeveloperedition', // Use Firefox Developer Edition instead of regular Firefox - edge: '/path/to/edge', // Open MS Edge when running "wxt -b edge" - }, -}); -``` - -## Disable Opening Browser - -Disabling the browser can be useful if it's difficult to develop your extension with fresh profiles. Maybe you need to sign into a website to see a content script run, and a fresh profile isn't helpful because it doesn't save your login info. - -To disable opening the extension automatically in a new window, just disable the runner: - -```ts -export default defineRunnerConfig({ - disabled: true, -}); -``` - -## Profile Customization - -Another option, instead of disabling the runner, to stay logged into websites is to use a custom profile. - -`web-ext` comes with some built-in ways of using an existing profile, but it's not really using the same profile. It copies the profile to a temp directory, and uses that. - -Instead, I've found it's better to pass Chrome's `--user-data-dir` argument. This let's you use a fresh profile initially, and customize it to your liking. You can install devtool extensions, set custom flags, and log into websites. Next time you run the extension in dev mode, all that will be remembered! - -```ts -export default defineRunnerConfig({ - chromiumArgs: ['--user-data-dir=./chrome-data'], -}); -``` - -> This only works for Chrome. You'll have to use `firefoxProfile` option instead, which has the same limitations mentioned above, where you won't be signed into websites automatically. diff --git a/docs/guide/directory-structure/wxt-config.md b/docs/guide/directory-structure/wxt-config.md deleted file mode 100644 index 30c0e8314..000000000 --- a/docs/guide/directory-structure/wxt-config.md +++ /dev/null @@ -1,5 +0,0 @@ -# `/wxt.config.ts` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/directory-structure/wxt.md b/docs/guide/directory-structure/wxt.md deleted file mode 100644 index 557ce1487..000000000 --- a/docs/guide/directory-structure/wxt.md +++ /dev/null @@ -1,5 +0,0 @@ -# `.wxt/` - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/essentials/assets.md b/docs/guide/essentials/assets.md new file mode 100644 index 000000000..106ee26f5 --- /dev/null +++ b/docs/guide/essentials/assets.md @@ -0,0 +1,80 @@ +# Assets + +## `/assets` Directory + +Any assets imported or referenced inside the `/assets/` directory will be processed by WXT's bundler. + +Here's how you access them: + +:::code-group + +```ts [JS] +import imageUrl from '~/assets/image.png'; + +const img = document.createElement('img'); +img.src = imageUrl; +``` + +```html [HTML] + +``` + +```css [CSS] +.bg-image { + background-image: url(~/assets/image.png); +} +``` + +::: + +## `/public` Directory + +Files inside `/public/` are copied into the output folder as-is, without being processed by WXT's bundler. + +Here's how you access them: + +:::code-group + +```ts [JS] +import imageUrl from '/image.png'; + +const img = document.createElement('img'); +img.src = imageUrl; +``` + +```html [HTML] + +``` + +```css [CSS] +.bg-image { + background-image: url(/image.png); +} +``` + +::: + +## Inside Content Scripts + +Assets inside content scripts are a little different. By default, when you import an asset, it returns just the path to the asset. This is because WXT assumes you're loading assets from the same hostname. + +But, inside content scripts, the hostname is whatever the tab is set to. So if you try to fetch the asset, manually or as an ``'s `src`, it will be loaded from the tab's website, not your extension. + +To fix this, you need to convert the image to a full URL using `browser.runtime.getURL`: + +```ts +// entrypoints/content.ts +import iconUrl from '/icon/128.png'; + +export default defineContentScript({ + matches: ['*://*.google.com/*'], + main() { + console.log(iconUrl); // "/icon/128.png" + console.log(browser.runtime.getURL(iconUrl)); // "chrome-extension:///icon/128.png" + }, +}); +``` + +## WASM + +TODO diff --git a/docs/guide/essentials/config/browser-startup.md b/docs/guide/essentials/config/browser-startup.md new file mode 100644 index 000000000..475aae71d --- /dev/null +++ b/docs/guide/essentials/config/browser-startup.md @@ -0,0 +1,68 @@ +--- +outline: deep +--- + +# Browser Startup + +> See the [API Reference](/api/reference/wxt/interfaces/ExtensionRunnerConfig) for a full list of config. + +During development WXT uses [`web-ext` by Mozilla](https://www.npmjs.com/package/web-ext) to automatically open a browser window with your extension installed. + +## Config Files + +You can configure browser startup in 3 places: + +1. `/web-ext.config.ts`: Ignored from version control, this file lets you configure your own options without effectint other developers + + ```ts + import { defineRunnerConfig } from 'wxt'; + + export default defineRunnerConfig({ + // ... + }); + ``` + +2. `/wxt.config.ts`: Via the [`runner` config](/api/reference/wxt/interfaces/InlineConfig#runner), included in version control +3. `$HOME/web-ext.config.ts`: Provide default values for all WXT projects on your computer + +## Recipes + +### Set Browser Binaries + +To set or customize the browser opened during development: + +```ts +export default defineRunnerConfig({ + binaries: { + chrome: '/path/to/chrome-beta', // Use Chrome Beta instead of regular Chrome + firefox: 'firefoxdeveloperedition', // Use Firefox Developer Edition instead of regular Firefox + edge: '/path/to/edge', // Open MS Edge when running "wxt -b edge" + }, +}); +``` + +### Persist Data + +By default, to keep from modifying your browser's existing profiles, `web-ext` creates a brand new profile every time you run the `dev` script. + +Right now, Chromium based browsers are the only browsers that support overriding this behavior and persisting data when running the `dev` script multiple times. + +To persist data, set the `--user-data-dir` flag: + +```ts +export default defineRunnerConfig({ + chromiumArgs: ['--user-data-dir=./.wxt/chrome-data'], +}); +``` + +Now, next timne you run the `dev` script, a persistent profile will be created in `.wxt/chrome-data/{profile-name}`. With a persistent profile, you can install devtools extensions to help with development, allow the browser to remember logins, etc, without worrying about the profile being reset the next time you run the `dev` script. + +### Disable Opening Browser + +If you prefer to load the extension into your browser manually, you can disable the auto-open behavior: + +```ts +export default defineRunnerConfig({ + disabled: true, +}); +``` diff --git a/docs/guide/essentials/config/manifest.md b/docs/guide/essentials/config/manifest.md new file mode 100644 index 000000000..cd15837b1 --- /dev/null +++ b/docs/guide/essentials/config/manifest.md @@ -0,0 +1,255 @@ +# Manifest + +In WXT, there is no `manifest.json` file in your source code. Instead, WXT generates it during the build process based off files in your project. + +## Manfiest Config + +To manually add a property to the `manifest.json` output during builds, use the `manifest` config inside `wxt.config.ts`: + +```ts +export default defineConfig({ + manifest: { + // Put manual changes here + }, +}); +``` + +You can also define the manifest as a function, and use JS to generate it based on the target browser, mode, and more. + +```ts +export default defineConfig({ + manifest: ({ browser, manifestVersion, mode, command }) => { + return { + // ... + }; + }, +}); +``` + +### MV2 and MV3 Compatibility + +When adding properties to the manifest, when possible, always define the property in it's MV3 format. When targetting MV2, WXT will automatically convert these properties to their MV2 format. + +For example, for this config: + +```ts +export default defineConfig({ + manifest: { + action: { + default_title: 'Some Title', + }, + web_accessible_resources: [ + { + matches: ['*://*.google.com/*'], + resources: ['icon/*.png'], + }, + ], + }, +}); +``` + +WXT will generate the following manifests: + +:::code-group + +```json [MV2] +{ + "manifest_version": 2, + // ... + "browser_action": { + "default_title": "Some Title" + }, + "web_accessible_resources": ["icon/*.png"] +} +``` + +```json [MV3] +{ + "manifest_version": 3, + // ... + "action": { + "default_title": "Some Title" + }, + "web_accessible_resources": [ + { + "matches": ["*://*.google.com/*"], + "resources": ["icon/*.png"] + } + ] +} +``` + +::: + +You can also specify properties specific to a single manifest version, and they will be stripped out when targetting the other manifest version. + +## Name + +> [Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/name/) + +If not provided via the `manifest` config, the manifest's `name` property defaults to your `package.json`'s `name` property. + +## Version and Version Name + +> [Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/version/) + +Your extension's `version` and `version_name` is based on the `version` from your `package.json`. + +- `version_name` is the exact string listed +- `version` is the string cleaned up, with any invalid suffixes removed + +Example: + +```json +// package.json +{ + "version": "1.3.0-alpha2" +} +``` + +```json +// .output//manifest.json +{ + "version": "1.3.0", + "version_name": "1.3.0-alpha2" +} +``` + +If a version is not present in your `package.json`, it defaults to `"0.0.0"`. + +## Icons + +WXT automatically discovers your extension's icon by looking at files in the `public/` directory: + +``` +public/ +├─ icon-16.png +├─ icon-24.png +├─ icon-48.png +├─ icon-96.png +└─ icon-128.png +``` + +Specifically, if an icon must match one of these regex to be discovered: + +<<< @/../packages/wxt/src/core/utils/manifest.ts#snippet + +If you don't like these filename or you're migrating to WXT and don't want to rename the files, you can manually specify an `icon` in your manifest: + +```ts +export default defineConfig({ + manifest: { + icons: { + 16: '/extension-icon-16.png', + 24: '/extension-icon-24.png', + 48: '/extension-icon-48.png', + 96: '/extension-icon-96.png', + 128: '/extension-icon-128.png', + }, + }, +}); +``` + +Alternatively, you can use [`@wxt-dev/auto-icons`](https://www.npmjs.com/package/@wxt-dev/auto-icons) to let WXT generate your icon at the required sizes. + +## Permissions + +> [Chrome docs](https://developer.chrome.com/docs/extensions/reference/permissions/) + +```ts +export default defineConfig({ + manifest: { + permissions: ['storage', 'tabs'], + }, +}); +``` + +## Host Permissions + +> [Chrome docs](https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#host-permissions) + +```ts +export default defineConfig({ + manifest: { + permissions: ['storage', 'tabs'], + }, +}); +``` + +:::warning +If you use host permissions and target both MV2 and MV3, make sure to only include the required host permissions for each version: + +```ts +export default defineConfig({ + manifest: ({ manifestVersion }) => ({ + host_permissions: manifestVersion === 2 ? [...] : [...], + }), +}); +``` + +::: + +## Default Locale + +> See [Extension APIs > I18n](/guide/extension-apis/i18n) for a full guide on internationalizing your extension. + +```ts +export default defineConfig({ + manifest: { + name: '__MSG_extName__', + description: '__MSG_extDescription__', + default_locale: 'en', + }, +}); +``` + +## Actions + +In MV2, you had two options: [`browser_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) and [`page_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action). In MV3, they were merged into a single [`action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/action) API. + +By default, whenever an `action` is generated, WXT falls back to `browser_action` when targetting MV2. + +### Action With Popup + +To generate a manifest where a UI appears after clicking the icon, just create a [Popup entrypoint](/guide/entrypoint-types/popup). +export default defineConfig({ +hooks: { +build: { +manifestGenerated(manifest) { +// Update the manifest variable by reference +manifest.name = 'Overriden name'; +}, +}, +}, +}); + +If you want to use a page_action for MV2, add the following meta tag to the HTML document's head: + +```html + +``` + +### Action Without Popup + +If you want to use the `activeTab` permission or the `browser.action.onClicked` event, but don't want to show a popup: + +1. Delete the [Popup entrypoint](/guide/entrypoint-types/popup) if it exists +2. Add the `action` key to your manifest: + ```ts + export default defineConfig({ + manifest: { + action: {}, + }, + }); + ``` + +Same as an action with a popup, WXT will fallback on using `browser_action` for MV2. To use a `page_action` instead, add that key as well: + +```ts +export default defineConfig({ + manifest: { + action: {}, + page_action: {}, + }, +}); +``` diff --git a/docs/guide/essentials/config/runtime.md b/docs/guide/essentials/config/runtime.md new file mode 100644 index 000000000..bbc736192 --- /dev/null +++ b/docs/guide/essentials/config/runtime.md @@ -0,0 +1,79 @@ +# Runtime Config + +There are two ways to configure runtime behavior: + +- `app.config.ts` +- Environment Variables + +## `app.config.ts` + +:::warning +This API is still a WIP, with more features coming soon! +::: + +Define runtime configuration in a single place, `/app.config.ts`: + +```ts +import { defineAppConfig } from 'wxt/sandbox'; + +// Define types for your config +declare module 'wxt/sandbox' { + export interface WxtAppConfig { + theme?: 'light' | 'dark'; + } +} + +export default defineAppConfig({ + theme: 'dark', +}); +``` + +:::warning +This file is commited to the repo, so don't put any secrets here. Instead, use [Environment Variables](#environment variables) +::: + +To access runtime config, WXT provides the `useAppConfig` function: + +```ts +import { useAppConfig } from 'wxt/sandbox'; + +console.log(useAppConfig()); // { theme: "dark" } +``` + +## Environment Variables + +WXT supports environment variables through [Vite](https://vitejs.dev/guide/env-and-mode.html#env-variables). You can create `.env` and `.env.*` files just like you would with Vite: + +``` +VITE_API_KEY=... +``` + +Then access them at runtime via `import.meta.env`: + +```ts +await fetch(`/some-api?apiKey=${import.meta.env.VITE_API_KEY}`); +``` + +### `app.config.ts` Integration + +You can use them in the `app.config.ts` file. + +```ts +declare module 'wxt/sandbox' { + export interface WxtAppConfig { + apiKey?: string; + skipTutorial: boolean; + } +} + +export default defineAppConfig({ + apiKey: import.meta.env.VITE_API_KEY, + skipTutorial: import.meta.env.VITE_SKIP_WELCOME === 'true', +}); +``` + +This has several advantages: + +- Define what environment variables are use at runtime in a single file +- Convert strings to nicer type, like booleans or arrays +- Provide default values if an environment variable is not provided diff --git a/docs/guide/essentials/config/typescript.md b/docs/guide/essentials/config/typescript.md new file mode 100644 index 000000000..3e1b111ac --- /dev/null +++ b/docs/guide/essentials/config/typescript.md @@ -0,0 +1,40 @@ +# TypeScript Configuration + +When you run [`wxt prepare`](/api/cli/wxt-prepare), WXT generates a base TSConfig file for your project at `/.wxt/tsconfig.json`. + +At a minimum, you need to create a TSConfig in your root directory that looks like this: + +```jsonc +// /tsconfig.json +{ + "extends": ".wxt/tsconfig.json", +} +``` + +Additionally, if you need to specify custom compiler options, you should add them in `/tsconfig.json`, NOT `/.wxt/tsconfig.json`. + +```jsonc +// /tsconfig.json +{ + "extends": ".wxt/tsconfig.json", + "compilerOptions": { + "jsx": "perserve", + }, +} +``` + +## TSConfig Paths + +`/.wxt/tsconfig.json` includes a default set of path aliases. To add your own, DO NOT add them to either `tsconfig.json` by hand. + +Instead, use the [`alias` config](/api/reference/wxt/interfaces/InlineConfig#alias) in `wxt.config.ts`. This will add your custom aliases to the generated `/.wxt/tsconfig.json` file next time you run `wxt prepare`. + +```ts +import { resolve } from 'node:path'; + +export default defineConfig({ + alias: { + testing: resolve('utils/testing'), + }, +}); +``` diff --git a/docs/guide/essentials/config/vite.md b/docs/guide/essentials/config/vite.md new file mode 100644 index 000000000..fbd80fd5d --- /dev/null +++ b/docs/guide/essentials/config/vite.md @@ -0,0 +1,82 @@ +# Vite + +WXT uses [Vite](https://vitejs.dev/) under the hood to bundle your extension. As such, all of [Vite's features](https://vitejs.dev/guide/features.html) are available when using WXT. + +WXT orchastrates several different Vite builds to bundle your extension. For more info, read [How WXT Works](/guide/resources/how-wxt-works). + +## Change Vite Config + +You can change Vite's config via the `wxt.config.ts` file: + +```ts +// wxt.config.ts +export default defineConfig({ + vite: () => ({ + // Override config here, same as `defineConfig({ ... })` + // inside vite.config.ts files + }), +}); +``` + +## Add Vite Plugins + +To add a plugin, install it and add it to the config: + +```ts +// wxt.config.ts +export default defineConfig({ + vite: () => ({ + plugins: [ + // ... + ], + }), +}); +``` + +:::warning +Due to the way WXT orchestrates Vite builds, some plugins may not work as expected. Search [GitHub issues](https://github.com/wxt-dev/wxt/issues?q=is%3Aissue+label%3A%22vite+plugin%22) if you run into issues with a specific plugin. + +If an issue doesn't exist for your plugin, please [open a new one](https://github.com/wxt-dev/wxt/issues/new/choose)! +::: + +## Importing Assets + +WXT supports the same 2 ways of importing assets as Vite: + +1. `assets/` directory + :::code-group + + ```ts [JS] + import imageUrl from '~/assets/image.png'; + + const img = document.createElement('img'); + img.src = imageUrl; + ``` + + ```html [HTML] + + ``` + + ```css [CSS] + .bg-image { + background-image: url(~/assets/image.png); + } + ``` + + ::: + +2. `public/` directory + :::code-group + ```ts [JS] + const img = document.createElement('img'); + img.src = '/image.png'; + ``` + ```html [HTML] + + ``` + ```css [CSS] + .bg-image { + background-image: url(/image.png); + } + ``` + ::: diff --git a/docs/guide/essentials/config/wxt.md b/docs/guide/essentials/config/wxt.md new file mode 100644 index 000000000..c3b732032 --- /dev/null +++ b/docs/guide/essentials/config/wxt.md @@ -0,0 +1,172 @@ +--- +outline: deep +--- + +# wxt.config.ts + +> See the [API Reference](/api/reference/wxt/interfaces/InlineConfig) for all options. This page only discusses the setup and a few features. + +The `wxt.config.ts` file contains the main build configuration for your project. Here's what it looks like: + +```ts +import { defineConfig } from 'wxt'; + +export default defineConfig({ + // Config goes here +}); +``` + +## Directories + +You can configure the following directories: + + +```ts +export default defineConfig({ + // Relative to project root + srcDir: "src", // default: "." + outDir: "dist", // default: ".output" + + // Relative to srcDir + entrypointsDir: "entries", // default: "entrtypoints" + modulesDir: "wxt-modules", // default: "modules" + publicDir: "static", // default: "public" +}) +``` + +You can use absolute or relative paths. + +## Auto-imports + +WXT uses [`unimport`](https://www.npmjs.com/package/unimport), the same tool as Nuxt, to setup auto-imports. + +```ts +export default defineConfig({ + // See https://www.npmjs.com/package/unimport#configurations + imports: { + // ... + }, +}); +``` + +By default, WXT automatically setups up auto-imports for all of it's own APIs: + +- [`browser`](/api/reference/wxt/browser/variables/browser) from `wxt/browser`, a small wrapper around `webextension-polyfill` +- [`defineContentScript`](/api/reference/wxt/sandbox/functions/defineContentScript) from `wxt/sandbox` +- [`defineBackground`](/api/reference/wxt/sandbox/functions/defineBackground) from `wxt/sandbox` +- [`defineUnlistedScript`](/api/reference/wxt/sandbox/functions/defineUnlistedScript) from `wxt/sandbox` +- [`createIntegratedUi`](/api/reference/wxt/client/functions/createIntegratedUi) from `wxt/client` +- [`createShadowRootUi`](/api/reference/wxt/client/functions/createShadowRootUi) from `wxt/client` +- [`createIframeUi`](/api/reference/wxt/client/functions/createIframeUi) from `wxt/client` +- [`fakeBrowser`](/api/reference/wxt/testing/variables/fakeBrowser) from `wxt/testing` +- And more! + +WXT also adds some project directories as auto-import sources automatically: + +- `/components/*` +- `/composables/*` +- `/hooks/*` +- `/utils/*` + +All named and default exports from files in these directories are available anywhere else in your project without having to import them. + +### TypeScript + +For TypeScript and your editor to recognize auto-imported variables, you need to run the [`wxt prepare` command](/api/cli/wxt-prepare). + +Add this command to your `postinstall` script so your editor has everything it needs to report type errors after installing dependencies: + +```jsonc +// package.json +{ + "scripts": { + "postinstall": "wxt prepare", // [!code ++] + }, +} +``` + +### ESLint + +ESLint doesn't know about the auto-imported variables unless they are explicitly defined in the ESLint's `globals`. By default, WXT will generate the config if it detects ESLint is installed in your project. If the config isn't generated automatically, you can manually tell WXT to generate it. + +:::code-group + +```ts [ESLint 9] +export default defineConfig({ + imports: { + eslintrc: { + enabled: 9, + }, + }, +}); +``` + +```ts [ESLint 8] +export default defineConfig({ + imports: { + eslintrc: { + enabled: 8, + }, + }, +}); +``` + +::: + +Then in your ESLint config, import and use the generated file: + +:::code-group + +```js [ESLint 9] +// eslint.config.mjs +import autoImports from './.wxt/eslint-auto-imports.mjs'; + +export default [ + autoImports, + { + // The rest of your config... + }, +]; +``` + +```js [ESLint 8] +// .eslintrc.mjs +export default { + extends: ['./.wxt/eslintrc-auto-import.json'], + // The rest of your config... +}; +``` + +::: + +### Disabling Auto-imports + +Not all developers like auto-imports. To disable them, set `imports` to `false`. + +```ts +export default defineConfig({ + imports: false, // [!code ++] +}); +``` + +## Hooks + +WXT includes an in-depth system that let's you hook into the build process and make changes. + +Here's an example hook that modifies the `manifest.json` file before it is written to the output directory: + +```ts +export default defineConfig({ + hooks: { + 'build:manifestGenerated': (wxt, manifest) => { + if (wxt.config.mode === 'development') { + manifest.title += ' (DEV)'; + } + }, + }, +}); +``` + +> Most hooks provide the `wxt` object as the first argument. If contains the resolved config and other info about the current build. + +Putting one-off hooks like this in your config file is simple, but if you find yourself writing lots of hooks, you should extract them into [WXT Modules](/guide/wxt-modules/writing-modules) instead. diff --git a/docs/guide/key-concepts/content-script-ui.md b/docs/guide/essentials/content-scripts.md similarity index 58% rename from docs/guide/key-concepts/content-script-ui.md rename to docs/guide/essentials/content-scripts.md index c75935ee6..91ebf5e64 100644 --- a/docs/guide/key-concepts/content-script-ui.md +++ b/docs/guide/essentials/content-scripts.md @@ -1,8 +1,104 @@ -# Content Script UI +--- +outline: deep +--- -There are three ways to mount a UI inside a content script: +# Content Scripts -[[toc]] +To add a content script, refer to [Entrypoint Types > Content Script](/guide/entrypoint-types/content-script). This page discusses the nuonces of writing content scripts with WXT. + +## Context + +The first argument to a content script's `main` function is it's "context". + +```ts +// entrypoints/content.ts +export default defineContentScript({ + main(ctx) {}, +}); +``` + +This object is responsible for tracking whether or not the content script's context is "invalidated". Most browsers, by default, do not stop content scripts if the extension is uninstalled, updated, or disabled. When this happens, content scripts start reproting this error: + +``` +Error: Extension context invalidated. +``` + +The `ctx` object provides several helpers to stop asynchronous code from running once the context is invalidated: + +```ts +ctx.addEventListener(...); +ctx.setTimeout(...); +ctx.setInterval(...); +ctx.requestAnimationFrame(...); +// and more +``` + +You can also check if the context is invalidated manually: + +```ts +if (ctx.isValid) { + // do something +} +// OR +if (ctx.isInvalid) { + // do something +} +``` + +## CSS + +In regular web extensions, CSS for content scripts is usually a separate CSS file, that is added to a CSS array in the manifest: + +```json +{ + "content_scripts": [ + { + "css": ["content/style.css"], + "js": ["content/index.js"], + "matches": ["*://*/*"] + } + ] +} +``` + +In WXT, to add CSS to a content script, simply import the CSS file into your JS entrypoint, and WXT will automatically add the bundled CSS output to the `css` array. + +```ts +// entrypoints/content/index.ts +import './style.css'; + +export default defineContentScript({ + // ... +}); +``` + +To create a standalone content script that only includes a CSS file: + +1. Create the CSS file: `entrypoints/example.content.css` +2. Use the `build:manfiestGenerated` hook to add the content script to the manifest: + ```ts + // wxt.config.ts + export default defineConfig({ + hooks: { + "build:manifestGenerated": (wxt, manifest) => { + manifest.content_scripts ??= []; + manifest.content_scripts.push({ + // Build extension once to see where your CSS get's written to + css: ["content-scripts/example.css"], + matches: ["*://*/*"] + ) + } + } + }) + ``` + +## UI + +WXT provides 3 built-in utilities for adding UIs to a page from a content script: + +- [Integrated](#integrated) - `createIntegratedUi` +- [Shadow Root](#shadow-root) -`createShadowRootUi` +- [IFrame](#iframe) - `createIframeUi` Each has their own set of advantages and disadvantages. @@ -12,7 +108,7 @@ Each has their own set of advantages and disadvantages. | Shadow Root | ✅ | ✅ (off by default) | ❌ | ✅ | | IFrame | ✅ | ✅ | ✅ | ❌ | -## Integrated +### Integrated Integrated content script UIs are injected alongside the content of a page. This means that they are affected by CSS on that page. @@ -26,6 +122,7 @@ export default defineContentScript({ main(ctx) { const ui = createIntegratedUi(ctx, { position: 'inline', + anchor: 'body', onMount: (container) => { // Append children to the container const app = document.createElement('p'); @@ -51,6 +148,7 @@ export default defineContentScript({ main(ctx) { const ui = createIntegratedUi(ctx, { position: 'inline', + anchor: 'body', onMount: (container) => { // Create the app and mount it to the UI container const app = createApp(App); @@ -80,6 +178,7 @@ export default defineContentScript({ main(ctx) { const ui = createIntegratedUi(ctx, { position: 'inline', + anchor: 'body', onMount: (container) => { // Create a root on the UI container and render a component const root = ReactDOM.createRoot(container); @@ -108,6 +207,7 @@ export default defineContentScript({ main(ctx) { const ui = createIntegratedUi(ctx, { position: 'inline', + anchor: 'body', onMount: (container) => { // Create the Svelte app inside the UI container const app = new App({ @@ -137,6 +237,7 @@ export default defineContentScript({ main(ctx) { const ui = createIntegratedUi(ctx, { position: 'inline', + anchor: 'body', onMount: (container) => { // Render your app to the UI container const unmount = render(() =>
...
, container); @@ -157,13 +258,11 @@ export default defineContentScript({ See the [API Reference](/api/reference/wxt/client/functions/createIntegratedUi) for the complete list of options. -You can control how CSS is injected for an integrated content script UI with the [`cssInjectionMode`](/api/reference/wxt/interfaces/BaseContentScriptEntrypointOptions#cssinjectionmode) property. Usually, you'll want to leave it as `"manifest"`, the default, so the UI inherits its style from the website's CSS. - -## Shadow Root +### Shadow Root Often in web extensions, you don't want your content script's CSS affecting the page, or vise-versa. The [`ShadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot) API is ideal for this. -WXT's [`createShadowRootUi`](/api/reference/wxt/client/functions/createShadowRootUi) abstracts all the `ShadowRoot` setup away, making it easy to create UIs with isolated CSS. It also supports an optional `isolateEvents` parameter to further isolate user interactions. +WXT's [`createShadowRootUi`](/api/reference/wxt/client/functions/createShadowRootUi) abstracts all the `ShadowRoot` setup away, making it easy to create UIs whose styles are isolated from the page. It also supports an optional `isolateEvents` parameter to further isolate user interactions. To use `createShadowRootUi`, follow these steps: @@ -188,6 +287,7 @@ export default defineContentScript({ const ui = await createShadowRootUi(ctx, { name: 'example-ui', position: 'inline', + anchor: 'body', onMount(container) { // Define how your UI will be mounted inside the container const app = document.createElement('p'); @@ -218,6 +318,7 @@ export default defineContentScript({ const ui = await createShadowRootUi(ctx, { name: 'example-ui', position: 'inline', + anchor: 'body', onMount: (container) => { // Define how your UI will be mounted inside the container const app = createApp(App); @@ -252,6 +353,7 @@ export default defineContentScript({ const ui = await createShadowRootUi(ctx, { name: 'example-ui', position: 'inline', + anchor: 'body', onMount: (container) => { // Container is a body, and React warns when creating a root on the body, so create a wrapper div const app = document.createElement('div'); @@ -289,6 +391,7 @@ export default defineContentScript({ const ui = await createShadowRootUi(ctx, { name: 'example-ui', position: 'inline', + anchor: 'body', onMount: (container) => { // Create the Svelte app inside the UI container const app = new App({ @@ -323,6 +426,7 @@ export default defineContentScript({ const ui = await createShadowRootUi(ctx, { name: 'example-ui', position: 'inline', + anchor: 'body', onMount: (container) => { // Render your app to the UI container const unmount = render(() =>
...
, container); @@ -343,11 +447,12 @@ export default defineContentScript({ See the [API Reference](/api/reference/wxt/client/functions/createShadowRootUi) for the complete list of options. -:::info TailwindCSS -`createShadowRootUi` supports TailwindCSS out of the box! When importing the styles, just import the main CSS file containing the `@tailwind` directives, and everything will just work :+1:. -::: +Full examples: -## IFrame +- [react-content-script-ui](https://github.com/wxt-dev/examples/tree/main/examples/react-content-script-ui) +- [tailwindcss](https://github.com/wxt-dev/examples/tree/main/examples/tailwindcss) + +### IFrame If you don't need to run your UI in the same frame as the content script, you can use an IFrame to host your UI instead. Since an IFrame just hosts an HTML page, **_HMR is supported_**. @@ -393,6 +498,7 @@ WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/client/fun const ui = createIframeUi(ctx, { page: '/example-iframe.html', position: 'inline', + anchor: 'body', onMount: (wrapper, iframe) => { // Add styles to the iframe like width iframe.width = '123'; @@ -406,3 +512,103 @@ WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/client/fun ``` See the [API Reference](/api/reference/wxt/client/functions/createIframeUi) for the complete list of options. + +## Isolated World vs Main World + +By default, all content scripts run in an isolated context where only the DOM is shared with the webpage it is running on - an "isolated world". In MV3, Chromium introduced the ability to run content scripts in the "main" world - where everything, not just the DOM, is available to the content script, just like if the script were loaded by the webpage. + +You can enable this for a content script by setting the `world` option: + +```ts +export default defineContentScript({ + world: 'MAIN', +}); +``` + +However, this approach has several notible drawbacks: + +- Doesn't support MV2 +- `world: "MAIN"` is only supported by Chromium browsers +- Main world content scripts don't have access to the extension API + +Instead, WXT recommends injecting a script into the main world manually using it's `injectScript` function. This will address the drawbacks mentioned before. + +- `injectScript` supports both MV2 and MV3 +- `injectScript` supports all browsers +- Having a "parent" content script means you can send messages back and forth, making it possible to access the extension API + +To use `injectScript`, we need two entrypoints, one content script and one unlisted script: + +```sh +📂 entrypoints/ + example.content.ts + example-main-world.ts +``` + +```ts +// entrypoints/example-main-world.ts +export default defineUnlistedScript(() => { + console.log('Hello from the main world!'); +}); +``` + +```ts +// entrypoints/example.content.ts +export default defineContentScript(async () => { + await injectScript('/example-main-world.js', { + keepInDom: true, + }); +}); +``` + +`injectScript` works by creating a `script` element on the page pointing to your script. This loads the script into the page's context so it runs in the main world. + +`injectScript` returns a promise, that when resolved, means the script has been evaluated by the browser and you can start communicating with it. + +:::warning Warning: `run_at` Caveots +For MV3, `injectScript` is synchronous and the injected script will be evaluated at the same time as your the content script's `run_at`. + +However for MV2, `injectScript` has to `fetch` the script's text content and create an inline ` - -``` - -## Background - -In your background script, set `type: "module"`: - -```ts -export default defineBackground({ - type: 'module', // !code ++ - main() { - // ... - }, -}); -``` - -:::warning -Only MV3 support ESM background scripts/service workers. When targeting MV2, the `type` option is ignored and the background is always bundled into a single file as IIFE. -::: - -## Content Scripts - -WXT does not include built-in support for ESM content scripts. There are several technical issues that make implementing a generic solution impossible. See [Content Script ESM Support #357](https://github.com/wxt-dev/wxt/issues/357) for details. - -Instead, depending on your requirements, you can implement ESM support manually. See the [ESM Content Script UI](https://github.com/wxt-dev/examples/tree/main/examples/esm-content-script-ui) example to get started. diff --git a/docs/guide/go-further/handling-updates.md b/docs/guide/go-further/handling-updates.md deleted file mode 100644 index 4564ac747..000000000 --- a/docs/guide/go-further/handling-updates.md +++ /dev/null @@ -1,76 +0,0 @@ -# Handling Extension Updates - -When releasing an update to your extension, there's a couple of things you need to keep in mind: - -[[toc]] - -## Content Script Cleanup - -Old content scripts are not automatically stopped when an extension updates and reloads. Often, this leads to "Invalidated context" errors in production when a content script from an old version of your extension tries to use an extension API. - -WXT provides a utility for handling this process: `ContentScriptContext`. An instance of this class is provided to you automatically inside the `main` function of each content script. - -When your extension updates or reloads, the context will become invalidated, and will trigger any `ctx.onInvalidated` listeners you add: - -```ts -export default defineContentScript({ - main(ctx) { - ctx.onInvalidated(() => { - // Do something - }); - }, -) -``` - -The `ctx` also provides other convenient APIs for stopping your content script without manually calling `onInvalidated` to add a listener: - -1. Setting timers: - ```ts - ctx.setTimeout(() => { ... }, ...); - ctx.setInterval(() => { ... }, ...); - ctx.requestAnimationFrame(() => { ... }); - ``` -1. Adding DOM events: - ```ts - ctx.addEventListener(window, "mousemove", (event) => { ... }); - ``` -1. Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) for canceling standard APIs: - ```ts - fetch('...', { - signal: ctx.signal, - }); - ``` - -Other WXT APIs require a `ctx` object so they can clean themselves up. For example, [`createIntegratedUi`](/guide/key-concepts/content-script-ui#integrated), [`createShadowRootUi`](/guide/key-concepts/content-script-ui#shadow-root), and [`createIframeUi`](/guide/key-concepts/content-script-ui#iframe) automatically unmount and stop a UI when the script is invalidated. - -:::warning -When working with content scripts, **you should always use the `ctx` object to stop any async or future work.** - -This prevents old content scripts from interfering with new content scripts, and prevents error messages from being logged to the console in production. -::: - -## Testing Permission Changes - -When `permissions`/`host_permissions` change during an update, depending on what exactly changed, the browser will disable your extension until the user accepts the new permissions. - -You can test if your permission changes will result in a disabled extension: - -- Chromium: Use [Google's Extension Update Testing tool](https://github.com/GoogleChromeLabs/extension-update-testing-tool) -- Firefox/Safari: Everyone breaks something in production eventually... 🫡 Good luck soldier - -## Update Event - -You can setup a callback that runs after your extension updates like so: - -```ts -browser.runtime.onInstalled.addListener(({ reason }) => { - if (reason === 'update') { - // Do something - } -}); -``` - -If the logic is simple, write a unit test to cover this logic. If you feel the need to manually test this callback, you can either: - -1. In dev mode, remove the `if` statement and reload the extension from `chrome://extensions` -2. Use [Google's Extension Update Testing tool](https://github.com/GoogleChromeLabs/extension-update-testing-tool) diff --git a/docs/guide/go-further/reusable-modules.md b/docs/guide/go-further/reusable-modules.md deleted file mode 100644 index 1c9513c36..000000000 --- a/docs/guide/go-further/reusable-modules.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -outline: deep ---- - -# Reusable Modules - -## Overview - -WXT provides a "module" API that lets you modify the build process. This API lets you add entrypoints, inject runtime code, add vite plugins, and more! - -What's more, these modules can be shared on NPM and re-used between projects! - -## Adding a Module - -There are two ways to add a module to your project: - -1. **Local file**: Any file present in the `modules/` directory will be treated as a module and loaded at build-time by WXT. You can use `modules/*.ts` or `modules/*/index.ts`, similar to entrypoints. - - ```ts - // modules/example.ts - import { defineWxtModule } from 'wxt/modules'; - - export default defineWxtModule((wxt) => { - // ... - }); - ``` - -2. **NPM package**: Find WXT modules on NPM and include them in your project: - ```ts - // wxt.config.ts - export default defineConfig({ - // Add the module to your project - modules: ['@wxt-dev/auto-icons'], - }); - ``` - -## Writing Modules - -Modules contain a setup function that is executed at the beginning of the build process. - -:::code-group - -```ts [Function Definition] -import { defineWxtModule } from 'wxt/modules'; - -export default defineWxtModule((wxt) => { - // ... -}); -``` - -```ts [Object Definition] -import { defineWxtModule } from 'wxt/modules'; - -export default defineWxtModule({ - // Add metadata... - setup(wxt) { - // ... - }, -}); -``` - -::: - -### Module Options - -You can define custom options for your module by setting the `configKey`: - -```ts -// modules/analytics.ts -import { defineWxtModule } from 'wxt/modules'; - -export default defineWxtModule({ - configKey: 'analytics', - setup(wxt, options) { - console.log(options); // { clientId: "..." } - }, -}); - -// Define the option types -export interface AnalyticsModuleOptions { - clientId: string; -} - -// Use "module augmentation" to add types for the new key -declare module 'wxt' { - export interface InlineConfig { - analytics: AnalyticsModuleOptions; - } -} -``` - -Now, when the user provides options to the `analytics` key in their `wxt.config.ts`, those options are passed into the setup function as the second argument. - -```ts -export default defineConfig({ - analytics: { clientId: '...' }, -}); -``` - -### Actually Doing Something - -The first argument of the setup function, `wxt`, provides full access to the current build's context. You can access the resolved configuration via `wxt.config`, or setup hooks to manipulate the build at different steps of the build process with `wxt.hooks`. - -Here's an example that updates the `outDir` based on the build mode. It's a very simple example of how to access config and setup a hook. - -```ts -export default defineWxtModule((wxt) => { - if (wxt.config.mode === 'development') { - // Use the "ready" hook to update wxt.config - wxt.hooks.hook('ready', (wxt) => { - wxt.config.outDir = wxt.config.outDir.replace('.output', '.output/dev'); - }); - } -}); -``` - -:::info Async Modules -Both the `setup` function and hook callbacks can be async. Don't forget to add `await`! -::: - -It's important to understand the basics of how hooks work. Make sure to read the [API reference](/api/reference/wxt/interfaces/WxtHooks.html) for the full list of hooks and what they should be used for. They are the key to modifying your extension. - -### Module Utils - -Additionally, WXT provides several helper functions that setup hooks behind the scenes to streamline common operations. - -For example, if you want to include an entrypoint from inside a module, you can use the `addEntrypoint` util: - -```ts -// modules/changelog.ts -import { defineWxtModule, addEntrypoint } from 'wxt/modules'; -import { resolve } from 'node:path'; - -export default defineWxtModule({ - name: 'changelog', - setup(wxt) { - addEntrypoint(wxt, { - type: 'unlisted-page', - name: 'changelog', - // Point to the "modules/changelog.html" file - inputPath: resolve(__dirname, 'changelog.html'), - outputDir: wxt.config.outputDir, - options: {}, - }); - }, -}); -``` - -Refer to the [API reference](/api/reference/wxt/modules/#functions) for the full list of the utilities. - -## Plugins - -Whereas modules are executed at build-time, plugins are executed at runtime. As of now, the only way to add a plugin is with the `addWxtPlugin` helper inside a module. - -Here's a minimal example to execute something at runtime. - -:::code-group - -```ts [modules/example/index.ts] -import { defineWxtModule, addWxtPlugin } from 'wxt/modules'; -import { resolve } from 'node:path'; - -export default defineWxtModule((wxt) => { - addWxtPlugin(wxt, resolve(__dirname, 'plugin.ts')); -}); -``` - -```ts [modules/example/plugin.ts] -import { defineWxtPlugin } from 'wxt/sandbox'; - -export default defineWxtPlugin(() => { - console.log('Executing plugin!'); -}); -``` - -::: - -:::warning Async Plugins -Unlike modules, **_plugins cannot be async_**!! If you need to do some async work and expose that result to the rest of the extension, store the result's promise synchronously and await it later on. -::: - -## Publishing to NPM - -:::warning 🚧 Under construction -These docs will be coming soon! -::: diff --git a/docs/guide/go-further/testing.md b/docs/guide/go-further/testing.md deleted file mode 100644 index 8c5f23005..000000000 --- a/docs/guide/go-further/testing.md +++ /dev/null @@ -1,27 +0,0 @@ -# Testing - -## Official Frameworks - -WXT officially supports [Vitest](https://vitest.dev/) for unit tests and either [Playwright](https://playwright.dev/) or [Puppeteer](https://pptr.dev/) for E2E tests against Chromium browsers. - -For details setting up each testing framework, see the official examples: - -- [Vitest](https://github.com/wxt-dev/wxt-examples/tree/main/examples/vanilla-vitest#readme) -- [Playwright](https://github.com/wxt-dev/wxt-examples/tree/main/examples/vanilla-playwright#readme) -- [Puppeteer](https://github.com/wxt-dev/wxt-examples/tree/main/examples/vanilla-puppeteer#readme) - -### Unofficial Frameworks - -Puppeteer and Playwright are the only E2E test runners that support Chrome Extensions. There are no other options at the time of writing. - -There are other options for unit tests however, like [Jest](https://jestjs.io/), [Mocha](https://mochajs.org/), or [`node:test`](https://nodejs.org/api/test.html). **_WXT does not claim to support any of them_** because none of them support all of WXT's features, like TypeScript or auto-imports. - -If you want to try to use a different framework for unit tests, you will need to configure the environment manually: - -- **Auto-imports**: Add `unimport` to your test environment or disable them by setting `imports: false` in your `wxt.config.ts` file -- **`browser` mock**: Mock the `webextension-polyfill` module globally with `wxt/dist/virtual/mock-browser.mjs` -- **[Remote Code Bundling](/guide/go-further/remote-code)**: If you use it, configure your environment to handle the `url:` module prefix -- **Global Variables**: If you consume them, manually define globals provided by WXT (like `import.meta.env.BROWSER`) by adding them to the global scope before accessing them (`import.meta.env.BROWSER = "chrome"`) -- **Import paths**: If you use the `@/` or `~/` path aliases, add them to your test environment - -[Here's how Vitest is configured](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts) for reference. diff --git a/docs/guide/go-further/vite.md b/docs/guide/go-further/vite.md deleted file mode 100644 index 98e67d108..000000000 --- a/docs/guide/go-further/vite.md +++ /dev/null @@ -1,39 +0,0 @@ -# Vite - -Under the hood, WXT uses Vite to bundle your web extension. - -## Basic Vite Configuration - -All of Vite's config can be customized by setting the `vite` configuration in your `wxt.config.ts` file. - -```ts -import { defineConfig } from 'wxt'; - -export default defineConfig({ - vite: () => ({ - // Same as `defineConfig({ ... })` inside vite.config.ts - }), -}); -``` - -## Using Plugins - -Plugins can be passed into the `vite` configuration in your `wxt.config.ts` file, just like any other option. - -```ts -import { defineConfig } from 'wxt'; - -export default defineConfig({ - vite: () => ({ - plugins: [ - // ... - ], - }), -}); -``` - -:::warning UNEXPECTED BEHAVIOR -Due to the way WXT orchestrates Vite builds, some plugins may not work as expected. Search [GitHub issues](https://github.com/wxt-dev/wxt/issues?q=is%3Aissue+label%3A%22vite+plugin%22) if you run into issues with a specific plugin. - -If one doesn't exist, please open a [new issue](https://github.com/wxt-dev/wxt/issues/new/choose)! -::: diff --git a/docs/guide/i18n/build-integrations.md b/docs/guide/i18n/build-integrations.md deleted file mode 100644 index 0dd9aba21..000000000 --- a/docs/guide/i18n/build-integrations.md +++ /dev/null @@ -1,82 +0,0 @@ -# Build Integrations - -To use the custom messages file format, you'll need to use `@wxt-dev/i18n/build` to transform the custom format to the one expected by browsers. - -Here's a list of build tools that already have an integration: - -[[toc]] - -:::info -If you want to contribute, please do! In particular, an `unplugin` integration would be awesome! -::: - -## WXT - -See [Installation with WXT](./installation#with-wxt). - -But TLDR, all you need is: - -```ts -// wxt.config.ts -export default defineConfig({ - modules: ['@wxt-dev/i18n/module'], -}); -``` - -Types are generated whenever you run `wxt prepare` or another build command: - -```sh -wxt prepare -wxt -wxt build -wxt zip -# etc -``` - -## Custom - -If you're not using WXT, you'll have to pre-process the localization files yourself. Here's a basic script to generate the `_locales/.../messages.json` and `wxt-i18n-structure.d.ts` files: - -```ts -// build-i18n.js -import { - parseMessagesFile, - generateChromeMessagesFile, - generateTypeFile, -} from '@wxt-dev/i18n/build'; - -// Read your localization files -const messages = { - en: await parseMessagesFile('path/locales/en.yml'), - de: await parseMessagesFile('path/locales/de.yml'), - // ... -}; - -// Generate JSON files for the browser -await generateChromeMessagesFile('dist/_locales/en/messages.json', messages.en); -await generateChromeMessagesFile('dist/_locales/de/messages.json', messages.de); -// ... - -// Generate a types file based on your default_locale -await generateTypeFile('wxt-i18n-structure.d.ts', messages.en); -``` - -Then run the script: - -```sh -node generate-i18n.js -``` - -If your build tool has a dev mode, you'll also want to rerun the script whenever you change a localization file. - -### Type Safety - -Once you've generated `wxt-i18n-structure.d.ts` (see the [Custom](#custom) section), you can use it to pass the generated type into `createI18n`: - -```ts -import type { WxtI18nStructure } from './wxt-i18n-structure'; - -export const i18n = createI18n(); -``` - -And just like that, you have type safety! diff --git a/docs/guide/i18n/editor-support.md b/docs/guide/i18n/editor-support.md deleted file mode 100644 index 704ab104b..000000000 --- a/docs/guide/i18n/editor-support.md +++ /dev/null @@ -1,48 +0,0 @@ -# Editor Support - -For better DX, you can configure your editor with plugins and extensions. - -[[toc]] - -## VS Code - -Install the [I18n Ally Extension](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally) to: - -- Go to translation definition -- Inline previews of text -- Hover to see other translations - -You'll need to configure it the extension so it knows where your localization files are and what function represents getting a translation: - -`.vscode/i18n-ally-custom-framework.yml`: - -```yml -# An array of strings which contain Language Ids defined by VS Code -# You can check available language ids here: https://code.visualstudio.com/docs/languages/identifiers -languageIds: - - typescript - -# Look for t("...") -usageMatchRegex: - - "[^\\w\\d]t\\(['\"`]({key})['\"`]" - -# Disable other built-in i18n ally frameworks -monopoly: true -``` - -`.vscode/settings.json`: - -```json -{ - "i18n-ally.localesPaths": ["src/locales"], - "i18n-ally.keystyle": "nested" -} -``` - -## Zed - -As of time of writing, Aug 18, 2024, no extensions exist for Zed to add I18n support. - -## IntelliJ - -Unknown - Someone who uses IntelliJ will have to open a PR for this! diff --git a/docs/guide/i18n/installation.md b/docs/guide/i18n/installation.md deleted file mode 100644 index f1779ffde..000000000 --- a/docs/guide/i18n/installation.md +++ /dev/null @@ -1,81 +0,0 @@ -# Installation - -[[toc]] - -### With WXT - -1. Install `@wxt-dev/i18n` via your package manager: - - ```sh - pnpm i @wxt-dev/i18n - ``` - -2. Add the WXT module to your `wxt.config.ts` file and setup a default locale: - - ```ts - export default defineConfig({ - modules: ['@wxt-dev/i18n/module'], - manifest: { - default_locale: 'en', - }, - }); - ``` - -3. Create a localization file at `/locales/.yml` or move your existing localization files there. - - ```yml - # /locales/en.yml - helloWorld: Hello world! - ``` - - :::tip - `@wxt-dev/i18n` supports the standard messages format, so if you already have localization files at `/public/_locale//messages.json`, you don't need to convert them to YAML or refactor them - just move them to `/locales/.json` and they'll just work out of the box! - ::: - -4. To get a translation, use the auto-imported `i18n` object or import it manually: - - ```ts - import { i18n } from '#i18n'; - - i18n.t('helloWorld'); // "Hello world!" - ``` - -And you're done! Using WXT, you get type-safety out of the box. - -### Without WXT - -1. Install `@wxt-dev/i18n` via your package manager: - - ```sh - pnpm i @wxt-dev/i18n - ``` - -2. Create a messages file at `_locales//messages.json` or move your existing translations there: - - ```json - { - "helloWorld": { - "message": "Hello world!" - } - } - ``` - - :::info - For the best DX, you should to integrate `@wxt-dev/i18n` into your build process. This enables: - - 1. Plural forms - 2. Simple messages file format - 3. Type safety - - See [Build Integrations](./build-integrations) to set it up. - ::: - -3. Create the `i18n` object, export it, and use it wherever you want! - - ```ts - import { createI18n } from '@wxt-dev/i18n'; - - export const i18n = createI18n(); - - i18n.t('helloWorld'); // "Hello world!"; - ``` diff --git a/docs/guide/i18n/introduction.md b/docs/guide/i18n/introduction.md deleted file mode 100644 index 37404dda8..000000000 --- a/docs/guide/i18n/introduction.md +++ /dev/null @@ -1,22 +0,0 @@ -# Introduction - -:::info -You don't have to use `wxt` to use this package - it will work in any bundler setup. See [Installation without WXT](./installation#without-wxt) for more details. -::: - -`@wxt-dev/i18n` is a simple, type-safe wrapper around the `browser.i18n` APIs. It provides several benefits over the standard API: - -1. Simple messages file format -2. Plural form support -3. Integrates with the [I18n Ally VS Code extension](./editor-support#vscode) - -It also provides several benefits over other non-web extension specific i18n packages: - -1. Does not bundle localization files into every entrypoint -2. Don't need to fetch the localization files asynchronously -3. Can localize extension name in manifest -4. Can access localized strings inside CSS files - -However, it does have one major downside: - -1. Like the `browser.i18n` API, to change the language, users must change the browser's language diff --git a/docs/guide/i18n/messages-file-format.md b/docs/guide/i18n/messages-file-format.md deleted file mode 100644 index f6e699d94..000000000 --- a/docs/guide/i18n/messages-file-format.md +++ /dev/null @@ -1,170 +0,0 @@ -# Messages File Format - -You can only use the file format discussed on this page if you have [integrated `@wxt-dev/i18n` into your build process](./build-integrations). If you have not integrated it into your build process, you must use JSON files in the `_locales` directory, like a normal web extension. - -[[toc]] - -## File Extensions - -You can define your messages in several different file types: - -- `.yml` -- `.yaml` -- `.json` -- `.jsonc` -- `.json5` -- `.toml` - -## Nested Keys - -You can have translations at the top level or nest them into groups: - -```yml -ok: OK -cancel: Cancel -welcome: - title: Welcome to XYZ -dialogs: - confirmation: - title: 'Are you sure?' -``` - -To access a nested key, use `.`: - -```ts -i18n.t('ok'); // "OK" -i18n.t('cancel'); // "Cancel" -i18n.t('welcome.title'); // "Welcome to XYZ" -i18n.t('dialogs.confirmation.title'); // "Are you sure?" -``` - -## Substitutions - -Because `@wxt-dev/i18n` is based on `browser.i18n`, you define substitutions the same way, with `$1`-`$9`: - -```yml -hello: Hello $1! -order: Thanks for ordering your $1 -``` - -### Escapting `$` - -To escape the dollar sign, put another `$` in front of it: - -```yml -dollars: $$$1 -``` - -```ts -i18n.t('dollars', ['1.00']); // "$1.00" -``` - -## Plural Forms - -:::warning -Plural support languages like Arabic, that have different forms for "few" or "many", is not supported right now. Feel free to open a PR if you are interested in this! -::: - -To get a different translation based on a count: - -```yml -items: - 1: 1 item - n: $1 items -``` - -Then you pass in the count as the second argument to `i18n.t`: - -```ts -i18n.t('items', 0); // "0 items" -i18n.t('items', 1); // "1 item" -i18n.t('items', 2); // "2 items" -``` - -To add a custom translation for 0 items: - -```yml -items: - 0: No items - 1: 1 item - n: $1 items -``` - -```ts -i18n.t('items', 0); // "No items" -i18n.t('items', 1); // "1 item" -i18n.t('items', 2); // "2 items" -``` - -If you need to pass a custom substitution for `$1` instead of the count, just add the substitution: - -```yml -items: - 0: No items - 1: $1 item - n: $1 items -``` - -```ts -i18n.t('items', 0, ['Zero']); // "No items" -i18n.t('items', 1, ['One']); // "One item" -i18n.t('items', 2, ['Multiple']); // "Multiple items" -``` - -## Verbose Keys - -`@wxt-dev/i18n` is compatible with the message format used by [`browser.i18n`](https://developer.chrome.com/docs/extensions/reference/api/i18n). - -:::info -This means if you're migrating to `@wxt-dev/i18n` and you're already using the verbose format, you don't have to change anything! -::: - -A key is treated as "verbose" when it is: - -1. At the top level (not nested) -2. Only contains the following properties: `message`, `description` and/or `placeholder` - -:::code-group - -```json [JSON] -{ - "appName": { - "message": "GitHub - Better Line Counts", - "description": "The app's name, should not be translated", - }, - "ok": "OK", - "deleteConfirmation": { - "title": "Delete XYZ?" - "message": "You cannot undo this action once taken." - } -} -``` - -```yml [YAML] -appName: - message: GitHub - Better Line Counts - description: The app's name, should not be translated -ok: OK -deleteConfirmation: - title: Delete XYZ? - message: You cannot undo this action once taken. -``` - -::: - -In this example, only `appName` is considered verbose. `deleteConfirmation` is not verbose because it contains the additional property `title`. - -```ts -i18n.t('appName'); // ✅ "GitHub - Better Line Counts" -i18n.t('appName.message'); // ❌ -i18n.t('ok'); // ✅ "OK" -i18n.t('deleteConfirmation'); // ❌ -i18n.t('deleteConfirmation.title'); // ✅ "Delete XYZ?" -i18n.t('deleteConfirmation.message'); // ✅ "You cannot undo this action once taken." -``` - -If this is confusing, don't worry! With type-safety, you'll get a type error if you do it wrong. If type-safety is disabled, you'll get a runtime warning in the devtools console. - -:::warning -Using the verbose format is not recommended. I have yet to see a translation service and software that supports this format out of the box. Stick with the simple format when you can. -::: diff --git a/docs/guide/key-concepts/auto-imports.md b/docs/guide/key-concepts/auto-imports.md deleted file mode 100644 index ac3b699db..000000000 --- a/docs/guide/key-concepts/auto-imports.md +++ /dev/null @@ -1,117 +0,0 @@ -# Auto-imports - -WXT uses the same tool as Nuxt for auto-imports, [`unimport`](https://github.com/unjs/unimport). - -## WXT Auto-imports - -Some WXT APIs can be used without importing them: - -- [`browser`](/api/reference/wxt/browser/variables/browser) from `wxt/browser`, a small wrapper around `webextension-polyfill` -- [`defineContentScript`](/api/reference/wxt/sandbox/functions/defineContentScript) from `wxt/sandbox` -- [`defineBackground`](/api/reference/wxt/sandbox/functions/defineBackground) from `wxt/sandbox` -- [`defineUnlistedScript`](/api/reference/wxt/sandbox/functions/defineUnlistedScript) from `wxt/sandbox` -- [`createIntegratedUi`](/api/reference/wxt/client/functions/createIntegratedUi) from `wxt/client` -- [`createShadowRootUi`](/api/reference/wxt/client/functions/createShadowRootUi) from `wxt/client` -- [`createIframeUi`](/api/reference/wxt/client/functions/createIframeUi) from `wxt/client` -- [`fakeBrowser`](/api/reference/wxt/testing/variables/fakeBrowser) from `wxt/testing` - -And more! - -## Project Auto-imports - -In addition WXT APIs, default and named exports from inside the following directories can be used without listing them in imports. - -- `/components/*` -- `/composables/*` -- `/hooks/*` -- `/utils/*` - -To add auto-imports from subdirectories, like `utils/api/some-file.ts`, re-export them from the base directory: - -```ts -// utils/index.ts -export * from './api/some-file.ts'; -``` - -Alternatively, you could add the directory to the list of auto-import directories in your config file. - -## TypeScript - -For TypeScript to work, you need to run the `wxt prepare` command. This will ensure types are generated for auto-imports. - -This should be added to your `postinstall` script so your editor has everything it needs to report type errors after installing dependencies: - -```json -// package.json -{ - "scripts": { - "postinstall": "wxt prepare" // [!code ++] - } -} -``` - -## Customization - -You can override the default auto-import behavior in your `wxt.config.ts` file. - -See [`unimport`'s documentation](https://github.com/unjs/unimport#configurations) for a complete list of options. - -```ts -import { defineConfig } from 'wxt'; - -export default defineConfig({ - imports: { - // Add auto-imports for vue functions like createApp, ref, computed, watch, toRaw, etc... - presets: ['vue'], - }, -}); -``` - -## Disabling Auto-imports - -To disable auto-imports, set `imports: false` - -```ts -export default defineConfig({ - imports: false, -}); -``` - -## ESLint - -ESLint doesn't know about the auto-imported variables unless they are explicitly defined in the `globals` config. By default, WXT will generate the config if it detects ESLint is installed in your project. If the config isn't generated automatically, you can manually tell WXT to generate it. - -```ts -// wxt.config.ts -export default defineConfig({ - imports: { - eslintrc: { - enabled: 8, // Generate ESLint v8 compatible config - // or - enabled: 9, // Generate ESLint v9 compatible config - }, - }, -}); -``` - -### ESLint 9 and above - -WXT supports the "flat config" file format introduced in ESLint 9. Just import the generated file and add it to the array of config to extend. - -```js -// eslint.config.mjs -import autoImports from './.wxt/eslint-auto-imports.mjs'; - -export default [autoImports]; -``` - -### ESLint 8 and below - -Just extend the generated file: - -```js -// .eslintrc.mjs -export default { - extends: ['./.wxt/eslintrc-auto-import.json'], -}; -``` diff --git a/docs/guide/key-concepts/manifest.md b/docs/guide/key-concepts/manifest.md deleted file mode 100644 index 6ee21f6fd..000000000 --- a/docs/guide/key-concepts/manifest.md +++ /dev/null @@ -1,249 +0,0 @@ -# Manifest - -## Overview - -Sometimes, you'll need to make manual changes to how the `manifest.json` is generated. You can do this by using the `manifest` configuration: - -```ts -// wxt.config.ts -export default defineConfig({ - manifest: { - // Put manual changes here - }, -}); -``` - -## Manifest Version Compatibility - -When defining options in the manifest, always define them for MV3 when possible. WXT will either convert them to their MV2 equivalents or remove them from the generated manifest if there is not MV2 equivalent. - -So for fields like `web_accessible_resources` or `content_security_policy`, you just need to list them in their MV3 forms. Other fields, like `side_panel`, which doesn't exist in MV2, will be removed automatically. - -Here's an example `wxt.config.ts` file: - -```ts -import { defineConfig } from 'wxt'; - -export default defineConfig({ - manifest: { - action: { - default_title: 'Some Title', - }, - web_accessible_resources: [ - { - matches: ['*://*.google.com/*'], - resources: ['icon/*.png'], - }, - ], - }, -}); -``` - -And here's the different `manifest.json` files generated: - -:::code-group - -```json [MV2] -{ - "manifest_version": 2, - // ... - "browser_action": { - "default_title": "Some Title" - }, - "web_accessible_resources": ["icon/*.png"] -} -``` - -```json [MV3] -{ - "manifest_version": 3, - // ... - "action": { - "default_title": "Some Title" - }, - "web_accessible_resources": [ - { - "matches": ["*://*.google.com/*"], - "resources": ["icon/*.png"] - } - ] -} -``` - -::: - -## Name - -If not provided via the `manifest` config, the [manifest's `name`](https://developer.chrome.com/docs/extensions/mv3/manifest/name/) defaults to your `package.json`'s `name` property. - -## Version - -The [manifest's `version` and `version_name`](https://developer.chrome.com/docs/extensions/mv3/manifest/version/) properties are based on the `version` field listed in your `package.json` or `wxt.config.ts`. - -- `version_name` is the exact string listed in your `package.json` or `wxt.config.ts` file -- `version` is the string cleaned up, with any invalid suffixes removed - -If a version is not found, a warning is logged and the version defaults to `"0.0.0"`. - -#### Example - -```json -// package.json -{ - "version": "1.3.0-alpha2" -} -``` - -```json -// .output//manifest.json -{ - "version": "1.3.0", - "version_name": "1.3.0-alpha2" -} -``` - -## `icons` - -By default, WXT will discover icons in your [`public` directory](/guide/directory-structure/public/) and use them for the [manifest's `icons`](https://developer.chrome.com/docs/extensions/mv3/manifest/icons/). - -``` -public/ -├─ icon-16.png -├─ icon-24.png -├─ icon-48.png -├─ icon-96.png -└─ icon-128.png -``` - -Icon files need to match the following regex to be automatically included in the manifest. Most design software can output icons in one of these formats - -<<< @/../packages/wxt/src/core/utils/manifest.ts#snippet - -If you prefer to use filenames in a different format, you can add the icons manually in your `wxt.config.ts` file: - -```ts -export default defineConfig({ - manifest: { - icons: { - 16: '/extension-icon-16.png', - 24: '/extension-icon-24.png', - 48: '/extension-icon-48.png', - 96: '/extension-icon-96.png', - 128: '/extension-icon-128.png', - }, - }, -}); -``` - -## Permissions - -[Permissions](https://developer.chrome.com/docs/extensions/reference/permissions/) must be listed in the manifest config. - -```ts -export default defineConfig({ - manifest: { - permissions: ['storage', 'tabs'], - }, -}); -``` - -## Host Permissions - -[Host Permissions](https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#host-permissions) must be listed in the manifest config. - -```ts -export default defineConfig({ - manifest: { - host_permissions: ['*://*.google.com/*'], - }, -}); -``` - -:::warning -If you use host permissions and target both MV2 and MV3, make sure to only include the required host permissions for each version: - -```ts -export default defineConfig({ - manifest: ({ manifestVersion }) => ({ - host_permissions: manifestVersion === 2 ? [...] : [...], - }), -}); -``` - -::: - -## Default Locale - -See the dedicated [I18n docs](/guide/extension-apis/i18n) for setting up localization and a `default_locale`. - -## Actions - -In MV2, you had two options: [`browser_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) and [`page_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action). In MV3, they were merged into a single [`action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/action) API. - -By default, whenever an action is generated, WXT falls back to `browser_action` when targetting MV2. - -### Action With Popup - -To generate a manifest where a UI appears after clicking the icon, just create a [popup entrypoint](/guide/directory-structure/entrypoints/popup). - -If you want to use a `page_action` for MV2, add the following `meta` tag to the HTML document's head: - -```html - -``` - -### Action Without Popup - -If you want to use the `activeTab` permission or the `browser.action.onClick` event, but don't want to show a popup UI: - -1. Delete the [popup entrypoint](/guide/directory-structure/entrypoints/popup) if it exists -2. Add the `action` key to your manifest: - ```ts - // wxt.config.ts - export default defineConfig({ - manifest: { - action: {}, - }, - }); - ``` - -Same as an action with a popup, WXT will fallback on using `browser_action` for MV2. To use a `page_action` instead, add that key as well: - -```ts -// wxt.config.ts -export default defineConfig({ - manifest: { - action: {}, - page_action: {}, - }, -}); -``` - -## Full Control - -The `manifest` option can also be set equal to a function, letting you use logical statements to determine what should be output. - -```ts -// wxt.config.ts -export default defineConfig({ - manifest: ({ manifestVersion, browser, mode, command }) => { - return { ... } - } -}) -``` - -Or, you can use the `build:manifestGenerated` hook to transform the manifest before it is written to the output directory. - -```ts -// wxt.config.ts -export default defineConfig({ - hooks: { - build: { - manifestGenerated(manifest) { - // Update the manifest variable by reference - manifest.name = 'Overriden name'; - }, - }, - }, -}); -``` diff --git a/docs/guide/key-concepts/multiple-browsers.md b/docs/guide/key-concepts/multiple-browsers.md deleted file mode 100644 index ee5a743d7..000000000 --- a/docs/guide/key-concepts/multiple-browsers.md +++ /dev/null @@ -1,133 +0,0 @@ -# Multiple Browsers - -You can build an extension for any combination of browser and manifest version. Different browsers and manifest versions support different APIs and entrypoints, so be sure to check that your extension functions as expected for each target. - -Separate build targets are written to their own output directories: - -``` - -└─ .output - ├─ chrome-mv3 - ├─ firefox-mv2 - ├─ edge-mv3 - └─ ... -``` - -## Target Browser - -To build for a specific browser, pass the `-b --browser` flag from the CLI: - -```sh -wxt --browser firefox -wxt build --browser firefox -``` - -By default, it will build for `chrome`. When excluding the [manifest version flags](#target-manifest-version), it will default to the commonly accepted manifest version for that browser. - -| Browser | Default Manifest Version | -| ---------------- | :----------------------: | -| `chrome` | 3 | -| `firefox` | 2 | -| `safari` | 2 | -| `edge` | 3 | -| Any other string | 3 | - -:::tip -To configure which browser is opened when running dev mode via `wxt -b `, see the [`web-ext.config.ts` docs](/guide/directory-structure/web-ext-config). -::: - -## Target Manifest Version - -To build for a specific manifest version, pass either the `--mv2` flag or `--mv3` flag from the CLI. - -```sh -wxt --mv2 -wxt build --mv2 -``` - -When the `-b --browser` flag is not passed, it defaults to `chrome`. So here, we're targeting MV2 for Chrome. - -## Customizing Entrypoints - -There are several ways to customize entrypoint definitions per browser. - -First, you can use either the `include` or `exclude` option to include or exclude the entrypoint from specific browsers. Here are some examples - -:::code-group - -```ts [Background] -export default defineBackground({ - // Only include a background script when targeting chrome - include: ['chrome'], -}); -``` - -```ts [Content Script] -export default defineContentScript({ - // Do not add this content script to the manifest when targeting firefox - exclude: ['firefox'], -}); -``` - -```html [HTML page] - - - - - - - -``` - -::: - -Second, you can change individual options per-browser: - -:::code-group - -```ts [Background] -export default defineBackground({ - persistent: { - // Use a non-persistent background script for just safari - safari: false, - }, -}); -``` - -```ts [Content Script] -export default defineContentScript({ - matches: { - // Run the content script on different pages for each browser - chrome: ['*://*.google.com/*'], - firefox: ['*://*.duckduckgo.com/*'], - edge: ['*://*.bing.com/*'], - }, -}); -``` - -::: - -:::warning -Only `defineBackground` and `defineContentScript` support per-browser options right now. -::: - -## Runtime - -To determine the browser or manifest version at runtime, you can use any of the below variables: - -- `import.meta.env.BROWSER`: A string, the target browser, usually equal to the `--browser` flag -- `import.meta.env.MANIFEST_VERSION`: A number, either `2` or `3`, depending on the manifest version targeted -- `import.meta.env.CHROME`: A boolean equivalent to `import.meta.env.BROWSER === "chrome"` -- `import.meta.env.FIREFOX`: A boolean equivalent to `import.meta.env.BROWSER === "firefox"` -- `import.meta.env.EDGE`: A boolean equivalent to `import.meta.env.BROWSER === "edge"` -- `import.meta.env.SAFARI`: A boolean equivalent to `import.meta.env.BROWSER === "safari"` -- `import.meta.env.OPERA`: A boolean equivalent to `import.meta.env.BROWSER === "opera"` -- `import.meta.env.COMMAND`: A string, `"serve"` when running `wxt` for development or `"build"` in all other cases. - -:::info -These variables are constants defined at build time based on the build target. They do not actually detect which browser the code is running in. - -For example, if you build for `--browser chrome` and publish it on Edge, `import.meta.env.BROWSER` will be `"chrome"`, not `"edge"`. You have to build a separate ZIP for `--browser edge` before `import.meta.env.BROWSER` will be `"edge"`. - -If you need to know the actual browser your code is being ran on, you should use a [user agent parser](https://www.npmjs.com/package/ua-parser-js). -::: diff --git a/docs/guide/key-concepts/web-extension-polyfill.md b/docs/guide/key-concepts/web-extension-polyfill.md deleted file mode 100644 index 09ae01390..000000000 --- a/docs/guide/key-concepts/web-extension-polyfill.md +++ /dev/null @@ -1,108 +0,0 @@ -# Web Extension Polyfill - -## Overview - -WXT is built on top [`webextension-polyfill` by Mozilla](https://www.npmjs.com/package/webextension-polyfill). The polyfill standardizes much of web extension APIs so they behave the same across different browsers and manifest versions. - -Unlike with Chrome Extension development, which uses a `chrome` global, you need to import the `browser` variable from WXT to access the extension APIs: - -```ts -import { browser } from 'wxt/browser'; - -console.log(browser.runtime.id); -``` - -If you use auto-imports (enabled by default), you don't need to import this variable, it will work just like the `chrome` global: - -```ts -console.log(browser.runtime.id); -``` - -## Handling Differences - -Web extensions behave **_VERY_** differently between browsers and manifest versions. You will have to handle these API differences yourself. - -:::info -MDN has great compatibility tables for tracking which browsers support which APIs: [Web Extension Browser Support for JavaScript APIs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs) -::: - -Lets go over a few approaches: - -1. **Feature detection**: If an API isn't available, it is `undefined`. So check if that's the case before using it. - - ```ts - if (browser.runtime.onStartup) { - browser.runtime.onStartup.addListener(...); - } - ``` - - If there's a similar API you can fallback on, you can do something like this: - - ```ts - (browser.action ?? browser.browserAction).setBadgeColor('red'); - ``` - -2. **Check the browser**: WXT provides environment variables about which browser is being targeted. - ```ts - if (!import.meta.env.SAFARI) { - // Safari doesn't implement `onStartup` correctly, so we need a custom solution - // ... - } else { - browser.runtime.onStartup.addListener(...) - } - ``` -3. **Check the manifest version**: WXT provides environment variables about which manifest version is being targeted. - ```ts - if (import.meta.env.MANIFEST_VERSION === 3) { - // MV3 only code... - } else { - // MV2 only code... - } - ``` - -### Environment Variables - -| Name | Type | Description | -| ---------------------------------- | --------- | ----------------------------------------------------- | -| `import.meta.env.BROWSER` | `string` | The target browser | -| `import.meta.env.MANIFEST_VERSION` | `2 │ 3` | The target manifest version | -| `import.meta.env.CHROME` | `boolean` | equivalent to `import.meta.env.BROWSER === "chrome"` | -| `import.meta.env.FIREFOX` | `boolean` | equivalent to `import.meta.env.BROWSER === "firefox"` | -| `import.meta.env.SAFARI` | `boolean` | equivalent to `import.meta.env.BROWSER === "safari"` | -| `import.meta.env.EDGE` | `boolean` | equivalent to `import.meta.env.BROWSER === "edge"` | -| `import.meta.env.OPERA` | `boolean` | equivalent to `import.meta.env.BROWSER === "opera"` | - -WXT uses Vite, so all of Vite's `import.meta.env` variables are also available: - - - -## Augmented Types - -Based on the files in your project, WXT will modify some of the polyfill's types to be type-safe. - -For example, `browser.runtime.getURL` will be typed to only allow getting the URL of known files. `browser.i18n.getMessage` will only allow getting translations of messages defined in your `public/_locales//messages.json` file. - -## Missing Types - -Some newer APIs that Chrome provides are missing types. Don't worry, the APIs are present at runtime! The polyfill only provides types for standard and stable APIs that work on all browsers, so just be careful when you use them. - -If you're using TypeScript, you can use `@ts-expect-error` to ignore any errors when using an API that doesn't have any types. - -```ts -// @ts-expect-error: desktopCapture is not typed -browser.desktopCapture.chooseDesktopMedia(...) -``` - -Note that when running this code in a different browser that doesn't support the `desktopCapture` API, `browser.desktopCapture` will evaluate to `undefined` and an error will be thrown. - -## Missing Permissions - -Just like with the `chrome` global, you need to request the required permissions to use each API. Otherwise, `browser.{apiName}` will be `undefined`. - -For example, if you try to use `browser.storage.local.getItem(...)` without requesting the `storage` permission, the extension will throw an error: - -``` -Cannot access property "local" of undefined. -``` - -You can request permissions using the [`wxt.config.ts` file](/guide/directory-structure/wxt-config#permissions). diff --git a/docs/guide/key-concepts/wxt-submit.md b/docs/guide/key-concepts/wxt-submit.md deleted file mode 100644 index 2c194929d..000000000 --- a/docs/guide/key-concepts/wxt-submit.md +++ /dev/null @@ -1,9 +0,0 @@ -# `wxt submit` - -> Alias for [`publish-browser-extension`](https://www.npmjs.com/package/publish-browser-extension) - - - -
{{ data.submit }}
diff --git a/docs/guide/resources/compare.md b/docs/guide/resources/compare.md new file mode 100644 index 000000000..0e54009fd --- /dev/null +++ b/docs/guide/resources/compare.md @@ -0,0 +1,53 @@ +# Compare + +Lets compare the features of WXT vs [Plasmo](https://docs.plasmo.com/framework) (another framework) and [CRXJS](https://crxjs.dev/vite-plugin) (a bundler plugin). + +## Overview + +| Features | WXT | Plasmo | CRXJS | +| ------------------------------------------------------- | :--------------: | :-------------: | :--------------: | +| Supports all browsers | ✅ | ✅ | 🟡 10 | +| MV2 Support | ✅ | ✅ | 🟡 1 | +| MV3 Support | ✅ | ✅ | 🟡 1 | +| Create Extension ZIPs | ✅ | ✅ | ❌ | +| Create Firefox Sources ZIP | ✅ | ❌ | ❌ | +| First-class TypeScript support | ✅ | ✅ | ✅ | +| Entrypoint discovery | ✅ 2 | ✅ 2 | ❌ | +| Inline entrypoint config | ✅ | ✅ | ❌ 9 | +| Auto-imports | ✅ | ❌ | ❌ | +| Reusable module system | ✅ | ❌ | ❌ | +| Supports all frontend frameworks | ✅ | 🟡 3 | ✅ | +| Framework specific entrypoints (like `Popup.tsx`) | 🟡 4 | ✅ 5 | ❌ | +| Automated publishing | ✅ | ✅ | ❌ | +| Remote Code Bundling (Google Analytics) | ✅ | ✅ | ❌ | +| Unlisted HTML Pages | ✅ | ✅ | ✅ | +| Unlisted Scripts | ✅ | ❌ | ❌ | +| ESM Content Scripts | ❌ 12 | ❌ | ✅ | +| Dev Mode | | | +| `.env` Files | ✅ | ✅ | ✅ | +| Opens browser with extension installed | ✅ | ❌ | ❌ | +| HMR for UIs | ✅ | 🟡 6 | ✅ | +| Reload HTML Files on Change | ✅ | 🟡 7 | ✅ | +| Reload Content Scripts on Change | ✅ | 🟡 7 | ✅ | +| Reload Background on Change | 🟡 7 | 🟡 7 | 🟡 7 | +| Respects Content Script `run_at` | ✅ | ✅ | ❌ 8 | +| Built-in Wrappers | | | | +| Storage | ✅ | ✅ | ❌ 11 | +| Messaging | ❌ 11 | ✅ | ❌ 11 | +| Content Script UI | ✅ | ✅ | ❌ 11 | +| I18n | ✅ | ❌ | ❌ | + + + 1: Either MV2 or MV3, not both. +
2: File based. +
3: Only React, Vue, and Svelte. +
4: .html .ts .tsx. +
5: .html .ts .tsx. .vue .svelte. +
6: React only. +
7: Reloads entire extension. +
8: ESM-style loaders run asynchronously. +
9: Entrypoint options all configured in manifest.json. +
10: As of v2.0.0-beta.23, but v2 stable hasn't been released yet. +
11: There is no built-in wrapper around this API. However, you can still access the standard APIs via chrome/browser globals or use any 3rd party NPM package. +
12: WIP, moving very slowly. Follow wxt-dev/wxt#357 for updates. +
diff --git a/docs/guide/resources/faq.md b/docs/guide/resources/faq.md new file mode 100644 index 000000000..a6e6d70d6 --- /dev/null +++ b/docs/guide/resources/faq.md @@ -0,0 +1,19 @@ +--- +outline: false +--- + +# FAQ + +[[toc]] + +--- + +### Why are content scripts not showing up in the manifest? + +During development, WXT registers content scripts dynamically so they can be reloaded individually when a file is saved without reloading your entire extension. + +To list the content scripts registered during development, open the service worker's console and run: + +```js +await chrome.scripting.getRegisteredContentScripts(); +``` diff --git a/docs/guide/go-further/how-wxt-works.md b/docs/guide/resources/how-wxt-works.md similarity index 100% rename from docs/guide/go-further/how-wxt-works.md rename to docs/guide/resources/how-wxt-works.md diff --git a/docs/get-started/migrate-to-wxt.md b/docs/guide/resources/migrate.md similarity index 80% rename from docs/get-started/migrate-to-wxt.md rename to docs/guide/resources/migrate.md index d51a33390..8ef96d714 100644 --- a/docs/get-started/migrate-to-wxt.md +++ b/docs/guide/resources/migrate.md @@ -21,12 +21,14 @@ In general, you'll need to:   Update/create `package.json` scripts to use `wxt` (don't forget about `postinstall`)
Move entrypoints into `entrypoints/` directory
Move assets into either the `assets/` or `public/` directories
-  Move manifest.json content into `wxt.config.ts`
+  Move `manifest.json` content into `wxt.config.ts`
Convert custom import syntax to be compatible with Vite
-  Add a default export to JS entrypoints
+  Add a default export to JS entrypoints (`defineBackground`, `defineContentScript`, or `defineUnlistedScript`)
Use the `browser` global instead of `chrome`
-  Compare final `manifest.json` files, making sure permissions and host permissions are unchanged. Use [Google's update testing tool](https://github.com/GoogleChromeLabs/extension-update-testing-tool) if your extension is already live on the Chrome Web Store
-  Extension output by `wxt build` works the same way as before the migration
+  Compare final `manifest.json` files, making sure permissions and host permissions are unchanged
+:::warning +If your extension is already live on the Chrome Web Store, use [Google's update testing tool](https://github.com/GoogleChromeLabs/extension-update-testing-tool) to make sure no new permissions are being requested. +::: Every project is different, so there's no one-solution-fits-all to migrating your project. Just make sure `wxt dev` runs, `wxt build` results in a working extension, and the list of permissions in the `manifest.json` hasn't changed. If all that looks good, you've finished migrating your extension! @@ -34,6 +36,16 @@ Every project is different, so there's no one-solution-fits-all to migrating you Here's specific steps for other popular frameworks/build tools. +### Plasmo + +1. Install `wxt` +2. Move entrypoints into `entrypoints/` directory, merging the named exports used to configure your JS entrypoints into WXT's default export +3. Move public `assets/*` into the `public/` directory +4. If you use CSUI, migrate to WXT's `createContentScriptUi` +5. Convert Plasmo's custom import resolutions to Vite's +6. If importing remote code via a URL, add a `url:` prefix so it works with WXT +7. Compare your output `manifest.json` files from before the migration to after the migration. They should have the same content. If not, tweak your entrypoints and config to get as close as possible. + ### `vite-plugin-web-extension` Since you're already using Vite, it's a simple refactor. @@ -45,21 +57,3 @@ Since you're already using Vite, it's a simple refactor. 5. Move the `manifest.json` into `wxt.config.ts` 6. Move any custom settings from `vite.config.ts` into `wxt.config.ts`'s 7. Compare `dist/manifest.json` to `.output/*/manifest.json`, they should have the same content as before. If not, tweak your entrypoints and config to get as close as possible. - -### `plasmo` - -1. Install `wxt` -2. Move entrypoints into `entrypoints/` directory, merging the named exports used to configure your JS entrypoints into WXT's default export -3. Move public `assets/*` into the `public/` directory -4. If you use CSUI, migrate to WXT's `createContentScriptUi` -5. Convert Plasmo's custom import resolutions to Vite's -6. If importing remote code via a URL, add a `url:` prefix so it works with WXT -7. Compare your output `manifest.json` files from before the migration to after the migration. They should have the same content. If not, tweak your entrypoints and config to get as close as possible. - - diff --git a/docs/guide/upgrade-guide/wxt.md b/docs/guide/resources/upgrading.md similarity index 100% rename from docs/guide/upgrade-guide/wxt.md rename to docs/guide/resources/upgrading.md diff --git a/docs/i18n.md b/docs/i18n.md new file mode 100644 index 000000000..1447f7d52 --- /dev/null +++ b/docs/i18n.md @@ -0,0 +1,5 @@ +--- +outline: deep +--- + + diff --git a/docs/index.md b/docs/index.md index d0c15a8e7..5ec382ff7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,10 +13,10 @@ hero: actions: - theme: brand text: Get Started - link: /get-started/installation + link: /guide/get-started/installation - theme: alt text: Learn More - link: /get-started/introduction + link: /guide/get-started/introduction features: - icon: 🌐 diff --git a/docs/public/_redirects b/docs/public/_redirects index 2ba0d9650..204977990 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -6,6 +6,7 @@ # OLD /config.html /api/reference/wxt/interfaces/InlineConfig.html /api/config.html /api/reference/wxt/interfaces/InlineConfig.html +/api/config /api/reference/wxt/interfaces/InlineConfig.html /entrypoints /entrypoints/background.html /get-started/assets.html /guide/assets.html /get-started/build-targets.html /guide/multiple-browsers.html @@ -36,68 +37,69 @@ /guide/go-further/entrypoint-side-effects.html /guide/go-further/entrypoint-loaders.html # https://github.com/wxt-dev/wxt/issues/704 -# Generated via `find docs/.vitepress/dist -type f -name "*.html"` -/guide/i18n/build-integrations.html /TODO -/guide/i18n/introduction.html /TODO -/guide/i18n/messages-file-format.html /TODO -/guide/i18n/editor-support.html /TODO -/guide/i18n/installation.html /TODO -/guide/key-concepts/content-script-ui.html /TODO -/guide/key-concepts/manifest.html /TODO -/guide/key-concepts/wxt-submit.html /TODO -/guide/key-concepts/auto-imports.html /TODO -/guide/key-concepts/web-extension-polyfill.html /TODO -/guide/key-concepts/frontend-frameworks.html /TODO -/guide/key-concepts/multiple-browsers.html /TODO -/guide/go-further/entrypoint-loaders.html /TODO -/guide/go-further/es-modules.html /TODO -/guide/go-further/handling-updates.html /TODO -/guide/go-further/custom-events.html /TODO -/guide/go-further/debugging.html /TODO -/guide/go-further/remote-code.html /TODO -/guide/go-further/vite.html /TODO -/guide/go-further/testing.html /TODO -/guide/go-further/how-wxt-works.html /TODO -/guide/go-further/reusable-modules.html /TODO -/guide/extension-apis/messaging.html /TODO -/guide/extension-apis/i18n.html /TODO -/guide/extension-apis/storage.html /TODO -/guide/extension-apis/scripting.html /TODO -/guide/extension-apis/others.html /TODO -/guide/upgrade-guide/wxt.html /TODO -/guide/directory-structure/components.html /TODO -/guide/directory-structure/hooks.html /TODO -/guide/directory-structure/assets.html /TODO -/guide/directory-structure/package.html /TODO -/guide/directory-structure/env.html /TODO -/guide/directory-structure/wxt-config.html /TODO -/guide/directory-structure/wxt.html /TODO -/guide/directory-structure/public/locales.html /TODO -/guide/directory-structure/public/index.html /TODO -/guide/directory-structure/entrypoints/devtools.html /TODO -/guide/directory-structure/entrypoints/sidepanel.html /TODO -/guide/directory-structure/entrypoints/content-scripts.html /TODO -/guide/directory-structure/entrypoints/newtab.html /TODO -/guide/directory-structure/entrypoints/bookmarks.html /TODO -/guide/directory-structure/entrypoints/unlisted-pages.html /TODO -/guide/directory-structure/entrypoints/unlisted-scripts.html /TODO -/guide/directory-structure/entrypoints/options.html /TODO -/guide/directory-structure/entrypoints/background.html /TODO -/guide/directory-structure/entrypoints/popup.html /TODO -/guide/directory-structure/entrypoints/history.html /TODO -/guide/directory-structure/entrypoints/sandbox.html /TODO -/guide/directory-structure/entrypoints/css.html /TODO -/guide/directory-structure/web-ext-config.html /TODO -/guide/directory-structure/tsconfig.html /TODO -/guide/directory-structure/utils.html /TODO -/guide/directory-structure/app-config.html /TODO -/guide/directory-structure/composables.html /TODO -/guide/directory-structure/output.html /TODO -/get-started/assets.html /TODO -/get-started/introduction.html /TODO -/get-started/configuration.html /TODO -/get-started/publishing.html /TODO -/get-started/migrate-to-wxt.html /TODO -/get-started/compare.html /TODO -/get-started/entrypoints.html /TODO -/get-started/installation.html /TODO +# Generated via `pnpm docs:build && find docs/.vitepress/dist -type f -name "*.html"` + +/guide/i18n/build-integrations.html /TODO +/guide/i18n/introduction.html /TODO +/guide/i18n/messages-file-format.html /TODO +/guide/i18n/editor-support.html /TODO +/guide/i18n/installation.html /TODO +/guide/key-concepts/content-script-ui.html /guide/content-scripts/ui.html +/guide/key-concepts/manifest.html /TODO +/guide/key-concepts/wxt-submit.html /TODO +/guide/key-concepts/auto-imports.html /TODO +/guide/key-concepts/web-extension-polyfill.html /TODO +/guide/key-concepts/frontend-frameworks.html /TODO +/guide/key-concepts/multiple-browsers.html /TODO +/guide/go-further/entrypoint-loaders.html /TODO +/guide/go-further/es-modules.html /TODO +/guide/go-further/handling-updates.html /TODO +/guide/go-further/custom-events.html /TODO +/guide/go-further/debugging.html /TODO +/guide/go-further/remote-code.html /TODO +/guide/go-further/vite.html /TODO +/guide/go-further/testing.html /TODO +/guide/go-further/how-wxt-works.html /TODO +/guide/go-further/reusable-modules.html /TODO +/guide/extension-apis/messaging.html /TODO +/guide/extension-apis/i18n.html /TODO +/guide/extension-apis/storage.html /TODO +/guide/extension-apis/scripting.html /TODO +/guide/extension-apis/others.html /TODO +/guide/upgrade-guide/wxt.html /TODO +/guide/directory-structure/components.html /TODO +/guide/directory-structure/hooks.html /TODO +/guide/directory-structure/assets.html /TODO +/guide/directory-structure/package.html /TODO +/guide/directory-structure/env.html /TODO +/guide/directory-structure/wxt-config.html /TODO +/guide/directory-structure/wxt.html /TODO +/guide/directory-structure/public/locales.html /TODO +/guide/directory-structure/public/index.html /TODO +/guide/directory-structure/entrypoints/devtools.html /TODO +/guide/directory-structure/entrypoints/sidepanel.html /TODO +/guide/directory-structure/entrypoints/content-scripts.html /TODO +/guide/directory-structure/entrypoints/newtab.html /TODO +/guide/directory-structure/entrypoints/bookmarks.html /TODO +/guide/directory-structure/entrypoints/unlisted-pages.html /TODO +/guide/directory-structure/entrypoints/unlisted-scripts.html /TODO +/guide/directory-structure/entrypoints/options.html /TODO +/guide/directory-structure/entrypoints/background.html /TODO +/guide/directory-structure/entrypoints/popup.html /TODO +/guide/directory-structure/entrypoints/history.html /TODO +/guide/directory-structure/entrypoints/sandbox.html /TODO +/guide/directory-structure/entrypoints/css.html /TODO +/guide/directory-structure/web-ext-config.html /TODO +/guide/directory-structure/tsconfig.html /TODO +/guide/directory-structure/utils.html /TODO +/guide/directory-structure/app-config.html /TODO +/guide/directory-structure/composables.html /TODO +/guide/directory-structure/output.html /TODO +/get-started/assets.html /TODO +/get-started/introduction.html /TODO +/get-started/configuration.html /TODO +/get-started/publishing.html /TODO +/get-started/migrate-to-wxt.html /TODO +/get-started/compare.html /guide/resources/compare +/get-started/entrypoints.html /TODO +/get-started/installation.html /TODO diff --git a/docs/guide/extension-apis/storage.md b/docs/storage.md similarity index 96% rename from docs/guide/extension-apis/storage.md rename to docs/storage.md index 9d593074d..6121da042 100644 --- a/docs/guide/extension-apis/storage.md +++ b/docs/storage.md @@ -2,7 +2,7 @@ outline: deep --- -# Storage API +# `wxt/storage` API WXT provides a simplified API to replace the `browser.storage.*` APIs. Use the `storage` auto-import from `wxt/storage` or import it manually to get started: @@ -10,20 +10,17 @@ WXT provides a simplified API to replace the `browser.storage.*` APIs. Use the ` import { storage } from 'wxt/storage'; ``` -:::warning -To use the `wxt/storage` API, the `"storage"` permission must be added to the manifest: - -```ts -// wxt.config.ts -export default defineConfig({ - manifest: { - permissions: ['storage'], - }, -}); -``` - -More info on permissions [here](/guide/key-concepts/manifest#permissions). -::: +> [!IMPORTANT] +> To use the `wxt/storage` API, the `"storage"` permission must be added to the manifest: +> +> ```ts +> // wxt.config.ts +> export default defineConfig({ +> manifest: { +> permissions: ['storage'], +> }, +> }); +> ``` [[toc]] diff --git a/packages/i18n/README.md b/packages/i18n/README.md index ea50ac149..670c95033 100644 --- a/packages/i18n/README.md +++ b/packages/i18n/README.md @@ -1,3 +1,366 @@ -# WXT I18n +# `@wxt-dev/i18n` -[Read the docs](https://wxt.dev/guide/i18n/installation) to get started. +> [!IMPORTANT] +> You don't have to use `wxt` to use this package - it will work in any bundler setup. See [Installation without WXT](./installation#without-wxt) for more details. + +`@wxt-dev/i18n` is a simple, type-safe wrapper around the `browser.i18n` APIs. It provides several benefits over the standard API: + +1. Simple messages file format +2. Plural form support +3. Integrates with the [I18n Ally VS Code extension](./editor-support#vscode) + +It also provides several benefits over other non-web extension specific i18n packages: + +1. Does not bundle localization files into every entrypoint +2. Don't need to fetch the localization files asynchronously +3. Can localize text in manifest and CSS files + +However, it does have one major downside: + +1. Like the `browser.i18n` API, to change the language, users must change the browser's language + +## Installation + +### With WXT + +1. Install `@wxt-dev/i18n` via your package manager: + + ```sh + pnpm i @wxt-dev/i18n + ``` + +2. Add the WXT module to your `wxt.config.ts` file and setup a default locale: + + ```ts + export default defineConfig({ + modules: ['@wxt-dev/i18n/module'], + manifest: { + default_locale: 'en', + }, + }); + ``` + +3. Create a localization file at `/locales/.yml` or move your existing localization files there. + + ```yml + # /locales/en.yml + helloWorld: Hello world! + ``` + + > `@wxt-dev/i18n` supports the standard messages format, so if you already have localization files at `/public/_locale//messages.json`, you don't need to convert them to YAML or refactor them - just move them to `/locales/.json` and they'll just work out of the box! + +4. To get a translation, use the auto-imported `i18n` object or import it manually: + + ```ts + import { i18n } from '#i18n'; + + i18n.t('helloWorld'); // "Hello world!" + ``` + +And you're done! Using WXT, you get type-safety out of the box. + +### Without WXT + +1. Install `@wxt-dev/i18n` via your package manager: + + ```sh + pnpm i @wxt-dev/i18n + ``` + +2. Create a messages file at `_locales//messages.json` or move your existing translations there: + + ```json + { + "helloWorld": { + "message": "Hello world!" + } + } + ``` + + > [!NOTE] + > For the best DX, you should to integrate `@wxt-dev/i18n` into your build process. This enables: + + > 1. Plural forms + > 2. Simple messages file format + > 3. Type safety + > + > See [Build Integrations](./build-integrations) to set it up. + +3. Create the `i18n` object, export it, and use it wherever you want! + + ```ts + import { createI18n } from '@wxt-dev/i18n'; + + export const i18n = createI18n(); + + i18n.t('helloWorld'); // "Hello world!"; + ``` + +## Messages File Format + +> [!DANGER] +> You can only use the file format discussed on this page if you have [integrated `@wxt-dev/i18n` into your build process](./build-integrations). If you have not integrated it into your build process, you must use JSON files in the `_locales` directory, like a normal web extension. + +### File Extensions + +You can define your messages in several different file types: + +- `.yml` +- `.yaml` +- `.json` +- `.jsonc` +- `.json5` +- `.toml` + +### Nested Keys + +You can have translations at the top level or nest them into groups: + +```yml +ok: OK +cancel: Cancel +welcome: + title: Welcome to XYZ +dialogs: + confirmation: + title: 'Are you sure?' +``` + +To access a nested key, use `.`: + +```ts +i18n.t('ok'); // "OK" +i18n.t('cancel'); // "Cancel" +i18n.t('welcome.title'); // "Welcome to XYZ" +i18n.t('dialogs.confirmation.title'); // "Are you sure?" +``` + +### Substitutions + +Because `@wxt-dev/i18n` is based on `browser.i18n`, you define substitutions the same way, with `$1`-`$9`: + +```yml +hello: Hello $1! +order: Thanks for ordering your $1 +``` + +#### Escapting `$` + +To escape the dollar sign, put another `$` in front of it: + +```yml +dollars: $$$1 +``` + +```ts +i18n.t('dollars', ['1.00']); // "$1.00" +``` + +### Plural Forms + +> [!WARNING] +> Plural support languages like Arabic, that have different forms for "few" or "many", is not supported right now. Feel free to open a PR if you are interested in this! + +To get a different translation based on a count: + +```yml +items: + 1: 1 item + n: $1 items +``` + +Then you pass in the count as the second argument to `i18n.t`: + +```ts +i18n.t('items', 0); // "0 items" +i18n.t('items', 1); // "1 item" +i18n.t('items', 2); // "2 items" +``` + +To add a custom translation for 0 items: + +```yml +items: + 0: No items + 1: 1 item + n: $1 items +``` + +```ts +i18n.t('items', 0); // "No items" +i18n.t('items', 1); // "1 item" +i18n.t('items', 2); // "2 items" +``` + +If you need to pass a custom substitution for `$1` instead of the count, just add the substitution: + +```yml +items: + 0: No items + 1: $1 item + n: $1 items +``` + +```ts +i18n.t('items', 0, ['Zero']); // "No items" +i18n.t('items', 1, ['One']); // "One item" +i18n.t('items', 2, ['Multiple']); // "Multiple items" +``` + +### Verbose Keys + +`@wxt-dev/i18n` is compatible with the message format used by [`browser.i18n`](https://developer.chrome.com/docs/extensions/reference/api/i18n). + +> [!IMPORTANT] +> This means if you're migrating to `@wxt-dev/i18n` and you're already using the verbose format, you don't have to change anything! + +A key is treated as "verbose" when it is: + +1. At the top level (not nested) +2. Only contains the following properties: `message`, `description` and/or `placeholder` + +```json +{ + "appName": { + "message": "GitHub - Better Line Counts", + "description": "The app's name, should not be translated", + }, + "ok": "OK", + "deleteConfirmation": { + "title": "Delete XYZ?" + "message": "You cannot undo this action once taken." + } +} +``` + +In this example, only `appName` is considered verbose. `deleteConfirmation` is not verbose because it contains the additional property `title`. + +```ts +i18n.t('appName'); // ✅ "GitHub - Better Line Counts" +i18n.t('appName.message'); // ❌ +i18n.t('ok'); // ✅ "OK" +i18n.t('deleteConfirmation'); // ❌ +i18n.t('deleteConfirmation.title'); // ✅ "Delete XYZ?" +i18n.t('deleteConfirmation.message'); // ✅ "You cannot undo this action once taken." +``` + +If this is confusing, don't worry! With type-safety, you'll get a type error if you do it wrong. If type-safety is disabled, you'll get a runtime warning in the devtools console. + +> [!WARNING] +> Using the verbose format is not recommended. I have yet to see a translation service and software that supports this format out of the box. Stick with the simple format when you can. + +## Build Integrations + +To use the custom messages file format, you'll need to use `@wxt-dev/i18n/build` to transform the custom format to the one expected by browsers. + +### WXT + +See [Installation with WXT](./installation#with-wxt). + +But TLDR, all you need is: + +```ts +// wxt.config.ts +export default defineConfig({ + modules: ['@wxt-dev/i18n/module'], +}); +``` + +Types are generated whenever you run `wxt prepare` or another build command. + +### Custom + +If you're not using WXT, you'll have to pre-process the localization files yourself. Here's a basic script to generate the `_locales/.../messages.json` and `wxt-i18n-structure.d.ts` files: + +```ts +// build-i18n.js +import { + parseMessagesFile, + generateChromeMessagesFile, + generateTypeFile, +} from '@wxt-dev/i18n/build'; + +// Read your localization files +const messages = { + en: await parseMessagesFile('path/locales/en.yml'), + de: await parseMessagesFile('path/locales/de.yml'), + // ... +}; + +// Generate JSON files for the browser +await generateChromeMessagesFile('dist/_locales/en/messages.json', messages.en); +await generateChromeMessagesFile('dist/_locales/de/messages.json', messages.de); +// ... + +// Generate a types file based on your default_locale +await generateTypeFile('wxt-i18n-structure.d.ts', messages.en); +``` + +Then run the script: + +```sh +node generate-i18n.js +``` + +If your build tool has a dev mode, you'll also want to rerun the script whenever you change a localization file. + +#### Type Safety + +Once you've generated `wxt-i18n-structure.d.ts` (see the [Custom](#custom) section), you can use it to pass the generated type into `createI18n`: + +```ts +import type { WxtI18nStructure } from './wxt-i18n-structure'; + +export const i18n = createI18n(); +``` + +And just like that, you have type safety! + +## Editor Support + +For better DX, you can configure your editor with plugins and extensions. + +### VS Code + +The [I18n Ally Extension](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally) adds several features to VS Code: + +- Go to translation definition +- Inline previews of text +- Hover to see other translations + +You'll need to configure it the extension so it knows where your localization files are and what function represents getting a translation: + +`.vscode/i18n-ally-custom-framework.yml`: + +```yml +# An array of strings which contain Language Ids defined by VS Code +# You can check available language ids here: https://code.visualstudio.com/docs/languages/identifiers +languageIds: + - typescript + +# Look for t("...") +usageMatchRegex: + - "[^\\w\\d]t\\(['\"`]({key})['\"`]" + +# Disable other built-in i18n ally frameworks +monopoly: true +``` + +`.vscode/settings.json`: + +```json +{ + "i18n-ally.localesPaths": ["src/locales"], + "i18n-ally.keystyle": "nested" +} +``` + +### Zed + +As of time of writing, Aug 18, 2024, no extensions exist for Zed to add I18n support. + +### Jetbrains IDEs + +Install the [I18n Ally plugin](https://plugins.jetbrains.com/plugin/17212-i18n-ally). The docs are limited around their Jetbrains support, but you'll probably need to configure the plugin similar to [VS Code](#vs-code)... Not sure where the files go though. + +Please open a PR if you figure it out! diff --git a/packages/wxt/src/browser/chrome.ts b/packages/wxt/src/browser/chrome.ts index 546c22402..34d0ef041 100644 --- a/packages/wxt/src/browser/chrome.ts +++ b/packages/wxt/src/browser/chrome.ts @@ -18,9 +18,11 @@ export type WxtBrowser = Omit & { i18n: WxtI18n & Omit; }; +// #region snippet export const browser: WxtBrowser = // @ts-expect-error globalThis.browser?.runtime?.id == null ? globalThis.chrome : // @ts-expect-error globalThis.browser; +// #endregion snippet diff --git a/packages/wxt/src/client/content-scripts/ui/index.ts b/packages/wxt/src/client/content-scripts/ui/index.ts index c9ba6fb43..4aef61e0b 100644 --- a/packages/wxt/src/client/content-scripts/ui/index.ts +++ b/packages/wxt/src/client/content-scripts/ui/index.ts @@ -17,7 +17,7 @@ export * from './types'; /** * Create a content script UI without any isolation. * - * @see https://wxt.dev/guide/key-concepts/content-script-ui.html#integrated + * @see https://wxt.dev/guide/content-scripts/ui.html#integrated */ export function createIntegratedUi( ctx: ContentScriptContext, @@ -53,7 +53,7 @@ export function createIntegratedUi( /** * Create a content script UI using an iframe. * - * @see https://wxt.dev/guide/key-concepts/content-script-ui.html#iframe + * @see https://wxt.dev/guide/content-scripts/ui.html#iframe */ export function createIframeUi( ctx: ContentScriptContext, @@ -96,7 +96,7 @@ export function createIframeUi( * * > This function is async because it has to load the CSS via a network call. * - * @see https://wxt.dev/guide/key-concepts/content-script-ui.html#shadowroot + * @see https://wxt.dev/guide/content-scripts/ui.html#shadowroot */ export async function createShadowRootUi( ctx: ContentScriptContext, From 8968919c8f46dbb5a2aedb266db89944cee86599 Mon Sep 17 00:00:00 2001 From: aklinker1 Date: Sat, 28 Sep 2024 21:13:09 +0000 Subject: [PATCH 03/23] docs: Update `wxt init` GIF --- docs/assets/init-demo.gif | Bin 139656 -> 140670 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/assets/init-demo.gif b/docs/assets/init-demo.gif index 474db34c2e2bf5c7a3d456c330fddd6e33b41a1b..353c8b73aaa92ed97061b187bfbc35bca429b93f 100644 GIT binary patch literal 140670 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%0DEA19BN~1Kc8iTo(YvahvK+D+ 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

@~3ugz6bwxid`wE01iigD?MrHbwDVSkjak5w8 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 |Rx4um7TzFmEI@v2~?US~Brk`oi- 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 z z5B;P1+dnK(D#Y!Q*~yu!@AlqsD>YAH_Pz98+Ew9@ySC%z4-&uHq|EV{_5N`0n+F>7 z9(3%l+tV0uU#$3`>AM33&Uafpl(vQLzk6^lu6Xj|C*Ni}-b_{Ji^wDQtXKZNwwZ{c zaig8Ga%*@xJ^j9$E?s1iOi-2S~A1pY1S|Iv}|zun>Avi{$E)A(;Y{#(}n r-uVCTH~#wnAo-?IMyWQzB1S^syMZu5Tt8oynN literal 139656 zcmeFZXE+@G+BK>SM(>P1x@gf2BVu%-2hk#Glt>~(4T;`+??xXrdM6mY_fGU6l4y}p z67MAYzt6MxexCjA_neRCocr>@b@_z*x7NMZz3x#_Q-(-cdg6ewf7}XVaByI9b785g zVk3!2~<{AQRT~3RaI3>R8Ut})6jUJsi~z2hihwV z>AY9f)zy87E&~mHF>wQQy^=LFd}L@6VE6>~2>Q_2*w};wYC_3rf-W;t6F);!Q`5)j zvLJXOF84$|=ShaK1-d+5ST&eh!>nzTdTb3+Y-i1$K7H!YmH&*|@fo_xZJnH)o|}}s zXtjI!^7+dF`&TZnUUfLS1O~bmYrlT|+70o_ZRWYVyPLbOwwK;lFLd>}dRq*7dwahT zRq**!zP`SG=<@gTOOElI^a`*z3_w?4U=X^3gM#A}g8ScvhK5Giu0(`KL`FtNy~K@H z3y87RiiwGdEqE2DZ5bCImzeL^vul6YzMdO%=_8d*#!j!W$0>B zsA_ywU0vOvS=eCqssUY1O^qYYO-)VB{U)ssY}?w~x-304p5e=kXuk2Kt5kt$?=} z20%vDYIt`bkdoJIusRPJO2)39rCO8U7YPz|Tpg?_7>ETcL@=t=77iuyJS;OCsx2Bx z6|x@AQmZQ-%Y?Wdt`60eOytT15-_RPBc=*e6L}vG*O$(e=oF}Dt2dO*l^fMLt_?So zFTA%vMld~StXQhEpDBAh(pb6DOM`t6(X56Tk8*I5D&}E$66acFH~EPMw+&?EEsJ(% z`{mjGO!J*$U%GvEK^kDMoBX@Hg&nMGE!vY)6UB+iyoh_7K}K zG8g;Xv2wU~cH$Ii9CqSWxk`5uG$amo5_OdC>?Y|OI_xGJJuTf$F>^oIO|=NQvzKO* z;;@%)UtGGE;naArm+9Pp=Tp|}d52Hgo_nRAa(pfhKIQu1^6tZfXdL(R!nn%z^P?mV z_Y2~bc@GMc3>^=O(w>$b6lb{~9+bdCcn=YUDUOGwh~l!tvWmuKOMIE5TlUWt_46j5 zg$eyO4y)SL4SGl#aT)llS}z=rYE*yn9@W-SL>|>mV&U-BjY>0oX&8ure`#EG|NNzC zBZRN2sY{QqLYUA==xggy9`xn zU2)t)BzbgMtqsP(7063KYbdV#}>2!#vq~dg#-$P@io^~bT z8UEtDldHyXzt6KO$seQTgmQSq567h?N9rb2-_zGm-t9K4ubAf&5HFRpbH>CX1RrDI zkn&ejOlhm!`@Wc)KnBBA5qqUVsR@pU0W=B#?o(EY&n1iLbmIKT?3-^l``JQK(II5` zGS&VBf?%hU8M>w;)OMVT;N?!zqZgOEX?9hYdw8FzF)8eWdWQBRqh!5#>>)5r{BV|b zov!Rw>?g%{Ufnm<)te{KIED`@WZKu+}_lImsqNfsGfH#Tjx`4j;;|3(*p&z{U5 zdr{>W6XyC^=4@@lw6&W&6yb7n*q#xZiiLU6;^im7QVs7+2=&RE*`Z+#@Z*72xdyRYe7V3}RjlIPc`K zUsa0*n{XDZWd5rN=`Mfr_I>4h{Zsg)SjSda{Q00;jsT@Xq3}=JK@4w?F?wM&v==&| z;uxELKt*kw0(%uG0yBWZXUfcyu>kxdNEuL8gAc^WXt%N_eKRNzpr?cZvgD$@o!ALk z$htqjrh$I+I!%NV74fL34eMo`Cb1(QuuctxD}eRlPa@c$%rzJ(}3RwuS{{w$0!3m#;($Xw|T5!>2y z>wITVDF6t8i~jWUBWgb`-`VGai8%*ZMAeh%+~Wpa9xe>m-oY03Q{*8iC6KS4ihkXo za!-ua(BB?|V6b|JPS$ze7H7J)TKpld2)JGTmN(Yx>ze}m&{siUO5p$+NFZdxGMWXY zTkBWouLbF5_?5kCxkxFtpM2EdKmKZJ@(5SuPMUp%FT_}NYm^}ulmbKMj!@eNH7tB-&W zcSR9(vjq;#TRB`kzaXkYcsM&5Q19;6no1fQ^P#GW^z0PLOC2k$TkE?fkxHBN1GJ@@ zvnG_8`}f~l*<=P!Vt`XvV_rKK(Aw^AfVh{AqS$c*JqV7X4HDM%LyD z%7?T`T$55HcFCV9mVWqNz(Sb+=v&L9+fnCY$_(o1r?00WFKh{3S7rw$#T9m%pG{V-=9|aGzi>&^KEflUtC?@84%IxeVz^!$)M{*Uq{P-V z+FF{7X{^s%3zzVWn_J9zh|dV_c;R}zvQFZ0TdVoiCG&c9U#qEgVeG4W+x6OUOjG+O z&2Qc-*XyY9rcTzgnYY*1A2CRqyYRG*0~l^LfZEMHw1N-Yg>E*U##+6e{qg&Tm7W`j7D+o!39V`F%87!P7?dF#I|W z({A6Qoj~0Ul+|29bY{ruGg=B{pcd?JPy^q*$YTAFdWAeqChV+I{<^-s{T$?j1@QwI`Qdu{0n_{ln*E3t{YX%LWFUVEh(DE)KMjNuBh8<_ z*`IOIe>wFXGbn%!62M^;AmHK8lNP|+9KgRAAczVO0tJdd0>z91B|HNmX@SzsfijDM zvZz2~3Qu`RkfKqLvS*Mg|X_g!jp``Q#`|o2g1^t!?PB{bM|%YKoR+nh(e=? zV$TRfT0~iMM8#r66)K_{6j=+2tT&2m^o(pyi)?L<6g&;@L`8OiqEKStJw{Reo>6hC zQG?Ay!Qatlz{7y(bn^XdaaROHhl)@{4wRQ7u8zD@ipyNxdaWV<}1NGD*jnZWfZP zZ=C!D7;TuIY|@f^LYr)UncVg$$x154#yABBKj~?DiepQPQ>lm1P_i>!s>`K+1|-$p zE7ddI*P1 zX>7^tyv*#P%OZ5m=rzvj_sSYf&l+yY8ePg7zs#DX%bu3Xo;A*%_sU*O&t7iHUR}yw zzs%mC%h|e>%Goi_+4IWTPtQ4Q$vIle`FfdiOqY8qm3wZSd*PLfO3%G&$-P<1{dJj( zK@Z20h67CCxZZGJ2Ao19gJ>B}V&a^838#?GqiWS5@XiBeXOsv zbC~3FWoR;H;)KZLa*}y^HNz z)9+^#J1rOYHy6L4FL4Nx12`E8il)W@bEn6UX^#zSM*3%^qN%kdshr*R1CLPj4oGTPis5*2Et!S zeh=B!Yuegs+CG?B_3%x@=t}$evxJfB_GxIxY-C)|n~ufIj^(zF)s>F*>yC|EhR!WQ zwmH+zy*HhBbRGL`okuI3z8>vE3?J4BKAf6UU{=#X7yg>tX|TH zUiH=9d@rO9W2BZ$-;b3leV@L{vd*tI%~>O@?IZ20Bb_%RU5ukWGNZj_qy0XkgIS})H#WhmqYl!8^i&bU@%Q$-J1kFp2YQ?1ZGbXbW9ShO_Kba9BG}P@Xf!JnWFIxC(E9q z@0em-n_~Vs1!kINyEo18c$&+1nkRdjw_}=rZCdc>v=Gyb$h{dcr^hoAzB7>Q8R?E0 znY9_&pEGhyv-0<56(7$k`_8In&#HIKYOKv_{hZZdn$x>Cr~i1)(09%#d(Na|&TMVY z{O6nn)4bKad7H=cPkra@v*#T<=AG8&U;LbRW?FE$xA6M$g1hg6XZAubJ=xz4$Xg74 z4;&V>BZ>ATfdGtKv?uvDXA=DbPYihs0SrO(5B~1V!0@tf?x39+OQa|zk$P6xWS&x_ zEt}RVq-;WSEKb)Sc`9?-gcU#504dZ&jYZL|Sb496##mu@cm zZnsQPpyLpM$wpkDn+RLrA+)kH^{8 zN`Tx)Pq9aEO2!W|sjUN-s;2@IZ&xgRZ2`)w=a*NOn{9LC$13gaC13EuQ0#0sEycg^ zLU7>KA@cy#*rSiWCkF!`y>D?)rdByjs&N5VK-VDLi6MYl(1m96lVIAX_R}HfZV<9y z8Y=|dYqAtzKL-z1ztQOl@^eO#3Tx#grw~AsTI6Azz17&HVp&q#D%PzHMT#zEoE*`QG{5g@ z8POTq=DwB1N4&J!JDAM@(M3?@lPIasXnFLg%@jxq_(k|RDjrY3X`F>4IR7{^c>(#m z#eP+jIc81`!-wUB{5Tjr_c1a5t23g}ox%T4ozac6{iicn6@1A5>Wok_ZbuHIlYEtT zbdoQQP*ZG*o$pA1k4r@tpHR60?l zVF2mFPd?C3<9_C->6N%IpKgkD|4yJ+(nU>A0|~3fQUu^Rv)jupC-UnM8$Qk6qGVNO zQZEquDJ9}>{rJ5c`_5%5=@NdrypK(tXNDJQ^OAl);j(`Cr~5V{v|de$N*-*078 z$8ZrW5jPa7_m)SP=0qcDVTskWt9G`7Sk%a~i zjR#SPog0M(H|IR&QGL-Ep-Q0ZSn5|r5$1F*ibpYbUp6CSq$g^&weEJQm2Ash zUW)jG23{k_AwxH;PafL3&=f?FIJY2+#AFB@vJq`oh!-6{;R|C{}p>Ix=FSE!X9(NUvyaz@;qcD zEvtIrpe|e~3QX;Iw0L5z8bz=4H|!zC*UpdHuYIbSCSvyjJTzsa6~gXih{hg!#XN;b zS(%7)ux`<>012l3ho!Tnyk#_+4t3?~SvpG7=fANh3~EpjRt@e61(Gmo@aS5}uL9|1 zWE+NGV-*;Cy+vRasf~tGn2AO6o?FY$cbKLNdR}}pDtmTyEc_6AFJ0F63^49|ro|<5n>s|@&}nDMrKt1p3nM2U!`uC7kLXBLwbgB@SgiTIYu6Nr zpTE!flH|IYeY6nPy91?aKM;jXR9xQLCvKK5E$liMP z`miyB^um8C`Q?X#D~vY6>`tEMdy6XDTSwCNcv?lU+}N{*OZP7pMDR1GZ!0qlr&&d7 zZUK|yWGEa8lYL<6qcM8Z%|(%5OS1l~>Fag2;kd?aFk zMJzK(7D#}GCnQN=nG!NjI0={OVbHV^*<(&3#RF@Yd_;1=j)OFH3DA3)3UN0gf~wRu zgO{r8nUzv<23@qU(!6H1bnje+U^))9Fk#{DVQ#h&+fj8d4V0h9PNO=$Jjn3Vk^7`9 z-xn;(ieqiL{}XC!{MYt^cjKVP(BIUiz(@agYWq8Y1^)rClfMI4f{j|JA%At2+RW~Q z5MiYl4NuCairG|N7rmF1`>;F(7>)Qaxx;jvMkW_0eFJ$3>qXkvJ`P{bk5ex4Y2e{#fMF9L~3K;os6ad5f_7?@X68;AYn8s{Npw+I; zlA7VvNF-Ns@e-piUoWD^DeQLoUr^;gA~ZA5VjUc!xc_udiurS6ke^bS6Uigv<+GKQybBCL8-q@XhB)K}#I-L`=N)bH1QG8io_(iaGQv{KaJ)LMnK68B z)@j+X3X9QfM%Y?jjjLhf>}#?<-c9RHAv&`IKz5EF^VNanxA5!6HE&7p&3*wWU#)&O zv0$|gXZnb-Qe>{T7Xm6ckH+4G2VH}P5DE)EJGu>BKz0i`1>P$kYc&9n%`@2!JLWjq ziHsEi4kVEWZ3dkh0}Wqc`Bz&6l2QP+oX>r!rt!Gl5nI+-oT`QL-YKOdQr9J8Cs_8r<_vS%1={a)LAuH=f+h&z(w zgTNPCBO6A(wvkl)BM)r+YnxfX2+jX`sQTzOOZqc|q8}>b?@0swP#up@e}AYgE?B7v z%-RALYKiDcgVr_zJ!zDnCk^6+^A<9D9rUDeHPYPE9Z;f^t7QbMDbb4~XJ3@>Z{S;y zCNDD=pr3+CzP*}090}FV<-)TX5X?TnSZZ+eEb@KB9h-oid3Sf1s)kh~1L@EVPL!Ou zYti!Sby*sjWxy^@-LZHG-|V450TzsZvS{h$Y7HDGMsVyBZdX)lP_gcF<*FE1r|A*G z2=#bY_&z+x=HR+!BfVGcrG%{EUf8Ee6;up~ue@_ES?T@Usx|3vD>%LjGa!mIp+6vXep&3lTBUb;T`=FwSs951uV>I~sa6$WAJ|jl$Vh z5lN}WB8E~q?2rgU!kB_^k~ek|wR!Qui7+)fwq&R=9eWC!13pJ8gV#ZP)Z83B)?PDaI;jJf`0cgOGXdNv|MzyV`%`ia|IeY^t*x7?rrxR!>6sVeEQk54~imW;c5Ecpn*a^$JL( zD)YX*tdhC|v7B#vH`fDnk7(dovpHQ~x;hpOpnrkt-@T)2b*zHG>h`hr_^Q!MA)HWy z^oR&CpJCQb#UKyQZnL|u52;oZ{8-2CxT$wx60i$cLP;k>Tr`biBbEiuyz%^}J&8$(!qYfF4Eg z4U7c(4P1vb)zd7RRTKle#zkRKxI@Qsi>jOK1Uo@ zWmjL|r^1>5f@)!;mMnadY%2AaoDIwviYSc{G$gR;W>_737(-8qLa{44c0V0TTHcY; z0kp;iYKxd@Tv%s4Ev@bW9gS{lG2{Ao1&X2e6NgC%Q6hH~@Ap+B%OY@F&;kZ%LcgU~ zC}5ydS=fDt?O~CCWJ+cGAwh+1M~*bVP9KSPh1Srx$(-DnRx-7bc)Iky*KA|ZXrYSJ zv6C?+0yBbhC*|4KmRk?=(Wl8qE!*XSG#d5UHqa6l5xYAOIvDaXt{gr4q}k@|6Eh{+~30@?eP``$!t( z)p$jVUj9%bE%oVZBMKh%JOw%$aeA>kin$t@(vO?PcvTCv%1xNkM9L?!ES`MLQa^pR zSp7KB#jNH#?^5k8e?4cKJ7T`l&1=0OqiJs);cM{Amfmw`tWJtBQYOlX%dkOKMfG$cLBDnojPZ_hd!F4r$I8IE6cci`Vj z9GwLoY(@q$WNR8&*;fsU-X<~qJae6zQ`2txnX>J+=lsD=Or_(oheusBQ*LgW`6ttN zdo)hXzc%B!9{f%t#D1WJ<5!ODq7xEi_7?s?W_t?&-wowI4Dih8Kjc42M2l|x=YIjW zI>~YBVdRG%cVC(+nin>CBnvan`OhL7jNs0Z*4+}Gja23NT zgqLTnf@q)i1Lsh}P%8+Q$lKf3Qz&@1%KLYtj1`!sNsjMb7YglB)$HjqUW0I>G%yaG z>|?^&xET7WfZ|u5YDX{F#u%g=?6@?@*ekP&SKGeNUlzZQ3ITexa+Y6w(GCK>Y%sIjPfg=LReaGuBap$ODkgfurPNG74IB&OV7mRAT4(u>vm9 z%FD+3$?{s_I?k^&#f?36$Hc7}{fVI2kVzvoR%4w($sN`B0ZBgQcp@n`8{KHhV8!Dd z6;@wxzqgrv&p7`(`~p&TTc3xTbi?-$$y(r}J=itH4j3keMzNew5Ee_r05Z zc>_7Y&Rf6h$9J=zs8Kx}&^Jo}J?c^*dfnHB#)=9sSrdqkbJ8-D9N=tvT})8);o-^W zNduKTH)K6VbQ)Z}#1ATX`e0Hwl>JbL_E`<Inr2D`y$i zY&ix*eET?(39%k_QcbiT3gmqKmGRDrT_2nvRG#0F z3Ne|-kx8#u_PSKNlow%W3!?rkS84jQv{x-85gFLsNZ!CP1}Bid@U{Hza5!!gkE9k4c{9xipE;ij9{ar1_IJ}28h-pP+lplO z)5ffSIAV3C!&gzfLP#r@qRO@riX<4@8AT z01HMpt^1MRU5XM+U)+*)AFZ{ivSfL_k^HJLvT|q6#MAgGW7|uexYEQ_pBr@)eJM^4 z5I_M0@f@|g5 zs7~Q#fG;b99GA*Kfcqu8UY)=a)Pno0@x@+?#7a*SNx}qnMgyZL?OMZVqBtvbl%u3bTJARh_IWL8Au!svP495!J<3Eha)`?1a z`b24Su^);`ay`RM0OYw7%U->fM`8^I6>-9ZkI|Y}SYHuIBGcRDV55<;;iNJyTh0?} zt~p}UP%h#jU^s8y_q=iAIiEq3IrXf7>2rU=WRv}b1`N^8h$6$5CrZc4+$lT1(@Tft zYTD}(4e|glYK?_%T<&%`&3|lA<^Q1%!KlA@YmO#~>^E;wkcvM28*i~tIWiu^viHR@ z3nwr-=mq^r(XE1Ac9CHWzlK(a5{t*82_@i)#`$~NA&jAK^}VR_6^ob^B-~7TtndlR zx%3;P=kA0>fbGME3ibvTBJ|o)%$(=pxZI7MoP5^)<;xA=*Zo;&y!`O&CEKya3U!Hj znosOO+x$~3?c(4-60?);?tl?!*g?6(UacJ-IW9#GuV%g+u?|~0xX;I+XlbQu z{ZeTIR_$FQ$sUFmx92A_+}dla8b+E{HWACk1hkS50unOj8H+pcAAj_BD;3IlTRfDs zXcbNTl*&s=iYM4AN~&=t;QppqPbfI%ctiY|2ANeDNMjHTGEDx^$i_x{J&hyY{?dNtt&ViwlDOBA z=hWk825OUdGPC)lQjLma$V{{*3$Qn->MeqiAD_fPcT~3{h5W9jm0#GLhNO_zZJ=Gc zs4^spRJ>2$PD=5TDj5(e#5N{%`dT_xIwkCpy%%$z9Fhc4Opl!{mZ7YVU)^usN*$Wy z4w!=_E*~6L;!c&7SGMOEbE|RTn8v;D{pwiZimWZHs2P-ol55ZQBt5I8HZ*-+Pyeb; zE?|ULHJmFY2|YjUr>v+kk>9vZ*OC}h{9nu!v;WTUK)=5jUJh*n|8J$) zG^{6qi>dmz12CG#rh?8r3R!7IK)nQsF3&7<@_vO;%#xuyq=bac2dqlrpqGmc<9F7x zPpP)t%sV19*<%JtJd0e3mTn7Y}a;fR{;ndy~ySOZ^{Rhy2ibs{^qZ{6l z_4z@X%~ zzaaN@Ch*m90;2^Pu%B3D&V%IMh`d-N&w$4p*`(1V0dIT(_Cq2g&@{Bg^j;s{yr#aRsW+vpXEWR#*? zQi(;tDQ`uIGm-?l$C0QU|K?^@Tc+?^ zVa9GHI=jNnGxAxw)nXW@k5KiqDjWf^U@`G*y%&D!dt#a-RJCTTqO?krcsfy5Lkkw6 z0uqY_a(UhNO(=sFu(TS+E>>Q&b#&qVlY0HPVx!nj?qkr?R2l|bfHQTl|kyr zCR;L#t@`P1$yRO{vCMLzvCq?SsSkcQc55gYP8g6Ruy$0F@-jiA=5muU=1w_{6LcQ!xW zEf^?%;hu;4k-aDKmb6N~{gS*sFyY4IE#UHEbLLxA*iFOhIoGx`Q{DSb=bHd(k6Dio z#up#e=IBxhUI1|LHdJ0~UXVIm^z~=HGB$G7!IzCIAdy0`Qn5Z%d)^!D)g)_C3egD-~X^FkZ zmegdfo0l3@-aHO3Pd*1d?qY%e9G$ggoNTL~#G3#Mgf^#QoCN%H3Wrn2J)#6hAW@^1= zH|4PYw&Yh(krTmnd_}6{pMCi>vdn}Y(%V<+Iz&K7xge}H(Eb^|S!Z>tIHH|UCj2IwK z)U&azC7$HT8cb~{H`OnCxa7H|DOE-WV_Mj8)np*_vDn3<+z8c<2Cois=<^Cm#>lo# z9>ZYta@`sUj|E%w5=pYGVr1(oFyvvp=Io@Y=AHP(*eOxrL{zcSjXf-=Nra7!slODA zVQ$oQ{El!1diNo`lQ#y5XdJRPFk3SYz-??tW8+-=G(P_X!j)LW=^_JP|G`ozyqmNq zZ8%2yu=*@U>>apnH$RHapxoV$<18AwEi)5Ns#T35u8FVF&w>3mVjIQGTG6|eBj?fz z(wZPW{QZ1rM(eV#<5#0N>T9a@6GQ0TjxWP+xI1^G8}4@eWOlpT^u64sWXt@C@dIo?r_$cbHqBG{E|OF!_T}>w2x-I*N$+%% zQnK0ez)rXy#*q`JKu)t!Y-$UW4wKr`n(Se#Vl~? zU4r?1Z>&C9myobHy=@vg39mM>`>eW9k8|rDvj*85Y!fy`t_VELGya8vm1H;H>@@^Z z%QXj%$CGwg6WlhC<=q5G#Xg^M*6F;ra?H6|TYvni#-ay89GPwG%ISL@NZm;Lgq_NM z1L%So*6ojb*zg2EL<51b5GX?e0$-lkOuoAW_Rqt{ZIx+YjNXg$ep>i8m|%>z2>q~% zXvk!QK#pfx6z}}PriaAW&;kPb*-c_uBx4>d_T^6$ChhX*wk91*FSsZPtNVv;gaOy~ zICLG%KAJiZg%#{5balZVXK8ju^8Bz~id58s$FSJbt_&l9s`WMc?8E2qEDGe3Z&X6S zhu+BLg`Ub`8yOCZAqY4Xc^wK3#_2v5$l_;EB}`bB=@xK#(a%R`1|S?t8I8Sn0YBGv zcta+>3+x_N5WW`KU=Yibwx%gC+WP#y3-|gn&&Qty<#K#R)m>Jjf}fr0#svQ*HBj}h z10#Crw)UrkSQUKH1LL1O$-hkvV4_n4XG(ud4bc4Y^8fFo21N3^DJa<>Mhuqn_=Wd| z|J_K=uoNrPmXrf8uhiHmq{71xn=Gyt~q22yT=xy{Xa?b`E zLvotEeRjKNux@<#@a7vT?B2yLQ6;C_FiW-ECV3Jr#3PnGVkxgGdnc5vS1*uEOzYr! zzAP%^7Q^H;M-XZum+Nq0S&h7N*&GPEPo|8RfTGT813ij#ZE1jnd#*8(3qd^jVar)A zmaZ(p=iLFh?rmP6AsEOoE~e~p<#*~ zLRjRnKoU$1n^d-UawobydvhE*hr&pg6J~rk4h`JDb8Mao zGIcHSM&~?E2Q9-Qc{Jggfcc1pXHk#J^GNi2s@h|QcvE$|gP&D5VLdo1*vj*rZVw+Z8g;V+v9D{kO|1Fk{MCdv%7y-WN_L4RWu{vo^ZAvD!$u zeDPP-IK6`){^T&Z~F`t}EBY&I7mx!AtjeP4Ne@^6<7 zm_T-_eLt@49d=@NOJ~+Tav6ZKh5u?PfC_j^1qr~_0&kPZUZGb^qDVMa7`2#%9IH*E zfS)CdB+GwPay#veMD}t&F;+6E7rbn5QA%b+^gM};NOaDATT==ZS1<$^tU+Yi;3mVL z07&ee6`2OA*|o)G1Dt#9e*sz^<8zYLKL+Rs1;$D^+UsnpT2xjCl0tjqxL_69W4BvjFklPvAnWW4?o629Wascgv&QtGLE5Wu`oBx-D<0I@FiSsXG-8 zK2v?*zI>43^ZbP4ZW)BSeFoP$CS+98l3E{&IK#*aO}utK!aNQd$E5mZ$$kru(Znk< z^sga?h5tsp-8hK9boO1E|F9Z!=`KxRZqfJ~Z2s2@6dkrguRwo?t*%7XkC8z@7ImGY zQYst8K+c%1AtYzWY@mL*2sMf|R_q1b-H(jk@IWnv0Te%DH!^^mAz99wq~@xS_X_oN zsqb3v{rzk#ZhoV7FzJRqC+M#Gv89q;KC5-TR9_2~h|9N}j;&ECYEB+{!Rt{Ywh)20 zH|HlK16oY7OEs3UZzy5neF_LMBi7M(#(&f7WsAstQF;2hH47+_yc47 zx_txuIYmyScRa8M^sybONmJRkVMB!V++HshTM0}I{rWmEO2~|P zW{7<2iz;)nO?G!Qw4tJioZXuZK@&Dn^pXT#1zGQENPCjYK7}Pvj74 zPp@W(9IChzHb;Cv6t3i|>TBv#> zJ*Z9^)cxnamXa@v0KL%~`c>RW9o8Z^IqsVquzqCtMSd((rQ|JCtln&1_3=vZn*N2| zGUvU|`fDjo=Bq4jk>_7%n^iWUntX~?@y+(zw7Ne+VtzPl9{N8!5dzGpuIWtIOtx=vXB>s9A2wy+R9MjJ2^eJVm|5`4F#qO|L<M7_Z*I1unfG(^IQv{=m!@>kZ0Yv+S^8JK@0X^iUWbC7Ho%-w( zQqw4r9idJt3d~r};Gj6MQ-pPq^pTAhXUfigEk+WHTDp?><)AhCQh8XE6xzWbhZBWe ziMB}5m&zsCVsUBNLEhidm&)D;QX3Ic#=v3~BAQnAtcVxQb_Fpc1P&1(Ek~ZHZ??Sh zzPyfCIXEx1=8KE4lB*TCQwo1yDwh!qgDT=l%dmjybG);ajeD(rcK_(ZQ=@z2?}pD` z*X%eQe}OeO%YOoE|EdJ$Y^T4Hv68=&vA^>w{|MIJuPyZQH8RUQ4@DgxmO-@VS2IqF zr}ITyT)tnqm5%#!((pUOe&?yYre zvotXkRMq^}@*;A=B;0~6D5f^YjAO5Iu4qPdfbp~!L-_mGh4G`RSCoePQ5mY!;|JC$ zw(_5A!KCFpHAvAGYcV#Bv}*Whg9i#jQ}we+sUdmqy}FTnm*59$*@lU?zDzW4Ub(Lu zBKXO>rzL%>-7P>beUV|;OZNwwC+=evytta(Li)_Xf-&D+8r0FhV@Kg_@XL?^SM@+} zx10bs;vKkb9qPFIDNA>;1&qNRW$AB#pK3uwN1%_6EcO>}1q;WaSVD#J)8?XbqE#m& zxwUw#qVKQUTSal5Af80>VuW)jvlxLVBP3+g3gTE4g*c-Pwm=-tWDZiRB&b1G;>i25 zr^NRg&G7f|1gg5wq8wDXKq52gmlhL&FKLUfk&j~^qWx>9ME^raIO4I9;2~9R789>Q z9;uo)bs?*XH&qeQV{RJFbC|(;i2y$Pj&Y2ZGcHd`{o!GGbt`BYpZNA>8$rN#Q#W7r z>ih8L_asUG98cu^S3rSx15tlL^Q-@up+h_9G#}96rr$AY^p1R1mEu!R9K{1g=M9U1 z-W*xjp%^egInQR`6eJKf%RL!D*&OxeQ&mPHh5i#R15Y;#d@?Uo&6`Jp#9`Ie?*s)< z-6P^}FVm(lMs$xB6U8KZd5{RQG<<=dT*=0iy8t|LGVYjioxLt<7DoQXQM%KJz=%r0 zxeX3hVZGgsF4vQWuhlWrd%JkGCaIeCGYj52t(AP0EoX6e^HvRiv^c#a5Jt>+MjIvb?y6;K@E< z^C?{3$+-W`IieId%AUz;2>sCqj-M;Csj#d{_{bXko_77>b*k=Cu9p8l3bfw;*H%Ku zE$sf{CavFb3rJqn@4WQyTMf4USVD1^)qV0Em9W3LGq!4pbhPzZQfHi_p@hl_^`0|% zs@b^DFZ5BAJm^4cBnd#6H6Vn7GX6rp3@eCK+^2uik3Q+sWE?qZ3hbhimWq(7!;mUIkQNcq(;#%%nP-ttz^(+g$wKLPZS=IA^++8 z!sY+tS8L?oezgw#D}87DUq~P8e^gKVhx7mivoEu(_WFrSng{nuA54e?9i0^UeY?2I zu8M!3^l8F`nb-Y|^x=zL9jI|JcJEv}STk{3wMzIZ@7&AD&KRj{$?0wgB=Guhv z%;&kXxDSz?V)~y>7W^@I-&`3!lEe-!7ohf^gfU~3Q3L4=7})!^4@o_B>yb;-~Dwj$$CE^$ocf_S=!zo z{=NUWRt(v{asM?gCj8H1_m}^6?Ec@!#T@?CN|@VkB^JLV(4aL zf0h0INqCv7^5J@yChwE4HC0ENoi2Zo_|^XL#SMeeX59z6GLE;otN1VSd1U%rKRf^K z=H-{4d@r8A^G8xNagA80Hj^K8dM3hQ*rfky?{-wi-{m#I62ewN6P4z%*VgZUVGfGH zjIAT?oId$NyvFCxEq@uViLSX0M;$uxN;t{-J=KQZ|DWrMLtxKH32y?3SLipU?qtg=KSCqO`v#q*K~T`kIc6M}fJ*b9$3g zeYJxC`r|Ww{mb#ErGGsHkY!$MXitH6c`}zLU!}&ih>|Ke@(GspbP+k}z)r?-jMf8X0AH^lfG19o|;cI*}eE*QK$Hn#UOwj-R-}wKRcbEVo03v{c`y^%)K;$2eth7DG-*6S_ z!N5w1-EX#kb7YC!PzO-j0&Ig}_K6Z+8?S7N!C3pj$TlS@;%!m z@Nx8-U@X@UMZwU?Yr1s)i-tO@j@OQ*i3RaZuew$oDp;F7ClKz|A+ z?ezbH9jJSX#_@{u8;&hh$jUsck7l-QNjW}3Wx*OqMSCe^N{UlGZT zSu8Yd{yNv@@=>+%#lIwW^~di|Jg{lGbla~aH3i2bW0Ap|20HF}LmQ!aD!%x>u}6F$ zFB)gh$y7^X2cS!(10oymw-Y8REvY}%He)_std~AjueJ66|rhF5l5 z02Gmld0nz-(_^3?*8Xhs=fq-x$)jNNTU&+oxdjwl&y~Zmfti5_=V{Vjl^@5hT*t@% zjQdL6Q86j=xO798`hAJrk7wjpZSNKru?{4Rji_JX7(;u$ zW#i3x6{s|S>1w`KvzR5A)&$;aHFVa@`S{zR$8MB$kgjXbiR;^FYwRQL~ z!mdpQF`xrT|DLLbphNe7VXdlV6|`5F152G^&QG(@c71*GS_ti5xQMIw?Df}+%I{q{ z8-v>g1c`^u%^6|e$4IwY8BHLAv8SRC-9b8lQw>5bW4nW*M`AAh{4pzAH_)%r$Z`A& zC!wj&^Y)`1=8mcCr?tksNfS$bwhcj`8I@`?T|uN;_8omsIY& z)9(GFyonrjO(jMK|EllC6$P-^I@4iQY#y<A>kpAZU1;@fdX|}+rp?6A*Z~H016g!&! zY+*r4Pk_XX!7x&R@L1*mReWs(W8BdXwNIf+_2F>HOYUv$gbmqo3&E}OW$Kd+#gsRb zW83y@s#zYziMGhMN?);w~63UpeG@%}Fagg)O>P_E_1T^A?;{B?irFtcO@@ zdMW>uIqW@!bdNu9>Xx6q02^2O=aJTo`RXCr+$_~2`rhSt`xO910~l8{b*8zh6MJ}s z5crEwjSMVxHjshohHAym@HRHeB1re^8S_SdTmnS{D7g;fn0J5OH_!+;`^MlT-8I1{ z!kA_{;=}{xaRLjF2DCYo2)u;e-6f)}VWp#kkO5P8U1>c<#KP&fwy9_D!JeNPNq2d{_V$)eu^q0@)I2%?=F&gOQ~rVbl5yShKU65I=edCS z<|84Oi&>{0tl8_{qhhB$FBm@k?(tHgP|C~-WNSw=ZJwm{@MVN_kI?l27#F3ILCF~< zWpfF(o%)@deZmhsuU_Gxq_XJxh@5`D7H;rYd@VDJ|Bm(Y++slrv)|p5qBVod6k6(V zP}=@h9yg_fuY&S9wps*!9s*}a4^6_OKe&k}Dtz(WX`Gnp=z%^8OMEifjc5Z1mQ@vm z)cWBaHv3gKHxM>MC9vDUv=%5o(1tYlVrSq-p;eK+>TXTY%!@VU003mH|FA>o+S^ho zt&fG&rB`)(`!V82Y%1Ry9E%F!>nGkNBStQJc+A(fL$SSmvZHs zL$~Osh!@GQaV}@}y@$ZmaEib##&r)m@V1KcN5@ATeY|YQYz%WrU&G|>Hncqj3mLoI zgOj-9A~qt63BJVrLAMhyR*7H4`kX-EA71SXb!=41+;#ND|8>8i{EMByOD;gnKt)ON z_e9m-n|J+;;;ud|YW(Zh`{m9Z{R2+!84qhd>Bc0^ifY9d!A~HFtaIWzwUoQhnQ`HE zD&{|j>mv1UeNp26_*U}F^SfaP&d8!zJu4s++aJqUb>8y><-KBh=!lG* zfs(>jSe0IQI5B*WseQLHJk!zL7#*}oG6c;7ZV{1sN|`_O`A=0tBw`^bE-wBOa0H&n zx3_U5oB=-7!S(dciI^7|@`c9AikS+f5cIsI2`3aq$s8I4O@A|SXhc^kMl^Y9Y2pIkGoeVd`+fxcs5|7uPvA@?a+ArkM+8O+0BxD@ z4Qs;p1_QaOW9lwy1%3wvH;HS`T;4HfUlqy4Y3az(v*ji&Y!o4yXVE$xx~6wQpJfgh z0|I$~lr?i%{}8ZGnFhzIKy)#a*AkOoZ*{F-d-^#Z4iW3%9wbkCsBrtm^qEcYT4 zxyS^GarEBWqG1d^FL#(K9vBJAOCuq_IwIx`_&&0cb3{W^4#)uqpCceCdyTHt#?yt^ z>;Mb<5C-^!bErKS+$;dJ7P<-PX;(Cm)$WVWzbFi9 z`Q~Noso3+Jk_9sHNYeJs*4Dw1QG$oG0)+V&ObU4}J$E@&YFBu!Nl189#FPpDNrJ;yVE6WtdB3wOmR4(Rw@bDsrn^y@>r?W)2v=ql@w%UIBy#nnJd-CKuG1z46! zfus-p(C}VVib7XN$f$J)XrNV;xp@@wM?_SKC0}Ed&N!>h_UoJ`82{NM0IAoUy9L+0 z+=GQc-5i99A=^vBDLrfe49?>Nug0Fa6HueqT$45k zvU!;`kqLBXH44y-Ph>UeHP;@oS1v7rlx^0y>@-^fRj5^dSv9~kGJJ+8@t$QP`w`%P z=Nly4$7lDlt{?Ugo@bw02!=a#ZeVXJrB!2yQ>lJ;%+Gs0Csa#c&JCJ@cVCCq6{+la@^ z1IqEp9RMst1x?)cHfBI)?fC2WHuM`bMQ>IeB#zuMzQNx@p@1jvn5v4|oaiuvi65@O z+q~)6;qMR@?`&(fiIs+T6GaLulf(OcdpXD*0`K5R_5ceOSOH&myy^URiJd$~#CcNo z3-hFBmBa}{U;z{H>oT-tR4BI+MS^LDj@|v6#7-P@ybAH95}8wBH$pD)t^!uFVMWOz zGeqP%8FiNll5G&kWuPwH=vrn_GmX1zPjso`&NL=>hiL-GNyvbzE;JSOnBDcbw7c;{ zcUQ%O?hC>K9Qaopiunn-$be@uK^6}lj8ybIF%~qP7Vm9q8x!x{m)KdEV;U^~cZr>G z-_qYDb}JQqYk!y6efibL5r4R8{P6pUhd+}aZk;eVcjqAt4HP_qUmt#WZV@2Rnz5D4 z9H|Iys)XHTF|Ta%Nbq6oO7%0W@IDycUM3UK0&5~cPTNN%SzZP|7fE*MSJeax<}&Rm zKU;K zkisv37x03>jPYZyzk&P!kSD^J$r+e2Q$I}_nihJ+{=nr1TKOAOR5XL6T~s%Ztt zm_JUP2dLs>Pa;SeZ<(HCU?PChlKQ-vYk{Yr+HGkG$ZJdY;81}0Y7y)V@cy%y`&jw8-x0{CwK zL<}FBOJdsh=Dp$50fP2S4)QJO4pgFE<6k|Az!=Y16p-EypG1})JFagv@L=NY@*iJ%1GIze$ z;{3b_jLofGg-E{BBImk*!HKp?w2usn%4lGd{il@HL4B2|mmJ7%)deJFL9cHqO<+;W z0l9`pRv^5OA+ZL3=A~7!;iik6l%V63;Yui4>9U_hQ}w1ZXbfiZpx zQ2y6R6{L6CWEEu()0nFH;yh+dtz=0NCg+$h>Ych6XS#Cs+K0$n%lxsn${J(et=jb> zizH;$$Q!_N4ss368}t+{d^mtajBS4^AJ_o&afFrz0IymZ^$LJ`mGWQXMPhFdbG9s+ zU2bPSEiop-b_f&7en2nuQq4_Z5FUyHhZp{Ugy7{T9!1_sjs3GDdO7HGMC;@h8&QXr zzw;+Ktp;d{)7AT^8I|6m30U@jS~89K^!^K2>4esa&Cl;mq3#T~fXc6T`kat{pSr#{ zn6Q+3KYlX(iE<<=tjNf!yFgc?dk|GX-&T$Q>#)<*r>3%&uh$?UF%bQ4*2{6+aZI@~ zY3V2cv}jMaBFYhJ^qA20C7Z9^81M}XomPzF954aNE7!@?IO`}plV6l>hxKc{Kyuns z3wTc*w0hQjP8yH@Dec6S47?N6xA{Ge4aOVg8w0- z&?d0AfEP=I9#j0LF>~Q1;A@R0RLAh8`Qdo z6R|9X=eGXEYYCb(LAL)!bhEj03CKSLxH0pWa2sHhjr!)uV@rg^{rH{P3Thew0}AcM zjL&b4$Y0?8a4I_uA&FlI$#=>~6YJtEenj#OriF1f1fDxC*%irKm(KPdzpgJvV&sj{ zZ&%#X(j+iCaPpTQMx|A*?C2eQZ%)uTTBOgH(ak|&r*I55ObxvK>oRZ&mU!3@34XFnnss?&$etzjRUd_FZQA-K) zyO3A6#naiE_P(Y`mqtei6>mRBK1)fMoq8GJAGSlRq9;p|sEQFD)a zpW8m==Xoz5$}^U`U15~)zS2(EP#WGIvpKQfk+qStR)T~m4j{1JtmKn1=X`*% zbt31V9Es@kYE)U>_dfk{lnQjdZ*$!@eyg&3O&Iq`$1z_M(V4Jm2)&qTzf*~b*i35Z zi5xi$6V)IsamJnOef;uM@GXn={8(lB6)93lyIjdTzXmY^U}#(->HB?~Jw&ZAbpd<6 zc~b6j3c>1&d*9!nYqHO2ItC#1n6k?s3hlxR>m{5XC;rul)fi_OA!-w?_JWRO^oI=bE2;(t zMLw(_x)ik(-B5fp?TvYGnEU=^}Ew0~$}O9oMHJ(np}XHapwIr@%^51!hf1U2s3px!ft8ck`w`rJa5{4A$w z`(B!^x6CH<9wh?Z?I5P_q;u~$!Kqju^0JSxh?Ef%T6O=CxG-lJ)~CkRhou__n^VEA z(ZE#RS+#D@iw%BumM=H`xP@CG=R?MKW=IAqIJIrH4_&*G2gFZg0d6WEi^?GLp8VJh=L z`3!i%2o-Zo^;!*M9uT-)EipvgPa(Q;h4KYJt@qZSU!T=PhDpp{fH@B8zN4T_bG0sS zam1xwB=*ai1mHW_Zk95noM^VCn7>jL?hZ3|ZDJr>inyqMV?*8JVus~Q_5qQ#Pzp~< zC3&kE$HOKSSxu5}nL z&uZIP0SRgn=D0T5$Q1mdI(^sXa_x-76CPQMIBeZv1s3m#l?9#}AA=;e_Sg-W!&$X&idqS-R{XfXq=|YsaaP!%*cRY$2U;X{`j{|gTYG#4iLs; zsdQ^dWiD%8IkCM7zFziN7q``mb_;0UBN3!K=H;Z;hyCubZMFP~Kt(*&^DE<#uRSg= zfjkh=G^1c_p?b?}y;D$!FlYE`{sLI3o?C;vL}y{UfXDHxB&m#fS^^I(lUuBr$!6;E z7h zR;l9tK-IJM;yy|Tz2ReM< zB4^?e=nH}1fXV{(Getq@tu^Kd=Rm1?f58`PCg1*kS$J)*FnWZF5=yPpdl>zOSFl># zq5TCd?`58?+~lG6n>LxhVi3tOekFbOw8km4NAXZXAEJg*Fogx$r{N$ap=jA=3sA)P zptu+IL)3&*o`sSD1ny3!)(OsghG-{TS#=0~LJ2KoiHdHsA7RlV6|bh3_3pnq7IlT1 zbMZ=tTqa9RZD_7_k1k!vLPKH-4)PA`VGZHqXgA>%<06F{opt3onOR+36)P!R` z;`E|6u%x2E&q3lc;*}yS*N^_Ok~_08K*)aCz}8sHR<64dXmV~5{_qmm-_Ze5dSFp@qe<@6p+%;ni5U}|p)i;%7(1|Vi{iWG4sry~Orz$! z^Gt?_pG?{P7#Yoi81jNH&VWmw_T@sy>Cz$M0e`HeU2k_;^;i-*HZ&AhYh;z?gFA|tN74!_q-$7 z(89z=NgPeoCWuc;KB_5mw=8C#hclAmm}@O*7I+Xn?A<9X^7D6VVi;(fLkB^>`jH7l zh>Tb^59?;FtWLcwlwenVWu*Ev52$&JIzg1%9AqZpD%$yslhUb2V?+o{dO#K>Pzh?f z1=YpVV;Uu;ehI`?8t2@gDu~j0YOsr5CJ$>UA&s<xStw{&d(lGYL@g^j8n70vgtu{^w>JwwG7y{#qs80EUQZ?9J&qlvsSPW)`^j zuA(boyEj$#?t*dO@~kE`z|`}w!L9Dgt78Rg#WXe6!1{^y(UC6YHwM_%)+j@0EXm5& z1lnj})?j`=+sSZHO#2irH-Mb3|6M@;1gwH8|L5Doco5-N8&_2TO_nXdJ*PfxuMRoO zY`DPWJ=|!H$O9rSp>Rzf`6;5$Ud;6mLhm(-zdGO!5FzA@=!IXa!kx znl3hNEO75WkZ;LSuxhYbvbK|>J2YBEb`7W)rC_RpqyM5M5>Y9tm5iGT3 z{D}@Jy%2C{a&RDZ*UE9l;=F6qOW5G$U$(APdCJ^o)^CLDX;d7YDIT2?yl_NE zJ9`IouEg}(*>e42weu?vuNn^*@^n|J8f_XGfxovk)DAb^8K!ws_|DRIJ~h3wdbTo2 zmLlf|%u+(OXj)1XJqA5|iylCvJCl#zy<(HyOx0}aUmq}kbR+)({IRs$HJKhrY{tQd za=grxk_-07zpuBj?kFZ-X`O-HdoiXm8aUqEcvP#lcYLT<_q(lr$%rIdKdLfgey}(J zZD4FNk#nZ+=78PmbGuK)$3AOYDc_k`T+fUdfgUlqF&0i`XB>Y1spfJCcBw>6mDH0! z%n)Kd)T2679xZSVviab|51vC$WgS_VwE4IM8!%=?XK)S6vJla%{ob0)r{bY2(5V}h zs4@VI^$?sq9{r8Qdt>~Swk5y1-P57G3_)H4p*-hGP4Q%?#9)24)r5!hgzPw0qOLD5 z_n5%ONGg0(N?k7yaDcE?G}a8NJu+1cQv0cTr!b{CMJe-oZZEdc&;VwCtjVE|SeKwg zZ7u_xGPr5}>8bWr>zwQ-oONZ*N>pH1J*`daeHPh_4GmV}PWIP3z@fzesNcv3?i=58 zqrP;Tf8d3V-qglV#ui)0}UR%Fawa~=dl1PW>0JuvpQR2*DPb&mh)x{LerH= z=z=u3IFlZftoXGbuR{tEy@arXr9rP~j+AIow?ao?`VvHwN$v`@oMYa#Ob4mk)4%{= zStq$+0IEyyDq@mF>n2NY&XlTWUye9d>;(KhYo|KvRYdl(mRqZ%;qkowP4;S67LaL7#}ZC7b-pUKcIdeH>hce8%m^Lu_C#B#*Dh?B zpX?QV-`!25~s*L3y}P^Oc~wh-<4h>j9-qrQ62f^LvpOU6ht*NbTrVOL#)JaHQOGqwpwEK}USQ9hS_kvH{clLV51i+iCd9r|Sfxx|+GWqB^OsChC8Lw-f$FJ*RtRGx<@>GO#$$Sbk z{}cDxq@_b82B6ehX4G80-s|?V$D1(i-G=Zp=C6@u*XCV(Ph$e4$eG{EGUNFCeq9C} zQ__u80>S;2xO*UnTTVP|hU|=pb3Ju^^gB=RZnd6LtzYZ>QQh}9K67^vA<9_*xk%YJ ztMAeIWd6!pA%ed|cE#$@ixG9u-g9+|;YH~%B``sW+dxG^5qPpe?xjv%H@Nhb5NoIw zJ`ZN6hs+jvS1j-aiOh6Z8G7oUJF^Ax$A+dkfQFWU(frlEi5a(&vcnmW`4mfy zKzg1-CM6zhvqiajQj(CENk5PoKxhaDWYSH+He}deBTMqDEA-S%i>*-+RggzwsB2?v@`bk?Iy_2PJHt~;g^TWY|*-Lc~7QdD-Z$9!6?WTEGa=!;&3*_i- zUnQ&A(I&QO0qHIYcqx7pg9sIgyIC0y29QWcsC+aRjBz^Rid(H6L}-fU=PByPvyeih zUGRPN3G7v&4n(lH)fcWfWN~|tLkN=@#9Mqq%r|9tJS3Z zwQrat1L)Ep$T7zIiU`o;q6ycl8-XhsAl3W&u0W}+{3JYdNe^m!P6W;{fh$J_H<6ZX zAo)s^jsstQDMZE_&}3&{&t!8W4}R$*ujDs$K`2$?K3hFc8h6Q6hkHDc!SJ0MS+AQnh{ZG;YEwB zA$9NG1Zwz8@r}2N3Xd64JQqV4_r6|x%|kLt7+GiLUG%~tDX+e$d)bJUeO?@vIW8J$ zxs9>$d~a?hdc-b2SouqAYi6@=?r(M8c7x28#;RlYs-i15o*6*Wn9!@qM!_6<^p>HX z95fXRb=5s2<_Pj*(<}?=pMW6!x@Nd(m+T_sBKs^>3_9jR4rfDCltgo44bwQ|#gwd5 z@6V)KZ?s&^NJ#|!3akgm^yq$SekcM*y_pDZcTsg1PscCz2p z*$}#P7&=-ilrQNeG_7%cyB_G6m5}ri8bj^@qajZBGOns>q&m`d9F5SP6j^rq9v(nd z;{dr+I(-vwf0@g+{8arZ5poUhL@!BqX3z%oc!IOIl`E&7Rs&r*(9{*$D;0_?CoXgK zQ*1HB)9gYSo8}FmUTmU)}e9b&F6Xo&!|v zMokxM)QF?;KU6h|hkXiQteQ*ON+69c)pPl^YVqX2rM4V77{2V+gL}!EgjXm|x~>8B zmA#u7Cta`W$4gI&R9DLQy<}Y_5KI412|Hc8>sOurA@mkyNQ$bqzy3wcQt+W54fb>B z58%0`T(h zST3m~nOesFsXo``yLXetc5fc!7oNM7w-x_oI!)emJ?=CxYG{vNa~iKTrsUNZnJdG6 zYaMMhHy$Y~{N;2j-fFyDH#wE38t*f7#_0r)@@p=3Nrv`dWMe|dve4b=!J8AM_vUDE zU+ve=Bn@*pe*9inea3K=ZxI#svL{LG7H#UGzH!Qp-$}kX!U4N?PJ71ruCklT^>+^i zWtc23X~r&m3+6?%m<{FgRR89t|7hS3j|yW+c^VZC=IOmoS%e7+x9IO{pG^PiNA{%* z;`F~AUcQnkons)AEnl7}ljCv>4ZNVHfdgxQ>-v@jQhuFS6C~hv7LzYq%BsHLV|PbF zUI#uan0*iOcEP1o`+;a>SE(hgr_lpM`Lin_o zR|erCuH}XenMU~ua#!yTv&y^*n456pZCBahpGY=p-kVRwQb=mhmU-;Iu>vFt_|8WU(mU8 z#U)QYj7(g=xAA0O7WJci8;C1ETYX!ha49+i^6vHNI{#l<7GLhzlB;WW1u4@ zn!`dTOm2c;fof`ZdVSCM^NJh)T8E0CUT1Q1rS)iy?WsT5)f(44enx9T?2XSiZrQOO z?PrI6?P{}7nkG7v)*^35C1N1GI?s<8|L$n`V|Pe*#?9mW1Q*AmSNG+~TzQ#>_so>K5T z_f?khAA_Y7RfnHk;#R4K%a;=l-Jc0Mam#R}>cRo-k8a7PMr%zsBBNGaulE_Pw~h6M zeTq7W8(6>psn0mS^T;8Cul+Ey-E)1m_W|=mst;4vA88-Z|2BC9)xB~1c-o<#H6Evu ze!fjk+x|J4W@frgq@Oa~SsnYFvbgqO@6U@jmMF8|Khk=Bf2{fW>EXk%t#5l~0M)yP z=D@9FNbbvRWFr%7Gm*dyz;Vll)^ppprVICAek~{TBVsrTg6lXQOHa}5?A8p0Tpr%z zjTQpIq)ZL?JoJ>3CGSoYO)r;-h-w@J)syI^+(cBGlGU$HQkG5aDR@Dn)uvE%wu8he z{_9HCtGdxS?zz5#w;QeBxkX>_ojZwssATi%W@T=$iLBT&y8|0}ZFz+-p8r8J{+lTO z|5G$$^WU(Yz<)!e%!T%lDkf#5e;;jcO_9<1CnEK?(e}|OQUy9~r=3y4j zA{`d}ACZTSeN%;Fjs4YdZJS&neQ5xzyOWE1|AV>f?C-XCF~pxXpB%e;^UXcd;*+c1 z3nQ2Hd_rsMc&nn`1J1i;NS@Y$AjFK3j~Q6mjr`$QSy)H7(2duRvb2q9Jw;j}qqZKN zsY*NAE6=5l)I@r9cdks{2(UbV=#EvnUidqSs#pF46j5#LxML-g4B!${SrV+d@!BA6 z@mk$xHEW*Fzx?v#9p}D>2dBm^6vNr#oN8Vem*{0aiwxpC`n1I?~U3# zcfOdClz|{sD57J7n#$wsY9k&sMDR?P8s^wg1Q$waBDN!n&b&Gj(!(gE#mK(KQUYjA zlS$=J)4aH`F7S}XDjRWIrmz#-%x<0=fr^<9wcr^sFXM?B{6xy=xeKN zUCCDl^+^)qCi#is`UvPqf=p2-L2IkE=9w(AvccEXvU8s~O%&N%E)p||C>MRXeibgHX)TBzpY|yYog~kQ(aL;*}qjAGL zHdhdZp~K=KTclMRG5B7UHM%3-Ne%>GA^>=VW=AHW#&DOAiio1;N4UKrUwycATc&)v zEa=+hV6Rop>H?#o_HPQ!GS;MHB|CGgYDbcP8mRE@;s*+P_%H!o?M_T?*{mgk;!@Y( zQ{(p%H88Ekto3~TOiw1G)aTr4RFA#+X@&BY-^CEE$7suO&1ZJ^KieZyPAgv1x#W85 zI%1gdrTg&hWsM%EBejiU{zPkW#20UKT{|4N32ER4g+Q&pa*ob!sJd1mICQfpuMn;^ z>v#_VMG%(&-bs4|hOPKI`RL^>T=6iUW+UK{c3g8YydAFm3#q1)Qb_>|crvbAsWdtc zK+8f*DX*_kN!#3)PXp5V1e%CRD~%`EdREuzsoU$aNl2qLfzZlxhg%QgyDsOdp@Clo zQrI^Lw=W!{1%7F_6zBY*e3?1TstL)n=C3mvQ2Xlmv7Vl9xQYNr zb(n@3kW)5WEIX3FwvQdUC6JOn;EP?*nd30S{U@_McN-YsoVr-$=t_|6)O~)2L;BUR zQabUADJopyL>e+)TsDMF#)i~_* zzO)g!Cw!JB+0&Y#lWWIi4p5^6NkgPq*<9vb=AyR_Qc&4d1QWWs{4(PLa$4Hfe`E+7 zsscC8sump9D#YYy%E7MqBVw^uFw;;F9OmZTZTCQ;9YZ5#9N?=99TZ(#0y!jGil$UP z((Q|uIeVu9!C3}^l!!1W;VHpXi-NZcIPjGX!O1YKVLj4PuO@A3Wkj?+TX3*$hK+u+ z-vwEMMwUROxpGl-UZf95v~sKeC$1d`#eWoi&8F$lHt1N~O=jX8E&)Jh(;itzDX7z0O{K%EEJr zUQec^x?@&=9remMAX6aUfTE43N~pzJXmwEFx&};WUzd$8K~tS_2FL%J^-+m*HYX&s zL&SY$MOad4La8kPJLi9Z=P3~uObRF+Wo4*K$sp2V4%`3!u4rsjmq0(3ZlL zcl)pg=KH`08qtoUb$L@D(q~3qO|vuYB>Q2c-zvM6qafv;nH$boK!^mto^I|uG&$Q` zbcz9aN;-yc|7{0D{1{j{ER6_f3~aiSxHXt@aG%*@R_$bOn?2u)5P#-t6-f)wy~v;N z*54Gq0hMB@9O(;E94;z8d4~VK-YqW!v{gPH@-(K@=|$(4Al^G5-7C^Ca}x{EX~!DZ z&u)k$r+!qAqkD(NM)QoM<$`y`EPOsv)(>PE-&XNfr=*`3!+S+&hwl|uO;2vpWZnJ2 z+Pl_)6^nYm(~)kl2@`MWa%WaEwxt#1A2V;JL$(kd;D9D2s&0F+#vmTV%s(-A;bO0u z#G7O9|2TKac3iFnq~oa|01yD#w&PwSA(Gfs(I93qxSatHvjd5?|AvltbLZIl)JV+w z(+#b*DNt!G{&%>?$6rMwV@R_6l4nP_udpvfGi3M1*6>invO-#TGHv{c)B-&qgc{T0P2--r_ng26$z>shOjXUzDg_ek40&`=B%&RxfxN zAox1>gYv~~v2w>%zFUQ>#{`Z@HE!ux63`%m!MX92;2}P2R-x1`z&gUK{0(2@EqY_4 zqjohTcZhf*s|?e*`RH`s$jQQ^^A8AG_LezsZDbTXq!A8V{SQID{&dm^EDB(mzYrmf zN9XEvynR`X&RrP_t`aVmZ z_5FJCAZy;r{~i~|pcrkJWh=v>N6pKM`Y;8uQ;3mLq~IrCS($q8G*L;c9m$uWmiiMm zym2O{4rs(d4VBDw5fVVrbw{tgIZ8oFmz31k5gkMRL&A|BX3uS& zLQQEu@+@{$_uEKF*K`!Or{d*OxT9m37zX%^A^B=j0l9_bZ$w?wlhJI2a2aTQrlYA-*yx8b6S)0X)_p%pd9L@Xwzg zM5lcr26Ee_zN_TD*TFTWNEx({=ikcMW%0ePNAE`}KcG{$@1;3gAPXwp5A;i2iBs9V zE4cPkk+MKC#zVl)5O*BdkpWJk+gRS?+L?m92ZKf3abYZyI6sJpmkkF%yqF#vKdmyH zNYHz+VNCFKk#i6BZl@uE~SQ$GSN~AdwQgYN%O|zN{Y+oM?BV{bP=1 zwC>{{Xfg7+{Sdr{zA{(_V#G!7(u5Qw#&|KoY%JtnG{hH>zgz}p^2B#(#+SIoN0H*& z5^at@rlq)@>+Hg{)M_A5!bkk)&1pE>Q zAL1Z1GEtq5hHwlp0FPXHj2y-9AC;%h+alRBXcz$Y;xSS#3qI%==voAq6af|D<(Ei& zaZFt9K6G&jMbkctVL<{{k^2BaCI^yBP?-OSsNTW^*C1SD5VtryrDS+?HmZ;nU8)Bg z#h3pjr}fp*p~kSBcg9JKk?ORGoZ|3A0eA)p@@pK(8699V#C`_A69%~a9sqM@@CErJ zo6v&yZIJT`h;RFmLLB_PjMf$b{-ado5Ralj8{jHH-Yp$o!r{3?LImwCAYU>Vs%%(O zHvEa9*74HvQ6@Z>bVPs&_EDA}XO-oW;Y<2RA4lx*mk?T)aL}yIaZso`URK#%lvW59 z@CR#eqvA8geHTUf9v{>pB#HsKPJ1X9n2Va>@YM+#S&aogY|-m8kV0Ky)MG_IhI@%q zJT#=}h9?7OA?iR9zpx}DH&E$|#;KA#r1X-lY&|vOFs&md&J1yRv0Uzf=xfm)JJ=*I zN1QDID@8A;H>YbYRC`Qf{qfRfm1ouGb33u1@J5Z$1ih9b>1#mnCp&D`VingQSaMBN zuN@S%M*6~2P}8U!0R;;-Lr%BSORTM`8!GkJ;{4BHqW8jui~-T#ZA{%a(D-ip@thj0 zGQSj~@$Bn5cOY0`s)kD|N@BI}$7B4T5Ah{!9$kgHi2fwaW^_VkHCI2#p9S#)loy>7 zxsjlp*IgO!DO)H<54u7f0v8)e)=i}ewozayRuSn`cU6C5ONt`dvX5CYjFYKY3m zmZ(j^k+}*)F^hPe+n5hSyz9l;S!Bx%i+yEio|+=79)chD$S?Ehe!Jz>18uhP5mo#k zS|tQBSRX^;GgWfV2X)XT{}|JD zUJj?ihfVM$Hw6-HOk&|Qau%DrOid80?6zjGqo8P;if-2_?Wl*CgzznXC#UEDe3-BC zbyb5X(rrXP0B&C0VZ?>|bH&#nVOYw4Qm!_uN4=RvKzy)-vHkh83h%3%lg6}F(gKqi zh@lu}JP?7;OFg!Juri2r_>Ld)JTjPZ_S!6x9e(ZFbcPMOJ)9&1Ye8lZkUz!m*I=bz*H*i!QhrFAsR5UtMU7XrZNf8` z$1<%qk|PsAFA7s5#9|V$&N68YlRxi-F-D2F zF<(8KX+N922@_&n5F3(Mx`RY6$u_(hV#Ldvqjp+aOKz@;hzfu#u4L{Xm=qKKoZB$U z$I5Uq+EO0wGGh|lPOhm$9gl;}?ptsWJFY<6Qmd=m0yC&q8VravRdm0DL?5VCHvkc( zCq{+)K2;nOYfj)qT+ZmG>kMmrCW*V!LzNc``%~bjzq%9S7~iSXSpr#5dCsP$LMdm6_xS<3f?GFy1M2 zz|^Cg8VguguA2nDKW=J|0d2?CxP3M0|M?3sxHI1kNKUFf=o*chnUSKYQ;ykY4h~1g zwZc5;7gaN>Yc-6Gkt_{t%86@+YmTM$-Q|cP%kxm~iNKefDZ3H{`k;o$5H5v($Ofl6I8^ritcJ&bTQHJXJJN2Ii}jc~bG`D} z!=b$<^i1jYZ)selvAhhaxN8P63>j*}7c!!z+`3kST=o6fo2bAh3WM zYxL&TQ5mx3NX48K32_g|UG_mg#6$M4>QBAx6o(*!%_T7J04@pi@SIfsE?L8s^ka)D z5nwl|8WTP!@I4^G+bVS-(n2a7$3;4uOWs?BNKEx?`wjWwn~;ud##;_+r})AofCodqK~Q3zEFmySb#vS^A_aU%bC#a=<3f=Zd8Q z^K`yv<9w?WQp`KdjL)c)d=trCrPEJy8Y9`eg)4ODpdUDh05 zjO_|dSKtmmJb9RU?8xf^*%C<9jH@zk{b^J7iN|lwYSS!s#WM<@!4{@W(`&0}8mzfr ze=g`TOU@)*$XBEvgSDvbVRtWxFcBo6m}zmNdHfS_50Flv2Mf{Z*}u#j_{B zKYfr+87Xzb>yuyzAJ}jg!kG%EbEPgnKjfnMRGO93Go@YNs`-WYG^i07C3e`$L@wgs zvrF8@r#Lng2LXZSU-)7V@1yp&=+BYF?}1{2Op$#0$ z-hL?P`FI$AMB)y!SMjN+9oJmKM-=}>WM>R({38b+262eT3^K*c4ZVH+B!;=5Gt6KK zkCUPzC$Ab)nts03(eUQA75g39-O7fk0Ff`nzTH%w z+cV;pdIyoshN>lVZ>sz(F38=8AZ@udCcADCaNbVO<4HPKm`;oNU@XpnwZAc^ql-Au{@)QZzN3|Hh^* z6YyPn$)<3P~-2F-d+^iMuc!qn- zD6Tw*f*ZMe(n!Q!KB4+{!Xz(Za%1J4Us9Yzd(WtfkNy*_v-wyt7NM8>OSJJjXzYm*kG$k?GA;kT|s zckT_1-mOphZ=~?pb6Vm(;`9`qI^3B2WxjU#@%GJc58w16k-@{H?)cYl-oYf5zgs6p zOGji};~QHaK6Y^5AHk~=)(798+ws;#!tADLiB?a1jS(_4 zT&cgS?_Q%8WWd+vS)o~9T8YXj-b&#G-7#z>tI9VD^TQ8OD(R=C-q@6=QpyI+BRgW) z#{DS|8dpAlxZSws;wU+&Hj_CbDj%S`-k~xBE{kiQ&pRVdiHWaj!8bO%^Jr>~aTHh4 z34wTNKeReiM(t;+BK3s9i$&D)t<~NJkMH8o5F4?u39FYeXO0#vEtqtw>F9(BQ7Snk zBQ?VpXh&mqxL~MIiGnXyZ}o0joOTPGY}3{9*kHBhw)%_|=jOOMcJ|X(7t1KZ1jiB! z)O(Mk#JLHsO^4lJGsoghgZs=@jVuuhlkC(s4Xr60id+4-x414GX z-Pml`?_SZT={MpCAC8&`hBHamMcSGRATdP@jto1XoH~LX!KvR?giTyrTu^kcdStg{;+|(I5LqF1EM%awAc{W!my^5A&B|=aUmg zP*&-_Q$Z|d^2qvPk;^~7>s>%NpkMpuSTYx_J?Q|yWw&KG{iirBV^I7{cLYj=Rg#%m4-V+3%6 zZ+8n~W2%2%dRxW3Ko%qZ0e_ssbCNE^YX+|_3eiY=Re(K{A!+D1K?@IR(QyPew zQ=M!lYBcJko1-$m^24tWVQH;JqaH09@M*!WzhBHzo{Vg>qJ1*gvOTyNSw3Vlc@QYUg7IR2#Q96 zdYxE^Q0+N!agV0S$zQI~wo>w{+tm}=<-II2iwzt1Dd)VkTo+GM|HY2 zhhup!S{E!do&KsJOEy_jTrT|_jcj?ga%X!ukKK2rwo`Zh)m8l1xTzuwnY3p}@*a)P zqwy}yzY~lBXNDkkHSE+sq=u@tL6tuoR6wY`5Tlz_b>73Q-G9(6aA8Y9RuLkiW(ku_ zCBi5hAAORXKRNphbEUY#~y+Ih8ew3EA0? ziMR6>uAckG-rpFw>(g1J`RUQ4p?S-<-Vlksf=V)GdHK~JG_~F>pdLBM{=qw6v>I^-?xh<&6}j(ZDdTtgHR*h$=YRf|maUr267)6@eIk4E zJj>pNr{iP|ftb?Hvg1Y+-Hdt)?md8ilfQCeT*CW+L`?T>!sdjl{z3XljP#QEXE)>< zTP|d;73s)o=LjV;@1(VhFHA@D@1wA^bcOUiu4{{>MRlgoE90o7xbtTv^C=m!!F2ssL*-d3 z;Rp%-x}9p}+mj)q5Uc$!oHa?vMDU!vm&<|b+}#!4a_xssBF$X-^Jc#XLnxuA65&I` z0a~O9(fRv9A+BS4L*}lxv$R>#E`Cn!GbfA>Y1HhK%#Rll2{0I)l}457%Prgtpd6mL zyJKcm(jcKS_QX*Zl3$g-&$+eq(E1a}gv1X$U~K8cwpZ@GUmx+Nz^A`AO?R6s)lo6B zYBvx8p`P#cx;Fs5<)|;g+~4EEIh!sM@lcb%vSHFDfZ$3E)*!D zBmNnWVFn;6Un>gaE3}CQnac{xZCfqYV6*TaQKOA=u%+>bO~uSb=Z_l&{nL+&-v}Iu zt~AL%rYQ;sNoO3Px^p|tnERc64;yXrM&WQg#4OZN`D^CwGOh3^lpc2yeC=@hNs9QO z)F^Z>rHroibH7VP4e8SU0tZ(bPE`6uecb7`cRJa=v$4JDjUU@=s#4&hc@4;6pFi4e zaWhyY*yE5BfYG{rldGPPK~~`oQHX~JN^C;1VuP~F`?1`q-UgHH<^0YMm|=z6){nTz zq4+I9o?qFuPd}d-FCR+93z8$ns_w=&w9@bfjd8 zq5k6**TDmCqYY63WtKcRr0`avkIt`Z-2^E#meNX*tXOD{YFK?`0ROBoG)G`4YRgP+Q_QAN|NSMI8RTOsTCP&_YeNL%l`bk&}-e$ zyX1I-6!pZ2rEurWkX&BfDbccA1v|D6L>90D0PvL$gwTH)!-GcgQ5lp%-zmW906+lp zb21CF`jK{uXhMuwSV$F%4_vg?d{6<6#7d;L*p3RDIO6-d|I=t6{Hk>PY}y$~P}i$6S-huJ8?j6*vX3mm8e*G>Y|75Mh4Jewkj z+dV1lICShQQl$Y9Z?HyD@>7_obqZ%hw+bO}`Z1M<_Hp%jcAFH3-qTR{mV$742#6K| zl&$&D6}SuCxmf4a!>+bRTXX%^1+#o$`;=rz4(wnkXfky@g$u7@H#ro!9&9TR64A~F z|DdrAV8nP&1_hye(G^tzjVf|YT}3pu;5MgFwn2A%{Ovu{*b&6hBI(990{@msjVR_@4Y{$d@Wx5oM_>yDqghGcQ(3M22SxRP9awWO@P#Cp zxEb2e#bVA-C!l)1ENB{3YYM{~;1V+H%&y6ZH5O^4vQ<__Y!+C9*NbdJRds3X;@>i| zt>{|`um_Lu2EMQl+LJu?y$3nP|CL?puJPJ{l$Z!q7xHddtlSZPTqk`tZs6;oSB>v$ zR`PS#in@D?h?Gk&%0{o3UA{5eK-_?6Q?~QOM77aZlPqCeF68Yf0853&`W`n2IN zTRn*WCTsgJ*icM5ZVeR!RiL|x&(cQl{QE!O$?5&sQQ-q&RYJ9amSU=!j& z1;wPWBG;ULqz}Ewf`&+5soWc6<^G4-G~m=RG0HB2c#fN7Y!rCMz_K9uDf5z^4KAL~ zAokxV%M_0BI4qnlo;6iq8ney&VnNP0>TnyvU~9kR));3ZH~A=+AW(Ec>B^x3OVW1j zahUxm>M%2ZI1Vqi0eKKs7((GZSc19;3f86ygei@Rs8z(H2GsH@fje(Ivq7Wr&nHpf zhJw4MBxD93b%ci0qTe%<8Z`gSVwrB^IJwcxB#vjpBIl3A#lUP=y&xQh#%+Z(V$;mjnZck{W-Ue z78jxQ?`pGaIhm!BeC|i7`uZS9FivX!nCeQ&(2-)6;_AkWY1E~{M|XPM$3n4M1o)*U2w;5 z&mb<@rI|-b@*8}MdB{R*(HXsK!pb6h?G}jkli~fffg?5|^mSEwB{V&;N=JlKJS&@g z5`C6fT+RsUEW2z@{107A&%$w@2!g)Bo2xkNjxv&15#dxF{c}{Kk`_ zlxeW>aPjjKB7};^S)Etzs|KGLdt})llA<(64bl-cHp4BoG^Ni|e?dmo(bWAV#;=2x z@H^rfckF22aboB{U)9RSSrDeXTP)n}$8n4n4`|Dm-K?%^@_m}y2B2vmk{L=u1BXTB zQ4O4UYydo#1e^T#Xgs4Jo*(KUC0-H)c#sP1M^LF1 z1<@PGMP~V4z8*6xPiXHb9?3%lW+L{?D;^v#j1yS(LST=^#3EM_pRp2If&$g5DJ6PA zNljt&Dk99S;3Z4Zpy#Z^Dl)6+^wzxpx9u;zSFo)i$1-Szk=TNWwu0bB)PXk64ikS+ zeXuNCshq7Cm5EBtL`D%&g0tA=(7DaSxUEI>`}UW5F@tDIUJ?_RwSkOW$&Vl@FR^fq zCjd_p>TN|~5-5nHJdb3vqc_}A=>@;~LLC$esTI$XQ#$Jg%frR{KEtJrDw>r95JR}g zE?mpS*HF0@miiBfnr5}1QH>H$UnTQu_jt$^F2rTwW+Sgt1>h*|YG529{XI0v*mAcwZv+Q7jJRK zm(*V@Nj8dT&)lU}mgFYtJZhBT{hi$Qtx42J-9)ISrd%?V&f9dN&sRe$23@Y>ns<2ap(X9@Om! z=ersjO^4puYI6~xP;At-sd6_SBP+A;7Az)S-6v=Jh6LWF5c-GDJHAGEQA(gkcng~$G#jYOeW^{Jb5|osU*xdd33VE zpN9OgDn8<7HTm?a%?9#XN@0t6Tm~98MsE*UZDXdz9v(-xF=^{5MO!va%NR^0(yvwTmU~4n zjs*3CFWzfZsd+PblCJ!XeF>=Ph$&XM`S}Q*V?_5mq%UPFHFgCwVSrsuFQgQ<@V`VV(QSOGf|G4-F_a5A;-Fmc($ z4T;@kkC7y0-pSx10!8ijXDzFv7mmoo3~A~Z_|xA0wIku4#D4=2xsM{OX}0f`LodI$(D{=*7sLlO}Z#kQ#AOr!^w)%FA+#K1li7bi)D@$>>4 z;DZeWZk_ve>^Oqbk6c|vzPfQ5Jr3RH_E3N>ufLL?umJi>rX8y)JRm?uWx^Bv%FS2O zj_?qgFnI2GVZ7TTwT*(D%w2aL!kMFm{;SYE0;J8IvdByh34swU%8RBR-1#3W%Pqb) zg&i`5Or45JUqwa&d0UK|i%r3+lSNy=Rm3XtSogu4DfqqObz@RNeCE+f3M$bJNpAqD zlJYF#MYX7e+b`5)bw)qTZi(t7`Tx>t~{t&yr?N6gyN7~045yVV=f+7oD_ zG_vF4$-D3}oj{o~`k9JL5gO6PEkV<4j@cP2{Kc^qS2!D~A9=i1PfiVmdq8!JiZ4W{ z40^=Lx5qYG=Uj;yr9_rCP`BGDwlRJgLhHS6M%CFM$Jq9j$qbxY)Q9PL^N9+jo*H~a zo=TZjx3l@3H$y_Slz{u5CKf=Jx4-Xa9@H|55|^j@fByKZCmO4B#BCy6zT_BQ*KU*s z)exxAUxQ&CF!#9A&}^6QwU zg1Dw~&2BK5i*zVO)PhPxpM;nIi~_%ItOBV&7b>qKWYiWxJ85>es1mo$@u;VZFY)Wr!;PifplJgP8{9V065)5VvJYLez^<+%4!(x5~Vw!YX65jV_?4ZL1 z-bh)oj{Ks8_may4|66dPdIfVTm_aM2i41$*9#C44}vJyUyHs>pb-jU51m>CzM zP7UxziL6GWagCD*sCejrQGulLNJ!6pi(4O=_wFGRS8v;@4I16ifqeRU@3eTL&!oi8 z$+U;Ya|7M8+FG5aeY<-?yXRbQB=n3Wg>)D_4s!ft?iqU~*a49qSTS@y;KTnT4}UEL z!ZuHd8=sHJ(UyvJZ_<{J{ttPm4P!dVCo^%JxXSpOmTylT`giTEe$fl)%Gr}guD_8_ zbI815r&#_!JK09_+(W{olkRau^+u1<({wRzuFa2U>t zGNrTaL(aiVLL*;L*C(7^x@*qaXy{lUkOTYy;8Nsk^d0-wG3F2u1)TIKh8`O+e3+1Y+ z2ic?bD!lHef#G9fEM(QMNpv1~d}=_;_N%+|ESxSXLIa`FJUBFx3w@fi*Qhx7UcT`o zJ+VZJr#FMGJGCU$gw4mj_~vOMwp6FQeUx;G4w3p;1$S9laozSFiuZrhEIF&?6``|J zcJH|+vj&Lw6FPW9=}{JDu*j2qy^6cAQv*K>p#_sMN)_Kow`$<}Iv%0{MN2JF^dW?m z8&sTVFWrkp=-$ls^?e4Ots%eP5#9c{uUk0F0eB8Dc|L%A#0O+Ra3%Zv`00O+aMcaf zeM2#9XEsjlNaFH7*@?NyoN2gbKTE3J2cew?R=2OcCP`PK-Ji|0bWlg!Jlo;UMd3YH zBlDe;eV#}>ILa$Z)J=%cefp=5Un^3f3%f!E(Eg;$SDxy|OCDnLOBg(^X+n7Zq4BZo zb$HNU4N=NI`15{Fl(R7; zB(V;?)_p~mx^~dK!X8q>2cBs{fSaeD@4LA5uhcZd$fOkegL*gB^2rqo8fec{gsaT?|mJ;)Bcuy2rVXo-rG0Rw739) zuTui#u30ji;%FE7?BRbLm<4y3G@#)9NOM?B&nN1|pEelphyyARh^N`HJY~4mL#iuu z0^Vpg>`VY&k0k7Ek@`L91kQ>Txg^Ot15kzYKM|};<7he`x?3}RUPk{4?nv=|zppo5 z{(G#D4&%Z7O}L_ntvk-Rx%;}{SE*fX9Vd1OAfdUc*ZX83sCL2Zp?%+^_Bq2*s{vSi z8MySHLE_+ucCjwAa7cdzlpfbl{C30vr{{K{|5i-Q0j=w*rAelu?I-rSb2dq8q#=Sd z?$hUh+IEi5ryD~3?-zCsn#gg765m?EU;uFWpYtiFU|82x=hH8gFMR9JvQrAqIo)o0B>$}~OI zQ)m1X7w(-3EDidJ{BEGXbdga|pzynNm)*AaJCiHK^aQ}q{d_TrRhU-p^I6pfi#XH} zbVt>E{X!Ii0K5y7jbVK2aD$7sJY~H)Idr3#3!bRe|K_wpx;}l@Aw%g13>$iTgbbvt zr&kabfASwf;)wi$BkJhkf5`+3~Ho4p)x?hiAXu68^1YVbq^g-QQKc zP3|M{w3OgE0hp21*mw0EAky}vmV6pV<6{K(4UHO|)4^c(Cg)SfW%uwAO#bsOwh|Kz zCOd@}Gj2E6-DjQrRm*?y?$qnB7gU0h!?*xfBP$(4M@I4y4gB@2dddnPE#L|@n(=pq zk1H{BtUwkfW)Bca?}O@J`PRx&1sLAe*|J`4W#7(xP;}!&+F4>rB^}P#i~2XxExs2; zlM!j4-wyVF@(CAVDJ!xO^7)hUZ@JN5pF&@EjiPK8elKzf$|q}&K5|P3-|l%t2m*oBg?uE+X#)lV^!myu*V?ZP!cM*i*Gsc3@Yz0y`!?9T0RePTa+S<*A@4RwU|Vm4oeJEqN#j;eKtym8yI&c=!j4=#;WpyxMGr= z;_&weDlfnc{ax#w=Oo}^_Qc3A>GBh|nL1yle?DKiu9pmou-tC_==K_S1r!rr%r$A z0ElBDvG4c`a`rkdjVTLnFKv5^-0-v7)Utz~5591lDc@!uB z^!wq{W2eAQxwizOCj10&CLes|9O>tw5{J+#{-l~BlUJqrIOYB6h9%Mg^H#aW=XI*h zX;JS)5@PMsv?-dyBe;;=GUwF1>6z`??dRgeX170n{W$4+T_alw(XZYWJS&ckT>BFi z7Esfrp(08# zw6){v^pGFFUfceAqvh2qf~TaMZfbbK8d(@x!G)>PK9c4k%1nTWY5RG&+WFU>v4tVh zH#ww$loc$kzo9g4^^x!g6zzRY;0DA7cgW4#Z$I(jc)RX{Hy>dLK6bP=w2K9J(Gm3J z+&=K~lZZR=F)Ae>a!Mz=x$e~7Areb+6@K0ah;)B5g3W7(WuK@_i z&;Ivd-ynEsLATXl*{%cly1%LSxz^aOME&a#!GDFz393+0w~+axrv?{JE?kd-TTxJq zrf7uj)AtviUIKVml6dVh>4fT@;LrN+K#7>$xZ8Afi4ZBuD3p_%W>_*?e3)NAO^Skbw zQp?7jA=fctQ)IMc3A@*1JsVRkWr$gPMix#+rLLiTM*erLY+t1l`Egx)3O2cmkj&q& zZY1@yOJzhNJ-9`*t=0A4+}YbH3PuYGS5uTT)(AaDN`cy{$+5CGWWw~j4#Emv&S4+ZyBd05Q+L;rn2>?w!=X_l@-)cI(X<8@%i`cxr6;Hr4P; zw;{@eDtX{UnA-K2x|*2n=rId4G2ho?9&KWg++&epLd)%; z9XJs6WJvtuN#pZ9R-CDe+h6z(9tau}n%Ml;V>4&6?Pbrlw^=P^NZ; zQZ5&ktW-=LT&H~ZKnMa2f{m$@U9Y3#Hz&_DCyQ^+fu=65y)GGPF1e4gUgyGI z_haAO>rFkDHO!2o9B!Fhh5A^P%_d2^A6Yn2X631=^3e7KUWbyQ;u0=*|{TI`4W**5>a%qsjY3KIxW{w ze2NeAZ$S53h$mbXjY$^i&kzH?h-?X!NYYrBN9iK=)DE_S`cJ0pC|wmGGlzAaL7-yH zRFz?!JT}&e&MXBHt$fXnVKT|yQf`!^24ee%$V>+fMX0fJ9B91-WBb-3?4AAQ1f|%e7x&b;CY%LvW~N*q7}0tX`3k(V@XE;_Nb(H zafI2svNJ_iESrArLb`!^{=?F*GWu@OFO67{TfwWK^-%Q>56qAb6DqHM6;K1@L$6_N zz&{5!&+BFlXdUXUxAN2{-ZUJR?zI}%0u`LHMV@URYO;yB!AH9B)op%NSlIN6W}T4a zi4NQtTmCf=ZG#w{*$}a(=nbnT46BE-r$qm%1KYL|fM}4sYcUvci;t?fcHCks#8=^Y z4iv7vSVJ~AH*o&)u*Q5AQ^*jZSRcDQJ$RX2Hwk@ub=%X+!#WHHDJMGeUjM_Fedv1P*;2R6s*s2OfF712X$nDE}ha zHd6MX$Ls5L$qvxb4YEI5k9UJ}Xxpj6zo#sIW;y=u{*tq=7=*X|mEKBDho zLj=NG)UEJCNA4f9)(UkPJr9&#KE(07x)_-A!Q#m6liB;m=$}5^H~?FO{b87f@K$qg zg{x#1T+S8*LQhD(Iw1B6K?CF?`{89kM!fP?=(~md^karMKUj+oB=(g8bRRm%AL0;% zSWW-_iZI7QNwP}~tuoxXRMsf!QGaEG>oFDk0%^;tNcU@6+vJi%^tOWB=oP>CxVtW+}k@vQkT}UkaQtQuNewi9nPgOAh@uM z$TvKK?klcrj@o@SdGU6wb$!yF8yRbFW^dFd@4J<_uiuSMc|^vPI^eSTkMkX{Qh5p8 zI*}wc3iFKQvdm3!fH&N1aren$!A%=!&xbba)8pqZhux{$cJg52)2k_OZ=wmTie0tF zf%xuB=jcunGB@A!th*FBPbP(3L*lFvBr9^n^WT(zwNBFMOy#_Spr5~;J|B4N^x;E4 zzbxKqdcHAqtZCnVjUf9auEQCL3X)UZO9{)o>RpknRt!f5&w`R8FT_xVQQzMf0V!op|cc<7klpj5U;4Sk64#Ags7ExN&8=wPcX+lf5IL3g%Y$jwoj_?V( zmXRWN^`>~E8pji6CbXK%{O)QyZ)rDbt`xB))(cW&+R&FqjYY^OiWXT03Q#gzx^dF4 z$WWQjh3mZQc=*72?cUD+w!OoL!Qe8)Hqx1aG&08ymCYcDw3n{Aw&MFbY;3hVAI*3g z-S>Z}>Aqr0H6U*u#8OG9L#A@RUxDHHm0&kjs) z4}6~fBysL}#^TYy7g_H*=UyCIyC3-S@UKsEFLNOhK>`*=XfQ9};Jkwtw~QL+7YoVd zK}*Hjm*$sBjc)El5R5<1FCVkN6uVsEZt&z)wPjp0yw>-Bq5wMrj_+@Xz4YWwp>7)h zo+57u-ZZf!HeZUwxT#`DBy7mLv&S`k-$ZF-%bz(PU7r2=BDu;Q34kFR9NKK&N?_eIYhWXD6L=b;H*6E3^I4F0+qpNG={a^N^8^cKWV4wqSNgxD1Y z7yAEux;o^XIY6!@{Aam3)a8w44#NNkmK^^dH^0%OP0-Y_ne_boT(JCN7g}|kzhfcx zJir;X-~m6;nvBWR0{Geq==N67cKZES;znhRGH$;(Or2*TWC8IZU745c4mh9vFO zYKzSUfT{?Z4nmML1_0Z-`D4q3&?)P<4h!z#pW;{&$d?<|1K?cXqctFe^LjS5^Nv`m z(IG#7-UQ%+WbqC9}sHVW={gRaZ4tP7+*JAc`=4)0+kM#_u=T@<0AK< z*-~!({PAECCWJC97R}3-=aEsSJUU=O2UNntkoFxA8FmF6O(|ua{|&)~2XQpRo6#X| zY=jPD2ukfLHet|Flk-kw19BlHZCT-#tKF}#9T364#P8&~SQLarcL@Dl z-Q-ZM1|JCE!2SS$Igf>OV*q;S8UWD;0aU4AzC536&S1m507uE&0GKNZ%3Sw>YXxyz zyf#*ppR}=LVzwWy_~-z!r9wC^0+dJ_OM{Gc+05c|ACD-{i|N3`W453DYx>?-74Tsk4m8NL?XEf-wWV>nKT8_TzXzaoHm4N1roeJ&EKtR~ zO@f0*wjn?WI}>c2xqQhSq|bFnPuJcBFT0t240C+Leh5iJJ}d)+_Aq>)dTB^Fn!e+* z1qX(vM_WIYgNQM2;|{(dNj1>nHliTvV+Ww52!-UFGlRb3)_d}F{N3qx&~ITFcQorg z-XZAH(a%Z7^p7c(AB@Hv7^nd~sI4wldg5Snecf0BF3KklqQ|=N+>DNW&;SRBg-2AF z?CJh31>RSJi(;9b$baOgedhctWohwoMnLHAJ^*OE_rkhbVat-t^JCM%r~@SRim|08 z>xL=%jF@8V!)@n`jygyu>!V_9P0ytq`>X-vyxzV0qPzu}bM|F`$Gv@gcH&vs!L?GU z$9xsq9B?c>UX%oe0IxoFrd?ziN}?UeDomi)%MB2NxRWGRz z>K%S(@#kCW1#9&~A1~*Ie>scUD?q2}!myP2%6V}INDL1qPZyxDf+2~6Oc-#f9FCZ3 zf!2Y&N^}7d9>k8fQ`|>+Sa;Ju$v#(laOUo=>FiMgy>z58cKcJ$3r{+`-p9QQi2B~2 zlw1y=Uj?!n-Cg!>`${y&cGPKL5XhB4R1? z_S_}|1z%Z^$+TtV`IF#g$!CXOC;WhU%?d|W&#C}KU7!5l0u+=uEZ0Q>vGmQG$NSVJ zSG=O3qx?g`8Gn|;%%XO1)}Bi??}OKEIWi%GCqnwSye#M-@gT1pm9qq3#i5V?h5$yU zXDYS@bJXE{gfZ#Qd({e#!N)a@gF&|~StVz2cgf4sM-pC>w~jyuDryJesZf=p*kiV- zBbRc*rZC*>JYG$8hfM_Pa4dj$Vf~hX1#niGw=uf>@sSMS?=`1hMIJ=Tef+p{%n6u2 zk0l;51)Z@GBw|~3LK&DJmxX&TLP1ct$?cR5M+9sw!gqxmJ4EY1RGSw-Xo2ei(Cnfu zy%+ITE|e+p&ubOlr2bAQA9qK7hw7_nwqh*%pi5S(WG*rWgmT*t-mYA|1mEJD4^DN< z>!92#{z$973!m!NbelEBB2KMhwzb;DFcX8`kR)32ilSL0pP>*C?!iaF49J(F?yE1Q zT(2nU4WH*S#h+9-o}|2ShRTb=c@xQB*a}g0Pnrd)gtVRnK zH;q+O#p$c!P&h2v2%mfgYsSXOPUE!K@Ftb2RA2nIH7R=|Y3CGa_b%z}Ytp_(gk33w z;4Z?RHA0w?%>ERa*e;pGHJKD6+4L0ItS;HZYqG5AFmF2Ciw`d_B32s7y$&aqt`Te3 z%J|&4q>1#kJXT+ez{hIN9^l@|`$^-2!AgfV)H&vEqvw zIVetcDev#vN#nwTKv)n%Y=yJd0p!k5A*n_(rN$XBDn??fjUc8eC}? z1V~;Ih%I;iAIjFvnRpJJ~FEOy#R0Dg!Ot#0OI$qv_52FGwQ!dn$0qek< z3t7e!>+lLG7#)Dw(oHPCs;p0|Sn^5kewYEgnLTJ`MuHEUz(>EDeKOXv5Wotgtn|6s z?%fKt4=r9xT`TBPNav%CjqTF8D$zZXzbjx#bd+(G$R&ndFhlDqTW?|=>Mei<(ebt{ zLYcAcg>G09$qr*`cM*g&;6*QJs=+QUxn~-~sF8^wyEv2aH2#kEox0{AJe-gI zNWx|MOCyKSX@JA)b?dC1&J&N0HfX@DKoKVhIm_Qu?VA*S2pz!)7m%KO(=Yb( zo>>18RqYlWW)Mh+{cVNS04`a*>h6B{AUe#OPY&XWsG3ro$+(ziL&(748G%-`^SO0Xg`CVd-3j8#rj^I{ZXFb7PGpwJ4$pAQD{R3lAmS zx<$(U07rVD#y3-?aIMaD=tomZ@ptI@ca;t^|6p=#eI3&cfb|+%>`04#{v*9(7VYLI zeTnbz))?tPx17M!g|WM0efh@P{9R|vl@VCDOP#@6pLm6utyGYA&B8(s%FA6%_5~0f z#);3X8GpYeT3$`S79!oG$dfX=Fuf`kX8Jq$-jb=&8v!aK$3Qs(9RZ zr==+Y7SKE)W23cpOF1)%6Oa!-A_OVyGxs);v0o5_R)1 zj>kOuGD$|ZI!+CsW&r?eTy-_;PS`semQi5TLg9b`o!`c~!<>T$84G1_?xj z>e>y>;v}^&hBTWgfh5^tKEaZtC4u;Y?l?zEydmj2tIiEu&l`-#Qjp)yOm53=>DrQU zSYaNIq@7qDTQoCFGU6kz=%uS?4UtzRr6R?auJTD`a4x6j=_*Ct#@fecU*2-Cpg|32 z5F;AM_a~@t4;enhW)LEL*q*8YfMVQ&g*+pe;v`4z$lM}sX{oXW2{jb!s(U9JS{D3*SIGizrX&DW1?0?-WM+xKC5wDXQy#PDAgDx)QQ9{FI65*6N?O?aa-BRO4C#VqaC;#{3jlWcaaUx~7wjVbx%c8n?t8`PGui@`>U}{Svv}J=H|g#Ifkn6= zFUSWOcP`E=gzpUBoZz2cFfadoLL4GlKj-RItx9)~4UKx)EADy2a9*ItpF+38UYk{& z+PuC%OMI0fso+4%*?OPn0oMHyC_i2MjOj+xhpsx2KcZ`-OB~(bRqW@R zt%f*?@XBQ&YT#09HNLu-AB{VA11%|F12hZc-&y(e4wo+^7I~U#TQ07-m#vGpl}D0v zmJ}io2(d#4bD7zvYRH!_FzaD$zTj;YeB`yuJHrXi0!dDmSSY!x^$X2}uiCcw@dGcz zz)ziEk0Ta`N9aH5#cd7>KsR*gD!O5|;B-~S{o{GZ;{`?&#mN(8$7=shr-qEq{Z?#a`}C&u>t`pU>BWA3@jO^5WoF}e=JUsCi9l!|DR;@}DeNGT4MTSlb;Vx2`Y&HZS1ZEG)Vj z(cp~%B9_-4xnxFRjTf~;Uojm2t}KEVC6RIUeld}1ukH*iiX=rf54^4%m=D1-kNB{D!@ykrtIEe!*odc_`V=L8v*Dp)sN<&W0VgBv6wvioYaBb~g4g_)? z!h4hEN24)kzWwXB_O#+95(n|1yqyty!}snoch%b8O5u?Wfghx|R^qfL$#L?T?-`ZM zJ)(1a10NXgaNcN+c%Wb-K{%cua2?2U5kK{04JJ4wRAI()5&g$u5SkAVtRM*FpJ4ab z!JEjXOX7l%A*O}h)kn#YQVO$b)dww;t%M<=i1qitfvp6>Zsi8+MM`J{^-R^^Zs_$- zW$WvH*T4P^d}WH|WLzJ5-!>#%vGMXTLHIiGoo*(x&BjaH08Wa$(!UI55@k)`U-zE> zx3&P03Nz700&i8bI!D#ZpR||EV(*QaHbT&doB$CAiFwDT-`WVmn-mzE`2Gzbm2h38 zb!cDx9E`u}!_M`eAKqQIL&9vTzdZ*EUavkP0I83wXZ3SlexSU!8dwa;WTpeC>Q5n_ z4G<&1j>^5G8yiQ@hlFeb2HUD$J~Ej%dkVX7nbU@F1iY~eln~64_~&zP`bzS$ho4B|yUGcY< zx`FFfSb}OPZ_qU4I9jOtettklVAt`l@1Iwn-ZFjq@9*)SKbOnQVBu|6IT1>3cq~+X zI>dq%;zeeRB`nnGn#275cCc$d)guznvPOJsYAuhb!)N9HYtF>^?fi<50gv4?+lNQqc)n6OWh z1Ii3zR7Dn!N?{f%){9=o64Ffs7d=@uulHnX_pZFwwh8!=l z`uf*B03;ixhhbGGzRS(v7)KDQn!Lu+V!f}kL^Rgq+eI|hSKSSPs_X(BbaMZKK8ttM zXAt0!!}!HQ2Ruf&f#F6PHkER)yPY8nIuJ%_CD;OkDgT6Td!upy0_O1jNAl1`eoID8 z*Vw=4){a+S%m{5SYjPs{K0TO2`%TuaP z*bDz0r*Gu_Y@D)1-iC+Zp1v!laQW{3i+t@9**bk_&pBf2` z>bmggd5gJ)SwWD$K-%;Ie813TcOha-a*X5rE4Hg^(JvjZzPU1WiZ{OFtE6_%k8ZwH zYS#+RCz96^QH^u3|2W()^snaZX87!Lh@TWzg@{RxdL3szFagQc>)qvAuy>rmGrBXv z+o~%3o7%E|z3F)Al=P+hZT=Iqwg;L3=2+0-(OwbV!d^b_h_rDd*8V#JNt*t>*==MF zh=!?;G)kWePU14OTC3R&Q~32QRrD2k2}}z=Z}Ruhk{yO9?r_V8 zm%7pwpiyS;Mhb+hak;!tw^_O38ngwu$Y~B0`FS`Qj&|F2T|v<-9@!%C6-HS8W%n+^ z#Yp&=-egpMY=wk3q=5YbZwfOH_8u%4qvx`W&6=B#bga2D?w1gO9E-|lw?vSbQ9v$Z zo{=2>U;4RUBtiV!!KcdWhq{nNUp~4FOy^|qw{AyYIBPR1Q7+T|Ra8k=>wT5W3C-1d z8==J2Rq^YReC5f2+k8Y|%h&r_BKSh2D%tFgR+p~gziDP2d7xZ)jDys#=*yAHbt{1Y zwhLh~<%W$pUTB&_l9{W=+%%P|sMp4KGN$T#YlE@zL9aOAAe8LP|BOXzq;ok7$0p6q z<4=A5t`+8cVdzeepes_uxBcRj+3L$if^#ynR9K%#h1GLsh1@NB28TFc2+glp%mxGt z4iOq7VXhk}q~#>{32o%)Gojd8NCn_`Qn}0w|=1H0B8VfabkGWJ#ug zY1L>}Db_`ncnY|5*tOo^aXViY9yA5ytb%3x)^I<9@>h``u*+k??C?(>&np1&QrJ|e z10dkhrH4sxS>HZUu?kp+I*?01zNtt)Bbmtu!IwQi-wM&t;M8XF=7%?C;!EC&a9j$L z=vujCyk6POhv{m$8*H5yuEG_O7L=uc%<0oP%$LT$A`=GVBQNL5ctlx`!Cl#>;zzX} zMBUI^d&l|h#d9X1J*EVQ+HW70W0e0z5v_d#MU)aI97@8`|IJwN|0gf}e?9=fApiyx z^52VT|DW6bf8BNyfE;l1KlA%=27vL`)r^cZBfxnSeg98#y}4ExrgrQW@;_Mqx!SA~ za{WIZ=Z^bRcThq34z@h^|AXcK6g$yzex?$g$|81`+Hj`E=CkdB>&H0t?mYX)51#d2IoNvM@>tDx@H+So zRJjLtb~uB_-m0}H%4IZP`dgZEuZGiPiRROh*4_h~7gZKX5S6|ztGRktYopJ)1;gCz z#%{_$pE&c^aIeo_=xSVTS+Z_8QdUyK?!)I$k2m(X=PZbR=#{KJHN7!zWkx!w8fR&a z@a4;3SoaKnVNF;5r{LVUc{=kzO7B6~-nX>X^bh5Mp*{Xsc*=^(0`MAR4gDcI6eng&RCpBugqRCkK=mK1GKj_3CEl~974EE83qSCwg0R8L967tlf%T za~cZ=@*Rn&0Bp4=lxLp205j;i!kRJ!Ax}qveFRZa&-qt%h5*_ZTLC~s7aBWW-*gcV z;?Si65P)&A##GItlb-0s@nbpyewK9VMOBk11!1B|$pG-fugT2bb;qZTa$Xe$0@lsN zyrEp8G}IUvt2{j89a`TB^hD9fAgzZ!S3)($k!Y?6(|${U*VD?f83=^otPA!=(10t6 z*8D%$Zm1EoH_~-q4UfyV%$#rubR)|qnJi770TEcSiVuZA0A!KP^5TP4k|7K*cTT_= z4f&)|)pssaU{4!-^`)xU8jSi^8}awkS5GKM{9pQ(>4NeTdZIfGyrUT}YIu+hC8oY) zSAL^)m;< zxA}BM1gS8^mYb};^c3hIjlg+q%_+W3VbP!x5XnOj&9EVuKPr`H4GB^2p-gt6VN8~^ z{qZ?7_zyIa_dAJANpR>O4V57_LSlzXnF}RiG+%fTKny=To(W0&uf3w;(h(_*y==R* z8lF2g&*kOXv*B52SemCvUJn|qAfJl3OHETRDabvq^mX5DmVP%dyy5JF+CO_ z3wXCi;1n_q3kl-8!6t)bQW!Vq-X~@_$VdqYjbo2CfD$-@xcWYb8y>(NIld{Wv6JC= z#pO2XxK7@9$JRV8x~Telorr^iovXMMGiTUPrd&7|i!$Y8zyhxt(=_G(b^p#|h@6@L z9gqDzcjwveeQ=Jx0~6o`xLC@qqFG2_@;tb^JYBEzcw#0p(Y0LSq}Hs^0peDsSFq+1 zSUu<|d?cRAPq~B`>dK3&gGiWoa)Zg?iU1`laW9pfZ5#SiAA{%D%7i$|8z}K0{wGEK z_XuMCJCd`}iKpc@1O)uAY{z_jDutAl%EZj^e`UM>kEdm8B29-+%CZsF@bcb&vYlO5 z<819ow)>BSX1+l(;q{uWyW&Z<>x_6ad6MlOVxQ%ReSQ>ScK3W!;eUBrTJ%J`uh|Q{ zU+a^ZAALUcc-ybUJ-k`ap$E4yn8l;ypFB%u$;c4W%vVmReLp3qu6Cuh^uT_G%lJk= zTVKb{eB)RSzm0y}n^zBH3suDmubf+rJ=?kP1@ZX9N`DZmgp=>P^=w(Yum$!fJ)fSv zkN|PMnEiR-Q)D}%YcTmYZJYLthheI!o^W*=Tz>Ogv$#>{Frz1^=$@aU&maAra}I`j zsab5Nf{8^ZU+$9Wt9acB9-Gw6;VjsVG2?ig2upY6yJaYO>l zE!M9sm0y)A?hi;*d^qhrb?VHRMr_fBF4x8G2{xganI>P?B%{yA(Nl7qeqFP4NtLd- z&b-s#XB}333tk$YGS*CVQ~Msf=orHuW20(`he+O8_zdIbOs1;#UwoWbRLy-cSqCb! z`-hX+&|%0{))me;9!|AUE~F3NctS&s{FuWHv9#(_M`SvZjh=62;yT9V6h^RD7wQt& zeJ`DhaT1x8sZBn-T4gIH{OVK4OxG*3a#bFx-W|3-uNsmDqqiH>u8HsTS#L$h^^aw) zf3EqNo3#H-gfrPXwO}<(MEIQQ2t>T6?e7osopOMTxb7YRCZl%*;Eu#~WJ6So&|im& z(JA=U+;c2@imvkh|L!v*0uw~bZkn-NM?t;ZhS}o-*Y_$y4I6sDhCfjfr>|R>wV2(C zdlVxEzQu32^1LptCSe_B+++6U@N3ND3pD6W-QfobmT9sM)r*$$Mt4KVG53Q4PS*$! zEzd)7VBp8GIYv&VC z!PWcTu0wMax~}5%n}BWk2R5IaGpuSi#P-6>9JXeqW@F6cx$uLZCQ>+3qusdAPD~aj zQ-J44fh_!%ss_7x92|}KL2-!buO@VnBIT@LII5b(kA%P7v(D=918*3n%zQG=T^F!<3-c%OppnPv~|@Q`&+pdH;ChR+IM+nR4$?-j2w3%__9ML!303A)*vlf@2g{Y&-=%*(6mn z$|7_5Q@u;&{g*Lc=NluM8}xtva>9LqT7&ZV9mqRQ!2`D)))FI%?e$^n&p}??KGHci*j3Ym_dwEjjdfuZ?25ANV~GR}u2raG8@5A_2wN zX0v&fksRm+K}i`@NH%|(|zPQHS&(^?-Dg8zScVjN)>+t4bpi@Zk-7} z=`_95SSQ?c^nI~U;h9g2-nDn%etAi9$>^i)i`gGNQNFkckyc8nc3T2!7MWSCBnH#e zxWfDOjm>7K&4*W9k5#H9;UPxW9~B*St|!Amr9JA*Scjkrlmb+dxGp8qE2+ASW+V*wMrClNhpk>N1&?fa+Cz;ibDh7st8b`bYV z>CGDU50xGM%^{ZrXuFDXlE9&E5=2IjaLtc$hEKS!kn=_NW2+ZoGs%MMNQTbUj`qJ_ z;-7fwoEpN>J;WnF@9U?zXh!zFPmT=LO^Of?ew@?7I#gtsw0ZjRIQRwrGV#JKFbKLVa!`x5%}59`h# zwJ4H$cq&Pw$L{3U(1E$e(15Z6;;y_;;-rUE6HR%LU^Qw)u`4q-5%{|UBt%s^e*ono z0fo_59m&k_7|8O~6j{Mkv7U6ko^;>kbh*+L1``)nFvDB#dPonK;1MA-o*)XxW8s;+ zM_gR;8PR%~Y@R6zPLcvc=`J4+s(eYGd^%P9~y znY9Iz6idfl*G;VoLvqZS_F5YgsSplQGFv-H9SMYW!Ch%VCM6~hOF${b;tCXa$$J=C z9%zm>Zb8HIq%M_QxkOsPrrn7=;J4L_O?-bk@cx*X0mNE%*1IA!D7rpZ|5S{^ZJ#S2 zqw}h5O6qL0Afc+67M$GBFg(l^eNl*-eeWoLV*{j)2Xwm`v$$H?{6NMc^~_GgiFi~6 z4W@tx+|WeG&;bgxn}6fs)kwX*MxaNb&GJ^*(ssP|Rm}yR__3@4en{d-W9SlJo>oJ` z8$Fu^*<9jJ+i|_0zCp3rQXSSScD5qgD|dfB{A+EF-`6!`)A^W?yMEMzty<2?pEp?r7{(LXQ{|7 zdbXr#xFj(_4hL0@SCB)^N&MS$x9TmMtp-Wc0T4@gBntWt3=%mlrGV1k@w_J90YsJn z#if8dJ$Ef+P{@pu@UlB1z_K)34>+_mJ^bw7%{%rkN|6(8ds;H*@0VRzlp77Kh`V2! zlU*_U>yFi<@~pD*rQQ$A&KN516XN*^Fk+^ zLLeRl(C`p|{sm-%1|If;cqp!|u%c5Kg(QQ;a^mfBePS{}t}j=QxS zg0;8eYvk-|e(4DcO;%Ydib_i%%X$r@_ay}A5~>+x9AG4qS+rFmub%gP&py7&JNJE? z1!c&fsjFNH#V&m6_5Mru&lCiO_0?On-@o{~{-Sz)U_^b0T?6he?{s`aVqZh@>xS#X zya~S>QVbf?yc;vTb0ZTQbNU){8Lt}??>6QOHx(K*6?r$6BsP`aZMxgnRPnm0>UR@K zxVgrlxz4+}KC!v+ZgX>AbL;Eo2fv%i!Yv&JEnVI%-H9#nQCU5GE&Z=s?liXy3bzg$ zw4x-zqlv95RFKf2twdSC$nREaV#`=g>tv4e^rt)xp|;n3Z7q-!JQUD%i+=(L+_ZbZ zhkG!Z7**Ajup%5NlI`ZMUAbO{k=H70w#)nW`hG;BFv_;Du>GMwkSw+b_N72gG4XER zypx1`Y^(q-EO2KMBND--gay(Q+67sQ;zD_p=yvoS06$t;XSmewgOVZ!#D#C?!jh2q zc2*RS->X@X4iv^&5gE=Pt*LwIi5)ISKy@WiBc*h6pHA8&=9Dw&ut}8B46^;x*$f1^ zgmtNLfy1e=h!ajTEx~5>9%dFKf(0-kx=&^hVc3%j72x63C<%372#Ix^-i^D-HjH5{ z068y>V*OhG`UN&mKBs?B*@?r+T(E|TO}Ewhy;mHz+;HV$;3zG zW)Ox3^+JPHT|w&PUKf0Csy9fB2t6^NY}g@@6fhP;CQm`VkWgy`SjXo-UI!C281`C7 zodPzcJjvMuI?+s;C*!8gJw`59TrXlx3Ge=5U|S_m=>l{mJE(S3_rF< zO5h+kD(o_SSncAYP#V-4|5#=Z9E5>cQ=eozgN$g{=?xq%CXZ2g33;6WniCW_;LaU!`x0mWOHk0>0kDIA}u z%oc0SSUN0}GQ_$uwa5GF!}jmA*zAVVBv!Ellj2r?uN`J=%F5N3SdWp zy^#POR68FR@ORtc5ZLku+{cHB zobPe$@6jA>G=KyhJWl6$OJOUzI6-a}#UiK1pCIc0Oavk))4V4y;U*JmCL<_NEizcf zc))`SyF`Rh?YX;ir-pI`WNF|K`ji^u3%`}`^g#vpI?DszjcKIv+d z=;z5;lPEBKqdoZVNE+c)5PK0nNmMRKFu?c~r(vgn2=MQYVD#0c5Xal89^;v<9CJjr zUwAeiEYJzXu|;HiNvGa1I%UXr54|(aLFkY$1S(;cjrf2(X0I!Zf%?}d;p|1MBCpR} zoDF>ATJ;415MEXSfWq5cB}K%_`X|I3!1qKar1iqR3i&!+)7<;oe&zM0_zpT+Ny;*qE$?w-Gu`yJiJE_$IeEa6jIy=`FcCPhi zpjlq$7qK^Q*?EvEP=3rkfH>F-H|2#`<i}^Ev6aIRz(R&Hp&vNUaJdeQPEep6xP_xK z*dpNNCYF_lg0TAvO(!weqF71*a2FDAAWzGB2AYm#t_83ZVVJBDz!MALrOKB$V?lm8 z_!gC=;lyIXpsuC`03{Hx@WHJTIunMpnKZC1i-Fw&uvB8;9yEXxo+a}Iyv|+_NduSw zmlrrg@YuJPOc7Iv&dj>3W146y9p@rHrWl;2t zsQX@j*2Ry(Qs4IF7@YmB`=gFv3;^0?gfPE1B|bDO&c11V0y83mVP6l%*Y-^@`_IL| zJe<&(ey|e~>TWtYVForZ-4i{xuRr_N_F~_Qa#-InaBg*9=IwzJ4Qyfh-IvzykNFvQ z?uq;EGZz|!)f5q9`d#|stU4!DlfgORyC?8+nq>Ihnj~t1JrLyN_BH+PM1;C4!CXi` zEg5vC7yE`!!N#22Nct1*Gkg4Mlk*PXN(T7(4A_G6F!92O&etD7Hy}pDRrYpJrv#Y$ z<>ln!c$oKXk%EL#eP3EY$1PFGJeKvJXfDGowL)I502(GZdH!4Z!%d zi4=S|qOf79Um3I?cWEy^QP|#IA9JEIPte)F5jhLi*e4LoM&u5_-nV-!DY9tMouX+G z!{nnEe$pQDFtZ%~QMcQt9^SnRhnn$5H=Mcm#D)jPy@0&W+j;rh{zlLkyO)eGkGx9- z*6yhP6!a+VY2~pI=2ZF-}sgJ-;``)N77dvW2#0?)OEIlJPV}s(G%# z@Po2vcg~3Ghd+8@nWc;}7e2SPKGd(n!lHiT_p(LuQZ%h6elQ;#FYOFnst1(!)jsfQ@ zhv5PTbl2a%%LLaN4&T&TPP%2z3botGgGm~~^Y;VM5$VzpNb6Io9cg1k-6V?*!Uo+8 zuofmEEZBd($WpU@5U5vc47T`#&e5e211$-5B71gi5WAYH>gOOjP+$W7WDwVGO+E4Hl!WaQ|-#@EcK{5hsFeNDCjbExWx zf~}4$l@HLu!MxHic_WDPoYPAqYPK1aHx{F}pf^0*5-7hn#j9k=XMoshjiGAw6K@Tw z-1019^@66P3`kcTTZ2{CZQf^!^%vpT{I29-b) z^ojb0=oSAy!}C>Uh4U3Et)4TCnkIR5%}bAQ?}B(#rr4Fzb_`Ti;n&vv>5&(i6)vTN zc1n-j;WJ8Py8hO!s264Fu=DEyr=bb26F)cmh3b!;%HP{N5<8b4F9?xHUMUx~E1exX zbtUo{6Mxs=d_qCwcdxSd>3a$FY&RLdkT*l&p&zxbtrOD22Bfm{l$3}Yf@&T2^exUj z5Y@A~kQ`eLk$CYoAT%Jn1M$k=bt^fxRdAt+eJW>qejMC}!V|7jqd}dJ zcWLnUhbAu#o^b|0N|D%XU=N{J3BtE)q^#7=hI1pzD-P;)Ms~nP@MoDXsOFrN)xKvw z5sxS7a@uvklmij)?H8T0@)Tm42mM}M@cUGa{vnn(bI8BTt{D>Wo7Vqoi8qIl8EVDV zSw9trxVBE2swO($4ESyy|DeN&w=&?SJm?M=R73nAZzJhb3sLL_61kZUW8pFnI9ufo zlaJ55!QCNw)&n80T0~$C46^{vhDu3E<-mM#o5wwZFa!%CIgPDIINEj`B`TRvXeoDg z-yOsij0C~-DEu5~JWCM?%EYi=9v1#V<{ZIu8@n=Tiq`{uc2#ueY))%DsOD&Hm*z$r zX2Y&iS(kXfi7fSu>Q7JP>rQ7P`G>Mj>(zh|BWNB}g0*%JmhWK`MF76&Xz;N5Q9?y6 z0xdmmDhJ5CObL!yY8=(wa?WeLbjgZC-qQN5Ge@{+s^GNXnBkULzLNtWEkeX*b#R|M zxF0C=+h){zydXz{GNQttgFf|QkK<}Zt?*9kY5nz~1ux2hL{5;X;dBApwfI`$*HrIM zYe1$lKUvV_p3}y?1usIgwBlZp%vcJzJd%@Zg_o!|b=UU#mbIstMsRtC{RFl^B>3Ug z1Q>7HbHla)a9w`eC_`^cUHytESZntEJXcY0W02f@C$-G~a3pm=oh2CRMVBDQlT*cx z&@8`fpH&B^ngO4O8W`!B3m$)jAgXNLB)Gx6*J)shA{$%o%@-h&(|9!3f$fBTsWoD2&zbEyP5b<2`e6^ z%VxKKQhjFFf*CU}SxlCJkz?eHuZq9?6*8g-XCScs(PgHn4rk?gl)psL&-A5Ftz~w| zbU0tkqc$`p^mv`J%J@newGMkG z9KR!KQk>8uCVcizr>{51sZOZ)5uQm3Kmbl-Sx@2|z#BK?E9nrx_C5uyi~@S65`+%0 zO!|p?WN8#cVhf+nR}IJvE=m>qjn3dXy`{~*Noex68kPQZ!hLkmikpj{HoYK6&37QN zFO^zH+O-3^Dw;YpQCi@3S?{A6GaS z=W-=s*P5aFf-dX|VHABm72UIIKe*3l0eOG-z!dj4@^tXPCF^TNI{xoC&Q0IUc!tt3 zscWZRQHi{~t9SCi>}8m42a0-6WvXl?FLG|DNTdagN|1=FF3CX=TjStsXkvP~z%8MY zcndM#4ff>5)Q3L5nM5f~?5CBdm=YRCN4}de3sW=Oy@MPSJ^?bFY`{w?A4psU=FfDp z2=kSrPtg6+uVrtKeXVrC2~2$zK>%i0eB6Sk+C)-05!cUNjzFCcqF7sKuj>jg`zt3< z6~u?mu=|q;(Byf?m!VC4|5Arpv~UR$xkFZ_%dX6vzVWXfTC+#}bmQH*kEB~M9y=!+ zXw()jNgu=X&BIBmXXTe+KiUTAvfBY7!(?eSOZhXCp$Gj2CrAqdVK4vIP~1!EV1EO~ z(S?kkW^eD3mKcXe5f1WAhqL1^Bn-z`j~QL(mH>CCoG^v5fgk4q;=bAD?I_=024depwQeeg4>C4VY>-R8-bGu{**`2jZo`ZfPIht5O*qCbi@UjIq(~{%mp8! zLQ6?aP|pF*EWA#Set#4wlP9Zl{-(7j-u)t&ksg#81xWj7##c9PviS~m$YWdJP(NUA zbVgEz;se%3q`Ep2HKd1H`U=ESZ5|L)v^1o=^;2NGELKlyWRpr5`eQB2gsG!x^UUvpjzE5na}cs zhU5Nf(Q&pvwrGO_4RXhop^iT*+zf%;y78XQR~Pw@62JgO9;g@Ry4!tpJBXr}rKOiz zyId?EcyGP0mbppo=?XzUhdjh)3ldC`M5ahBgHATOMM-jM{Q{^F-Sa0HOx&}m?Xp(= z45w;BrLur`tu~Whicb<#dD3x!NPko)Tv^4@3IKN)STe7(!|UY zGYYJ2eFWsAzhnkra&fIjyjjdPVBUd~ge_zulwJtZo0U&5pJ%d{2RbbP*gf%C zgkJw`r3Zk~@zS0I&t7G~^Q$PPsYLMk-E#1(?JxORU*6LL_`H%S#hB$sEo8h7wdE=m zrbcEl`9-L#1F~lU7~VJW+*n8{D)ZhBiw{OGnVddwoCz094TV3(=Zdl8Q=V`skL=8f z`vJ(qx)1wvI-fC}RDWZ-@Y2Y;xm{^bA$2$K5~n8|epcr@^y@uv+IWip&z|5AIrijd7P)Uwm?ucTr=e%}@0}JqrWn+0 zE1tp+c$dFzp$73XST>?aY}<)%_Z$UkYzC3e9C~0b-TNb)`mm@>bax0)XivTA{+84x zYEaCF8d5iav+p_{?n|ilC>9pE@5OR(DuLBbOgijf2|IA;U$v!}VcuMzQuUD569?ad znVDVn3g24BA^hco91a#}u0X&EqS>iEU!i#+gmb{j|V zB1iHogM&K3q8?H%-yY81RPnai6liDq=_jqMZ?UzBe4IuRD=iwY?QJ!$&lI~W0hF-- zSSdkx8w4g1SUex8P1jHS61|6QzKY2Vj<;C}vt)Z;qY8rX9%h*KD6@`(&W8y_HiB8l zbEL;plxd)c&Xxj?AnN1bs#)Q4N0Ye*%m~_u1m!-~F4dgU0-Ukv_OeNzg{zk8ngAj1 z60BxzdNwia@Z*38Oe0|2(OQy%f^;-mp&51aE`T| z#6S4sC~DgB#_22anWcLoN~pZ6^b8ca)RC9Zgr!~=5B1e#3U0JzrKcNwNmDoXc-`A~ zgSdL3RQNItG%NO|+NWV+Bc*z?vUP&#oQ>KLsUZQC=|Xnf&IZ0QkmLyRRRz#aLaTVe-$N~yXfcs zedHp;d{Il@2=Q-+Nyp-YUF1pH*D1YXcRfqR*&L29_fk2r+5k%N3Rzzfg{_pLX+ zgfnjl=xh}`R#SEn6ql-o7WX|spysRA{JCt|s_!!nEA2a^d_hkFbB6Z;50L?gy7d$O zAZUYY2@DSB+IaQbJu?rHm7Z^@UW+}P&bjY#a8uSQj`G!Yh4{RkHQ7;Moy(h0Eo@S- z+fVuRPEGzM?bo*KMw*$?l$ZYd=_=XVEdXx{T;@}kQ*C;1rNctTinR1eJWgsDJ7%=L2ldIUMMNW@14`o~{ZM}-{e;3#5 zTbl-nO8M{wmbq6x4@wV3W?pjIx<%;TJxnj^Osl(CA^|vOTFfRpb2l1iaqWa7SX!D8 z_SVW6dh`YQHcUVq0KL=$3y*JjSp($ZwU@RlaR=VkwAt8ZZo9o%P~;|SH_NL|1D!~; zM0|p^T!I?&?=MVEgiqXZ-;+@3z8@--+Qgq_G67Nw+ema51#H=RCva}CcJKfNAhta0 zuls|Wh$uZUn9!weQ^ie^Y>eb&wR^zBOdilSI~AYbk}o^<>XtNC;2kSi7-+(7@s3er zsK5eN6?`ZLUzGn&)`WYaF!l$HcXVG|ocSlYoRpu*?ryx^&d{t`Mk;wR9RT~gWz9JX zkA1ot0UFKF6agZh>!`%>Qbob@rZa#I2INt4^=Ha4Ff?lmdm4#V9fHfFg=7Sb)5~7C~4lu4$aVhkN+VPsy`@{u_R7I{(7EhH049cOOc56r~q=xPAc)tYgc@fUo zjj*oNnoE4Q$h>gIZ1L)zgf_xqTAX<1<#!Zs>wgv;0_Xj@0@LlX6+73iiw6|I`@!u#f}(*Wdj=xax5K?B+PS68>xOj=LuQ zBv86NyL{pGw~IAa@`z|AY=TpA{>-8<$tL|ogy$FrO%Fd0&)fpur?(;|%1M~gKd{S3 z8BzTi6MyN`LyvMTGh9gtj=1#5(&jk+yvwd-5!fh`D4n*ZS);tDtF(*=#GiJ7q~wlt z(XpIz+Fs@FsB#kAbEv$tyAZed$t^#YEg`FT!^8p-R-XrO-Qn=1A%`NU)auzD@kb&sV9nUBv_Z zs*zx$H(cWSAcc5YcuuTU#_LF?EKbJ1=ft_wc}3h{fqzP7LDM3tMuAjPSbJcuAe*kZ z^ZaP`Xr73@Uc&9sY;=ZttLS(2IqNcAFY_GU9Xe7loy}g<_5dc6b=N#oRT=0iH*;4u zu*e~1r2dxHrSqR;BH|>o1Wif7K-YQ)VeQMKbh!8T6ZN&%v_{&yy>XTd;hxgtf@s>D z^5w~+#y<1B*F8q_71ho)Bl!%}i730#pm1~um7ktsBRWf8oW83Y^9qT!uN5^x_s}Zz z%_}eL)71|&BoA^TJ}nP?c9R-TW9GPyD*yRn^&T923Kt;vP3*BgzZ)v_dK5B-HK48`399o4d#&Xif0@qkEk?s zBnOqoYVs|&Hv1$p(o)qV3N4r|ka|NihTmerqZb%@*lhi;)6X3ESvTcGrB};h*nIfE zYamS;cCjT;kFcLFbQuK;N4KC}z6be+uSI*1<}*D(v=wiEf^9K^a6$B4}?F1YbuUW>kK!XI!$hUy{Q_YAG9S~{Xz)-^hc;ms;y|6+4HCD-gD@nw#4m_yYYotE1jC>8 zi-sTUn`9vt!{m3HQ!k-}{r?p}_0StkmuR5MD<|#Z`;zS3MFL%~Q5jEcfT%$EWfu;< z43!mTh%bVblkMoXd(;-nxOHVvG>k9te!3eg@RgalN73~tGkk@Rpbc#Kf3bJpPff+~ z!skyaEkNiULJz(7me6~XE+sT6qV$fM(0h@NprJ`eK&pa|_=Wi#sV?gpz6adt@d3)OViwk=xk zho=OGhQjk6)FG9^2cfp}Q@E0TFUzd~xp=UnFml)!K&ZW7LmR0%Pn5q{G$i084KbC7 zxGCt$gM~>V!AzN`8}1kBl`>1X#8W@>l#b0qH;|7gZ=g-lCitTDOWp+QWjs&fiU|+9 zIN!%56M7~hhwR%?1b-4vUvdV#GuWNdYKdcL&Du&_P|f{3yvt=WlZhCg%Ksihm;&sprboj6_9C&K1 z{><)MNR+l(k+dW{<1VT|o3lG5_YBV|04}a@dk^(n z80UKvH-7i}BqZ(&D*H>$1v%?Avowuulsjq9wqCVdwYQd_x`VYG>zcmNjuOUffeck& z7P9dkh@^^`8Wa0VTpMd~s6zeL3Qm6KD-?O99(`JS4xt%M`n&YDr1c*Rm(o(qu#i%- zan7VA__eH3`0@h_nmIC)V;LqtDk{g!= zrO2b$IiwLxzYAgLmw8F6A1Oaq)-a*w`xnu_*0AJ7(=R z@*wC|R)1g|D|ZPa*7Bn;^h`?n!9JAXjSal``q05 z)@s!`rQ?`}K^WVbpViz{X@%Bm%qSJ;Pm~LdqZno06th|2j@3fDJ~H62{M{;2p%d-t z3TDUfs0Y5h&6%WB-sHj9y;>oPVVu&Lv=Jh3oeS$m_ROY7!xwp(t1syzK`2F>o8NRjbYuG$Ip)o%=byxX#RXY98RjJPBX+F`&6-)nJ8e-K->-B z`r~eWb6)#Anp*}Ox#;sTY=wLlZGBw??dk0Si73 zs<04luNshmV&9+mGOHBl?<8!xd(pJ=#X|n&+&W|tpc8*Mn%OWI8X3X-F{!2l9`Sd$ z_zrvdh2{s66?@sa&Pl3_PF?rdc*C=vtE^(%k>!IEB$>?ux4(=>22_rvblGV?VBMu- zDycNrmVmTuyDTsFB}+hKit3ESl{Cq^=DqfHxv0^WvNVyV8@i^DVw=)1@4fxKy@d&xYr84@+_NS%fAmuCtfhvCsVM z8`=1f0^mvr#?5z5jmo)n5Pv;*^f9ne52J}*J3E9kJb2sS(1r%%%_?gT*5B6CUS?!l z;{v7_MJ8#FkziMIEO~;Z)ysdGHg-N&^!@gd*V>EEnu7uF7x)? zwrnh{P5PXA8!+ZMbo!-W2vf(>N9`b_L7*AnMk8GEuk*^e6mMA}IcK1_U$KEV7tE}Y zY^_s0#OqgkY$!}atFb4kCGx`=v=bQVMIm!Rh}xjR8K@)mw}zhxQ~MgD$K-%&n6?cBQ0;~Bih6-EL1_B3)}bF9SP z+8@0Y(Y0U%-8Iw1nkS@QK;AUSoOg>zn`KKkjdJEn9p%a$b!NZBl`9&r^9(oPp70^n z2`}b5cZ<6k8`$GNz0l~IfDJSsjgy!RdPHFI6j>4^fEO_5^MUAo5<2F|vnz1P)Z5ul zK)RRsr1K%FV=tA?5C#aA4R21hWD>2deoBx5Pj7MLg1)NfIL|R$)rfio!>^GGQIa2{ zH59(VX{;8EVHX)Ex9q9_`Ul!GYWDSMfu08o`R@rC8nwleW2;ho1|LU-4g2_yDt4gF z1m(Tm_0kl%1<(()pvha1Vw{0SREiu1M9*uG%ln31A^E_cvMYc5R3GDamb868wf4dU zTWqjp^B(zrJd_hB6f$(N%uVP%c@vuybQ1K0)^M`?3r#CPW(PH1d|3thven-3;h}%d zFu{-Jg++y%C{;c*^5v3W7+aa{=HPMKlOX5neCX5V4?n{{I4PE!9JBq~YaHMkwM!-> zb&wkJBx)Io>b~J;{ag4W${ZSk5I)|`gxb;HA1>*)z|%oZZgoxBP{sv`%72*P;03?C zLG1J}hsj`;pAJ{`cN~~Mat%L2F~5)Jn+lg)8kPT89$amOTP|l0o+=@A>R&7cd%zHQ zusj|NfPe~n{y>QCK13-MwBlieXdhLGf@tL$sPt0Cn3gb#`w-n+0~xMLT3!%ZK1Ho- zTqAH?0Z6Ww-BlqQ=(-!E8=0`nL(lgXktfc*A^C{h-DZ zB-&wua{i2V2S7axQgAoGUo%j&)o)CqN{#c)P_?%BFg|wm_Q3>z!p&&qj%6wv(qv-g z0#h^#$5qzHp6-Jm-83-h+mpvpYq{u0V@K7<DjoiN{K7Dv(NZ( z$Bn8HUNGTB%T6!#w?J8?bNtgr1Kv^?=}kvDmA%<5SE|OA-SS|?FRE-rBp+&mI8%+z z|K#tj+dK^o`yA6_YeY*G=^y3JJA1degb@-1;rkmRd!FwwNtizxY=eWHeJ<>rsZ4g# zu-0afFV1g-RAXAgd*M}{)ghj3W-q|_>ZK*TeFF4?hIUc5#1k_-d=hk=~XE{?j&webcsNRo<9=4l`eAUNc>lX=&kmk zh9hyWh&yLTvWd4uV{e|iDvB~1Nv$l)t2HIWTLo+A!prskMo3lzC*7 z@IbG{xzjS;Yq_~q_1cl~sj~I^UhA*QHov08ZhzPKqa48d(s578?t7%ppBk>sNR!4i z(Mu-y?i6k41^e%x?C6X#c0!!!RAOBPaimeHR6YVKg>fJ4d`HEtsn0F)2UYt*-`26) zbf5cE6_2&P8bBp}BO0?=?6?=A_C>{zqVhV)M6e=7jkjMdDJ74do1Qubr`P+@{k5;x z4_B?!*Fybj?Ju>HDC4M4egEmS#Izq)KOXH1yrUZ2)E|8BXRy?S@cuY?vfpgiK#|0A z*?`+eBqW6KwbuT)x^}YR>;5oCweZ+C=lVmq_&|i5TBO>qBv_j0Ns6we+M|2}MR{c;$yX>wiuIDTl!K0$5yH9^sgE; z-8GgePCu+y;lTCt7yH_NAlD)Y;)BU@>M0h>RD1AL8$2w|CgqJ;s=**^&mk>TJ!9aw zZZ9+=<6PKQ&nh3xx}%=mG?;x)J!fDr=dpV3^kD8&^}Mygyf^Ck?+5e0su%nkETE_t zQVkU{Y7}u$hKd9Ym1}fuUQEHL9nFs-J4qtPRz?(YXD7==Rrh@?_`^MT1E7fLN@7 zW=p8eutz^HPhE9}ah}$yCBW2w>WOGJtZ~$9oe~2c+zr)iqMNMs(yUWErItQzO3`ev z&}`I7Xc6{k8hFt5IN|m~4Ba}Oeh^PveV<-_w4FyYPMNA>9*{!vHX~xvksdnrp zbUXyme;*)l^z9}Odu{$yJ;Wf6@r)BB4KFQ5d8`dv!oB%Ly+h3ToDa2wBV&{neLJc9 z-T{L=1w`MAd9X>+TV2yTCNZpIuG?un{`K&2KzzLtf!A+b6@aiDoG1EI)H5OSg`4B9lErCj!(mLY@#>Ya3=}k``-_xEypXR3;<_&?U z0OR~2DN533V_Fc21K>W#g9)t^r8BUEI%Fy*Ma6cUa~zz?X}pEwKs93wWO&F5V^u+6g60GYgnCnjNcYhw{j}yXE63%|7E?7oV2#e z0hZ1I}gBP5Kw#C@-qZp^zfn0q!gyj;-0hwc{pvL`+4or=jqt>8@h4_gh%&C z)Y{rAAt@>cgs*fD=_}4u&%hnG+Ua{q{9D>8>v+WR-#0la<836WGq4KlIR74e?BclG z1Tb>z-{;vT6KCc{sL>Ccj%Q<5Q>LT|M6Fo(=0pEK#1 zDQ*);@qCVACeG`2yM0tC={l>`f9t$=z5XAZ7OPuo;qO+5iUVx!oHudVG)n^Q>P?Eo zMqIt2EE;q?mvEZ;>3Lp@)t_Gqrchewc}V?sn-_dqX_1LYnXO&yWM(RznSv|GZs#^a z;OF7S-6Ats;|&lMyLLsG_jm@AxYKY&xbJjJ%PMX0zz8&t^+Bl_~KZAIoI!-JR+}hVQ%@etG?K7sw~!28D92 zUywjF(n};rQQMc6`O{~e_upVx=(V5eUL?sqKLq;`bsk;b7HHtieJjvmmYd6Ie+1lB&Q9+rxno8@pzfk$KpT}xg2ZJ;3yWw_mpIQvViG`i))wOXB zxy@Xb`)iEKpOP6mcs4ILiny?#;BAjIY>Cg4CRUxB;)Q!iZPvtu>EA*9t1FyU$UcxI_9QOBR!tt}=ZVy|}Wc2cT zq0axi(=uKiQeee1Ms#jXLcB1T?on=~Nz+nH3XP<+rcUbMwR`bieg4P`IX&Fn65APAN4eRTvH#IFUj(f{s-gCk$ZiKCjgq&0S@?jr5Q|rxnar+?P#1#E;cZZa^yD>@>bBkE!(G-q4Zi!k1jJpPa7@ z!P~w3G)g14bvS;%ah=K@TI8cA?ie--(||HHWN8Ny*%$US)?;={m@Ygu%MXS zjGG-5*6rQS3Mh+tHT3oMpRc0Kvwe_m2hDf1c59-J$&bejnjQ z`TP6p8%pJriSF;(f~1f4&0R8~gd-3c^yAhYFqMm5O9LYi==PE#UxB5+Dj!=I{F(~O zsV|1;(4S;EcUsnmmwMAuWTLj|yw`h}{D7E*rFDL&V1`cMLb~Q&?bKEEv1bPa8rLOn zhQx{qo_~j#x+MmT;h6>k2=R2s-W|5?ee~l(As&z89ga~><4x*hCepgM!dQi|N@sUY zX4fcOw!%nbu_!;<(DwDwkt*)Mt{|}iE*2iZvjFz#mL7vi3!}2bA5-=5Bt( z#BzRV@1CfFYc*4|HC*f@!#M;A;!(%b)E#F-Fdx`hEHM!FnTs%M48b9vxujY9tqhh6 zbYbI}6eWywq{wCI%}`uH5VS71RB7p-U=;Vx;GJSEm(@MXd!CcM?^L=gpHxAYuD@Ea zEOW5E*B`fXT}$zf#*-{P^Wfr|&rt!YLuQM=tt6{=OWx~@R1U?SJ1u{Y#qCUg*$^1c zr&Lw;u}oFAX|g4?^wIkUg4}jl*2=}d>-UWms+PaFI@I(1*f$w)dK#Qu(jclLF=&`z zU)ovHn9m%fbCLT(#0zxZ>BbhRX4-H&znSPKI&026IKg(OPhrp zB~3$uS8A+FTcxf^+NHIE+pAJr%=pZl6F;uj>8rF#bbNGO&R%9N!9ayvE~{^zzPNS0 zq2o&0WsgaXHN9>}=(hW1cMIfVVS68x01Q7< zspm5c<%4G;SZdp))F94r7Df_?FPG_+i#7ENp1NkwA zyEG3or_yYA^Q_4ji0)?$6s+K5vo*-KeF$Z!6Z8!WJb{R)hlO$Q`b%6q8e|wW&>X8p zFv+FNZ=0HE-et<9YezwKj0ljD<@~qSzLQf#dCetn1n=>xYslniRv#iCAt%i1$uKRW zyS2jLf|_xCZ6tly&QC2-pNq{YJ#qYWuiU!wS?QDzjT1gut^vZgLjC>vERxzkDV{?; z4qIu4Pe!(J@tul}v&`TFqwvD)bktar7YXmJDHN{Nvl@8%V~iJb6cK{8&ZrJYW_sDA zAkk zZ4!z;kO4+*?8HM1fd+^F5fxbT>8*GBI#%Fxv&dtm+E}YHF#*g1t$ZO*)QWKC%f~nn zAz^7JZ{Em+Xl-sDX2$lUn8<9il#pSmx5H5zveB)+|8};?XC02;l2Yq49)GOz}Aa@893i) z66)`@w}t{V$V>S-;0ISY*vW(TjPR=AD`TL~4#0Eku0LZ0hA=X8 z(E3ag*(rn@+mcxi`}{uc>tT8}l$DXM3`C`kfqDXv+tv^aacc3)k>XQI{$+UmNBEON zL|@vbk3dL(Lk^z=zEByxVDjjz{|>!!7^-4lTV zIn)&!n#g-JUl(3UA4wK7@NEdPTjM<)a7$OWPdW?9`Jcf{3j3?ygf)*OeniL>3rkWg zLYX2LU#maa+y|a<+CKl-1*WrPq+8^F_LTdIJ=dA+J{hs7xJ}b4TYdfDgFHYvW)$|e zeTTyz9Ny&neWYwxtgsqJMfHWXOpvq8nB}Gn*MU6N(n-G5`N?#m1(qq?{ZnR&GFJOb$V4T1 zZdSj}tgfH~+y&E~Ffi5c(p>y58D$dBir%qfp@2>`cUpv$P3jrfXg}Fh%NuzE33Y|0 zv#rXGZ6cjdgzxs6bSql~B_GRoKSyK!yk2R>O9n(-GMzSu&Mm(#@uspS8W5T+u{$k2 z4NcOt<_5`@vkn$NqHMgA50J>kr7sL`Rt(~UEx)Z=evq`%qKCgLvEJ^r)vL4nRAP$- z+X$4}D5zX8+d;Lr^F084w$2yF0PsiNQ&-Q2PgEQo`?O)-pkV;j7M*@P817m6!4T&d zuHszm6Jr&b08tK!P0CuC)M7y>85N(JS@9cBy zi@rG2cX8y$#ZeXa$!Pc4KKCa-+`G*Nm!dshvJH0jdTgsWjw`hVhKaT+dwydRdCw;L zv()pktQRPT*=j}Pv=k?*fMY6SrYbX^KlI9R@L*B(d75n;q&$d@am6P4sIdEf5AFzD z^|iqGn$#IzL{+Gy9k_m%nSYvSbV|HAy!tgnr#pIw=;3A>=V6U^Gl zk5anp-X9qL@fIpWozx-|<7ZNx8x+)QGA5xCm+GUZY_Sn+lH3m!gZZT9Na&V18xuR! zh5f$vTJ}xYe_suJ+243{2`rDQo^iOUfZICLzxpa!sjR7#B8>w}lOTS0V+j1R8ZlIl z?59J#I&Bp!{#oGCJS1=xG9?36MTObKbgrsK%JrQ)E%lcDuydY}76Sn1Q}${W>cW8j z06>ibWPb`sq5x`Kv{8994N-?xDgeL(h6B+712J^xF$vQ5z^GWG@~9iX;%ETiptVZ* zSNvK_WTRT03(Q#uyC|uHg5r9IA0bRnug8{l=Vp;$ZLk|zP9mrm061e!@&_~1 zoWpb~=siz>T+R$eV#Z4%0Q@3ktfx}}bPOb5?<6-d?)>Wsqz(d}E+AGEHG&8r$hjBS z^EJjVeUHdy`dyp-iz;D|8cOm`RR>scX>_<019q?wit0EPNJ4>uH4qAw!E+8tlAI~t znLKzFp4H*y=ZpY+s_%~GXy9KNB@X} z^A05imH^b4nr`Avjf$YG_{f5xJE9h_;W{AdVsGfGi^?dyY08`c& zyGqb$?9HA%sNxXaIzY{jQ*tAvE^~t$`e8i@0GbP27kVcrzFpyA&75Y{@_Mu{IqxzF z*l+TSghQ!G$o>aujt|okUG53uZk{F3*lTn}iiKTtj@gXwE+=+tq!eYqPuM)3sOGPSJfs%?Ag8bNGGYna83$}xkh2b03r|JP+aYI*G!fw zP&yviXpECorO<-5qvL>LqKG1i1TaZX1X}0TW&$gi_u3&(C^MqkvMm63xE=nVnqOe1U!l#)v3#y-g+V~Q?Rl*mge50x6xL>JG(plOet{D z9~aArqYF8?T?t;HTE9(4x+;Sr*=eTcROxZM_p|){ZeO0cqB$d&IP-ABj1=iDqqBB# z<}UM2=9LP1_6@k9`AiCsn&XlmzP?!ga!KjIa|+k|LW|~$=hZJn|IS4J-SEgemKP`HbXworafx$`|I%8v-yRO?=NTzuM^j`&uJ&)?{n(qH}No ztKi@c6#`G+pFo#Qz6JwW*4L&W?@HHV&)r&!WA{y}lk2}v13qL>(+&de40kix-(dMu zDylmeadY2Y`?N)_-5iMZkBwe=FKk}^R%zO2q&(I&HtBO>Gz|)hdT$!8vq$)ss2dx5 z=d^x%-_s!GX<~!qf>!VqG6drj)jH-{(c@WY2D$#?p87ak3@!f70_t`fVW2 zrR>(8=QZ|{ibqwI*F_ROyhxij7_RdP?T1pzbnny-;-(*cjizd9ImJ_@c}ehzX+Jvr ztNTqYb3SMoWUu{&P47rATWRnb-2+^zob!>2SG~FckWMau)dZ;BIF`s(*F}NFfC#I~ zV^>P8ZES!-{}2BgKZ73syh8aIuJsA?erQ#3+!0kQnvOv)B1n!v{*a{qkP*jqGOX0&mPQDdjI5x zP{>d1n|JfLRd6vO%~?@6w5sjv-G1{`IytHx z8+{?0`B6-}#*EyeOCN_f?>8AT@l-c6alf0+esJ}v8(HW$uY@gab}A0RrD&BYX}*NN zd8xUA(}d?gotFLO28&y|R+=f9{Bd7ijXyUqg!edI-n{#9NitJ7Ak{4k1deu))891B z!mc0F3fK}4P+Tc(#~+l%%Fx~Qxwi7NX^9jD-QkmOd-J!ZE4(3}62IXBDs+DKpUu*@ zxrtrnJ&7+yU03G2ZxGg0iiEI2_ylpL3hfFGDfCVzlp=pD)9S11?4Ft4>D*Umyfd^3 zBscAQKMF@7qK|&@8wd}_V&S=>4Q^SI`_ag3)!P-LFl|2NH&=eR{s6HC50An;`ejyy zukz=gZzqa$6dIM-xrI-8A?E!;$oF9htgixTsvbfPu9K9_n+Bo8`sf#R2y^qppQYE z!6n!=M)xTCDW=nxf5u<<=Z?bG_nsBP?4JH5!`8gs@X50JH#~{s4mc^q>7x#orZ{yE zk;YuE4kqJUKD-K?2B-;gDu+i-5hacBP|{&+=holIi7n5R#RLRF={0UQH-NCEFR+Ay zae920ahag9a_=@;ZW;BTS=3{^cKobdE#mSw|VRg&o_J+b(3bc2_)6KeQshf5q(H$3#I{Rf52m1>;hOk zY*Ok~E!K9G4Cz-9rPt~j^BPnvsY@aXDjX(*u@&j?fA#uh3J$o`UXpSuL6*6AjH;~)x?`+m)1 zA6(jkv;w^+HF6aFB3+7Ngoc}I?;OAWA5M#z2HR|vg08lzuvO5QLCEX-ReZVklHUI@ zIW@J_`^j5NC5#skdY_?Ky6scYnn0jC4ZyU&GKRP!P3sgt$PDytBV6(Nhl4^ASOPIJ zBRLt)pih*h7NwKZpP{O4IVYU0^vZH9U$> zkj}kXj3c3Vd`7S#BbYjc_3lv30}XF|Wy4H(9E4K>BS`13UgEsO#`=iKh}Iq{=A5r2 z_sli&s=@ZA?w@pZu&Xz{KGuVs6o!=_EXvq0+cly#L;PRo^c+_;?1 zT7u-zA=gn76EXo*;$Z={DpXaO2Fqs5&G<_&6>5$b;rDDz! z%~KfeP1UoVG}1c_+9R$n@eKZ5@UrdT-NWB)9B?#GsTVQzyH4a&QQt20Dj{;`vv5U~ zdDps>2(mtEO;_QJ7A#W8tc@5n$ofpSb#G?ndCQ$*Zbk^!E8Jor9i}Uup%j&oMDCtK zXBXq;<|3~53f~`qr;O*WMtkg2;g8@7((H=bhhw!3NY^Zts5+MJ8r$2&%m3-Le6HZ@ zaMpGDL54lr@cnJc`iMVQjz6D>xgRK$VmM_Wn-D}edzMPAGfaY`JMLs6ms4o{navz2 zf~|}<0C0n<6x`A6Q?z7c%_wsiEbPG|)5&SUa++iGBVi%khis#QKU6fJa|@RiRb&~N z7XQ1|&cJzgDMRW%w|6NsQQ59WkO$KUrH3naB$;u~UGBcxr8koa`v$Kj!pI!KbxV;Cfr4{U(Yoe#Y=cVZu_>$a*yy#DmZJ z%iEp8JZzG*C-tSq9dByZYXjE?k4BdN0rUI-n1aUAm@SFOVe*8a`nOIyY}cjK{kLKz zT9hvtmUd{Q(N`T=G3O4#mp0b{DFvZa~R?wf@3J zEES$Hr%>Ddjw}#mESUYXmIdl(AV0iMDK~Bal~(|cJ}w_Mf&|@HK1X|EL(&L3c1ht%_-Y{ zfXT{(nVNCXIgdR%2h4?#u7Cmb15(9&dn!vWN-+2myTOLL1K*C(qR=6>NtZ}S72g7f zh%nO|*A$u$2qG{o)f|+7KnDFJ$XsrOey@l`npE|6**lLxm!P3TF+Xg5wd75G`ta0} zDpa%BTE!;@3KH7QyTEFG*BLitZ8fBf*zHyj7iD zq?piuPd41YK3IGF`ldwWst!KMtabQ(vIO10oYM9j3~i8Ndq&){o*3=@nv}{{FUM>95Vn4M<9IJbXRC_kE3Olmve=XvJNj ziXeuvPf4CV4bFbH_wQrep7AthQ5Xt|g~_E_@l|6swIAsQ{_rz)c93tlO~+Hcs#-s| z)XhW_zUhwb$h*VC7Ko2p-4fTY(TBWL(&~KqIP=AG;9^(Kjk7(u$A))9bk+|gAo4|( zRnKmNTq}7BMNGehy*=WOTT`|YMvs!mGyDc^m2UW$rUl?L)F|MrUmhr2Je_xl2?-U7 zBCwbe@}}^xL90#`r2S#g{a^9-#1ld>2{aK3SGwSAnaPh=6J#9{w8tR2$m{gj#0;NA zZC3B57t$?LoX?&G%k`L_5R%UaA@5}*F)PW0k}qrTCCS2>M8g!;GLqc|;jhFsH@e{t zE=+I4ue_U1^Vm;wZ{og2#nYn@_u2W94sgT4NmoXnO%@4GK+y#4Ky|_hiz<2|7;tK= z*!Ep0m3RE6sKZsb=hHef$uI@P4(v&7X3mM#LOG$Qm*6*v(c$a3r=si z@f`w=SC30v=Qk&LrbA_Nj)beD(07i59K$nx*j#>9xc;8;OwB}MMp1$%`*fMAeJW%>Guy> z4We&$t%}?{D!k(#*Vmixr1_#3mOer@u16hve3RV=Bbt6iVBe@TfF#+i?%9q6lBQjG2E}47&_ zBm{p9W|6lSR+L(C%wwO^+w8sZ%{Jdb0i3uW>qO&_$E;%Xi&2yVveO7wwzXaEftnZP{n7BidNGgP8ti* zC9_OsSL+jqHBRjufBTb_`nM8iNlnzh=~H{(N(-n&L`R=L(ux*?PYKuFplv45at}P$ z;cW#?MN0+sq?1{cHdhdiI0yp<#N8FMb|0YmR2VPPrthQCEFB=W?CqsIi zc)S{JW=6;f;4xPK3KjlcM6rQP0MWoY(CO=hqoW~204FQZl?s2s2d(2P%aZFf=Y_;X zq%&u;7RjOHL9uTkx*2k*f)(chk@kHI)i+lMUzta4^6eGykmx4imv=uu^9g`;K9?+H zGf8;lCfg~AflDgXK|Pyc z;f+z}Ik?erYm%s|)`^|>+C?Nyxb?`k!I-#Zfj|2491`}?U|DJ;skpJbL?OX#5MoIo z!Q7eJesc>s4(+ATW#S<2VgV@fc`TMnF;Z{6Q1N=Nv+8HtyOQjk!FFqz_)) zGLA+eP88MTdk8U_u9G;(kOW|>T9}LoxaZ;6y^MexVp&qG?YD|#(qrJtWN2U%+CPl9 z=Y5i@G$C{x#uatDj*80P_6`$)&%mDG-aToH2L;ej?N%oCh`_btd_69^oQV)1py81@ zw5Ytu?y250dw3WznO-mfYe#roYh?nYWhlb$XSx_I)9QL&75%oR^DS&yzi2X)ZZ zV|fi@ZK<4D{%WP(ao4HAoVba_5?EfKY=4sWb%bq^0UNc0m6rTO*vmF8GSp58rrQM` zKAAs1mT#h-oVsb+7d{*UsgIW@xZ)DqpzwD|J>3wP)*!@{4AVUf;yiTtR04C7&v~0H z;xh+J8V=DyYK!*Et^Trk{m`mS`H6cW?EZf1dHD9<0g|L`MS(7EoZqRZnlFjZ@;q5C zl7`42L4tf>S$U977a;fwq|4FT^b9PHgPb>-#rU3umEAhF1IrEJ-{!B9aDX}(3F>j$m4jD9CTh{Q1W9AvY5Wh`v~JFElso zM1rYwIWj;dg7a3`a~kkPdhF#_$ZsE49|e~=Y_Ha9zHm8vPU~F5{QY^92iW&>lT`1T zeFw69+16j)3G-?>@ALZKQ|5;%aq7ZS3Iq@t;?PseU8IvIdk9j{&y;6kLAb=laInZA z^BDx=^sg*nMDJC0<2(3Pj|4YAn`WA(Dc#|SdZW+vrMa|ubF)sf-dqSx;;VmjWpn(= zCL<_wTE=r(+_V0?A`5Vugw5stU4Pl}syUuT;^tNRGJfa@^3`WWHITdz9wh6_qt@Nk z_r&9ACC|2~S^x@O2w8plnW;p5okA-SjDnLFqBdo&o|kZoU*+k-8B7y@hN6Xd@_)~U z+Vj9)>l5CslnAfll(neCM59Rh|>Q$h|>QTP}6^Z z#{WfX{9olK(FN>5cmHQ`l1NJVKZ%n<ND|1!9c3O-P?o`%_Cexp{-%>NK4(Izw1 zW-ND~+)@{Pwk4r-ZgA;2W<$+;_swdB^CUeUFa;UkwXOGzGPiAg-bRTF<|FjAJ?qdO z$(Awi`?!8zW4_aHo?UFc^2%<1(&mLukDI|?KU%rQ-1Ewd8v4iAt|Y%b&hTBxv)xv~ zcgjJ)LYFhX$8Wlf(RWdMP%&WQwq9(Eq~`WUvG3kQ;J2H{0X&u=!+u9L=~fN(Lry1D zKG3NL4{2!cURxUdf|#K=7Pi>Ohu-H*YFp0}Y&$L(q|kBWh1Bt-_M)g(FX1KBi`CM-lPA*j%0`HHuy$nk#;eMM_M`ptmp3 zNUGO{2@m3UJo;z?rP#y>w0En>cjM4CQ{?~e|v2sh%HSh=;&u+F@mK*G6>Q+7Tjf1#Xtas)X@ru`q#jOz2mdkt<#9JUwzSUDKv0S(z_j-IMMf=>h+dM}?KvF+;Ey=)a@m){AGshO7KtTxzmb&ous+I2;oX4Z98%mENQ@_2b zw#-B@l7a#l06OtEWVEiPrqpIx6Q7KUlA?&9Xk4oPI8*bX4dbW<3-KpAx#IbQJ9&@E z;Jw0(F7RV;*5R05k=mD`-Q0($1Zr6k>oMBuw61vl)W@X3Pj{xj{HD$E%C|)bB{4ia z7+$-o;cvhcGX|$Q4=YilNjUwZh4CeA+IhLJXU7W`UL!Qrji{8PrTRndA1^M*{rfIn zjTvivLi2bOMrdGJ)I-~bCI3RZlSlskTJfU%`@K@2_ix^U`sl<2bN1sYp88ne*fQ+V zY$^&Il?i8_K^4T1LOICP8F00kQHF%W6keza$~p|mSprT)TY6KCeuIu_$b)YK(;T=% zMs8hiuFvO#m89@Xz88A@<7W$Ig+ zFw8Cy#>~>80);3>V0fh@w3vwS7waA{ovOY^ zplWgd>hxjgS&eLIt6!tERmOvbYUar9YEh{m=lL7eHsuer1wMko|9u_v|GVoL?Q`Kc z2>Jr}FY~dfjyReO`M(j4|7*SZPvQ7K)*JMNR`=QeAso+D(|jjmtImbvt=aqM>&^dU zKFSVrT}WMNvaQdyHSarLZ(OkY9%z*|=Sq*qVlCvE?YUx%N!(}XbnO+4~yE(~j zK8*YR(Ss(I_-X{N@Q=Q|@9LYv3>r1w_KI+`>Ff0g$_Ur)xAPS*A9PgzR(!w6BB6Ip znk#B=; zX|US(UCEBJfN1tso1F3OZAG4{?BhH?HkyDF*Nbqs^}l7QdB$0^H1VfN4Q3Q#z7>hz zPG|ExA=|<_2OW}Sgl0-Y6g-`T&6RYch`IAB?^j`5C+~I&4cU!e(TJ-PMQFu{#61WD zF$|OfDLrJQr85lDFSaobdaEyw{y>6>tA8Lt=!oP|n$?y=#%LGgATe52qI^I}sA{jT z+20TGE4OL?#{25ynNM$HH25Fb$w=_XVVuPBf z^IDhhQhryq-l(*$s%~m-rJQ=@%5!H*Hvbvo3dYJ7%44Ac#yF><3HFC8MdERFA;n%x zwFi7&L?VcWrc@rp{8SS;&bOElLB+sg+lHi#MSn_#*hJCEAo!cfuWyNvh#@RCB^J{R zXp(KGxEBdX9?b7QUA|lOv*|LaaZ&PeZA<5aPorGRALU!Xdc*Qf(3Mr8`aYqgPfdB& z)o*49i>>kn1NxTTEjezdlFbY^+#}}rBdZmg*d*4rAk?O)3Dyf?-vAm1?#su^(vIb! zTAvMzzbJ1v6fzkzLP$hV06xne+LzP z-EFDbRvmv=?WqfSs$2i8d!M5;|NH)}f$Hw}b<@&HpYPn$ZvE75(eNEAF#*bw9-U#H zh6u3c9Um>^G$_+`HWYxQeJkxL4|nBXNE;ZO0ih1tYBoKp;%s_Z@)egkA<248-Vjb+sK_{jbI!F*aS zf%-D)e`D`Izv2Aj{%v#$V=ztcF?vsk-g}hbJ9-Jp=q(r_N`mMm+DH&RBYK1&h;H-} zi6MjtGFpfTLnJ{Yvt7Tv)?U}W*M7Jk+z;+Q;XKzm-=B4Uj`#6;jmmO9Ci&uB8!KGE z+O;anwzuO16a=ay$92+=N`=q|jrSd?mt-+e#kt$oLpZwM zlz?y$(xp>tQvMp94qMbu5yMduT?j&axK<0eeSs7LF&qC{UD!Hep;dhV8>U0gE1L2PQbS)FOW zeteW6lGmeF2l}NWo|Yuw=jL${MW~|WIgAENsdz)%KfaC01l(j)aaYrbi)WZ>1|xhx zoKFsEYI zLAK%q%!P}pV-tRRp49+NU!QCj`m*`HIGk;_Gp>}`n+lV5UGXsPSdwgJ`^q-s42Y*Y z5y;mPPNd<*$9;Km+*PNprG|+_Nt#l}BK67L+v?$ec}zk4xAZo7GRi5Ane;!vPSa}39ciq&I@gYO#7cyaM; zzPBE>bL1#R(M!E@R;60}>N^p+QgBOb>m;5;?eD9o&6BzJC1FBwis~X;A^@@xR?vls zMF5x)0<)&Z#C$1oQwm3>!u-RN4qB#x-}yNR&lAGP>m;v?>u6A<`S;OCy^DDkoJ`k> z_Gi`6!!wG#2>D=H?`e8eRcK}>7QRp(P_|M$b8h^;!O@;2@rA%v#?7~poh@#Sw{z{4 z9AxcPr~i1qa$C7=3Q_*ENb~MxdvqpNgXIx{NmqwOTAGnwI2NU~X&|ysiDjxyouS+; ztEiB3+kc@$!(!YlSA=<28fgAt6sH4aw%WkOItApGjq)k*K9iDo(uo!yFuRpm`AxF$ z!*bG5WJrTQhns3}Ml`lL9Ios3xU=yNHOr&rwZ;)o;m3~xH4ak)-;I5zRbPHKk8HdD zHsk@r!!6~02O+U|fSL3&<`xu)TQ6r{Vu$qQFzXEe#U+R_jR=l|j^6(B){N2{K?bii zWV*&~T+KQ|FrqE5KWOs18cXhUDBaJI(fTH;&9(4;6#e!kZ;lU`XF-ilZPmQ-$W-z6 zc9M5{+57XoH`QFbe_d{qP7#y$t6y(JJ{(N0M3AcTz4799t`>zQ&9}H@JVv8UMDt@`)L3hRf)qTd_qFXu6 zZ`xoUSX)CS7q%xJ;R(U*)xqyMqG{c|Vb?-pQpA1oqL++fzH)dUZ%6B=2o;4#e%p>v z?zoj1F2}zeb3Pv*CHNrK-t*dGfZ}+J-WU@Xj>bs&o{2JWqQVClku(EzyYiEU3vk6n z?8Ybstlw%4FF-Ww00BRcWukGO-q#+4(up?#MFDm*%+eh;&$K-5>IE6)OaH=a%6CD#%_13(joxD1YdSj#=(KUS8Q@M+bDz03>^oR7 zE*31{n6lQy=qqN#Pc_bXqYO79MRA3DR*&CW`W9K2~N`ri|K^Tpp++xLA~pl zOLXrdqaON%H~HpmfS8+x|L)!+jf5kfOtcq5yknvqSGQ{@4q=gcG{ZUp?aIqR~13-TxgO|JxJ(F|BOeUv~UzT6kV- zrAYC9;+VEXfPO<*NDD zjj!ISOZ%GQtvzmu53f9_OAuGi8(}A8+7PmzLO@glIfaOqN6&y$omq{-GnwbDgU}_keMO9EWi*uzup>!NvV1-z)0szd0 zSM;NXgD#o?d&NLvXp{;X{K&6X3k8mIlFbi|ZduPN8OI0QB|Lpti9Jn|S772`c>Y{3 zpU@ElDyptLx>{-~QD>az!c~7TZ~xFo+-9lj&xF_8;Cg?j7p8Kt`bomXq_}x2kXVz5 zcoRyDbg>o-7NdyF4LsYyLxLkfvRF`xJP3N6K7X&_-Pw!5w2P~c#sjYxDr=Sd+%LnM zpC38B)N8(X9Ok?@)5xiJO*&6$w!{5zz93?tma-0#wBm#Mzf{$I0sGTrulo|E-mIW| z_sox<*1u_+$^CL6j*&xfeg-G4*vOq8CwRU2GVrB%cZ>9=7Ndk0BDyk5UAT~)7F%k0 zi&F6`weDB1I~3*qV}^EZf%@Bj+HpLuRhqRVaumI!UPlzac54Pi zeR>`9=XLCxm-qg(h23~9qTZ2O++h+2%lOoh^`|524U9krJiO7Ff4{T9pX*;!XUV6| zvTvR97h#$B&dM8I)%Uv$4?CaNcTJ(YYX5XK@pQKoGuPkfF8S0|q2Arq-QDx48|m8J zp5EQ3-ZOlor`aPP z@=1j0*M4XTv4)ZO58WS7f1Am)h(Tk3HKP-@+;uCy)igE2>$DzmV*t%NX#VEH?Cs`W zCWtRT73>+5e$mFELDUYm5t1EJa2`^MvZ11flzWEcOHdl;Lki1-dK$xKe+ETitZJ}f zMQN1Di(yR-l*QDLfyRinbWZ;*$sume^zWQP@9gd1S&Yj(b&5C}JEF5P zVz)B?%M5|#`{1Ve!R;?%5FZvBOuE_o;TNnU@cRcQbjNMYg;1A;u;_(|(uI4y3sEZz zF@G0g-_Er0E+)Dxipwn~mo7f!OHE%{%!)2{I9q(wyJ)5MG2eXABKl(ye39Od^>im| zcW2gXe?{ZeT`TKThwrFWKEWV%I-Sbs_2Ma=`A$pjQlwY~cL347yH zdqDAzu}^VNW{9QB1yaieyrwzQPjg-@&z8QfTUka$-}xF9J*2U+{I{)->bvqM>fIXO z+=|Pp#-EjCjn$=wRTcl${eYKK@aetiPYU|e2hpERc|OB6KM(e({mu9cXnZv<^O?56 zWS5T&4SWUe`+TG^8_u>$e`!ss{*wb4s+TsqLpQ!QOmY0%aF*FL zExWFMX#*a!`PAd{b*(MSg-v+z8v5UcP2bkxwaqW*n^KqMt=?^U^jY1sAj8YH0E%Bc zSHGCu{AjqZu*3{J< zoxUA>7FTcv+jHly`7vLg^L{Pr6MP)QR`BmD;nHrg)~*K6ZgtFVp~dd={g&F*-NvlN z`b*zfK7G#8`rH!p4b`2ebZIMPRkh>aH;T)*HpJfW<(Gq6dn09glYM(rt9$SM?U62h zpVj(4ck}y)nD2{a-nve9zq_fH#r`wGuK^~#&pbbN|? zw|{(@=hfbj%JOh~)L1=iBoH>%QgU!n%=z;sPG^_Cr5JY~(#Itc5b)RY_+W*z?b z^rx}&R~7yv;OCz;jX&M`f8OjrY+0r>X#Mh=W~mGOrOW@zq5sz%q#CSs#F%d;x`&KlesxuV7bwsCa4rc!)4_$kj2cOf2?A)WtuPJ(wE3( z{l%r;2)jbA@+%rs#~ zGx@ZWc^!{D(o?5Jot;s)ofGnVTYAkLkBwfZFuB7toqqa#XmIIIZdm-`omfZ(KI!}Z zvFiKc%gAgE8TRm?^^r_|qq61g+ph-{H@wO?BX(2zpT2L*?0t1>7uFE8z5JID(pEQd zk3+lc503JRC&vDzOMBGT&+nhdo_>xAU3v%J_R11DS>Jfuz6LTl=-*S4BDEZW{=C(l z;?%%vp9z~`x+dSff2ohurjZ*Slorm>W41Lt&^-doHR}Dg5zct^D^v(GzE zZq7*G>IP2h%s{xsSSZ`TO7zkbXJ*4+vOg>}hF}J=Mm!Zg%x};yH>OP`DmGf)$l5z& zhF+JMT{Tx+@US))rCL)A#9o&)P0DRNo3)Vh9>!f`cOABTqY=LR;~hVT-g|1f!6%Pa zOC$d8-``5CQbi?|93Cal-*xo7FJfGN3(1i0;8yCXROMZ&_RA@` z#bw7a9pBLA95QYA`x)v%{-Qkw*!Y$yQsr;qGJzE=6xDl`OPs}|>Elk`an~fn-AQ$cw z>5*rceCk=K960_Z0mFW}Rd~0$^9vzqRCW8QVp!zP!`!|O-Y-H)3er!FWo`?0(lCp z?~7m(hFZRJq2qEP8oc^^Y|%$8Z5Wxk5g9sZoA((oYIn%AHr>nsv%EQ*8Bx0G{q+;4 zpE<#H{fTTd<6_Fey-Qb85WnVbUFkJ?tNfWSbS*`!tb-`=#F?URX}>(ZWoVw$HR7|~ z8ae*e?4SH5Q}|EZ&Rd(m-HR+&`l5bJdw)OKGxvNzgeOp~ZFJs0Ue)*&A9^cnukLeb zv@LZ3^OLxsspUBy?j6s6#@e9+$v2En^yA-7e5|v)_8-RU`K^6`cKX!%T2n46jYSotLeY6&=tPFsfN1m0;6slcnGq6ZLgQJ@-x1_xok6g zwXyESZGCX@QdY8Z(}?-w$X7S!wR~IJ;*PvShc-W8OeT!IS{}W~Ef!`|z3%j3HlSkJ zL+VQB>rCRECyg0fR|F!JEk2kRlu3UPjT}|NtUvO-3;rTmAu)-ucwf*)9QIP0kGSsb zWED7@xM|vRI_VW-{ba>vYoYOUyebDC=#U_$`m}KJPP}|TjhW*Ir!=#GU+~k%r}RG^%_tNoqDgI8IhAsm?O3%cfeX z?Xu2YKbtBw+vo3Sp4pE0*|l}e-#mI$e~Z@N7W}{HqXytQa0KZ5f1s8vl-Ib4pvy*O zmUJF(Dj&Lt?lmnjZhkhB&ME)DpcefRVIo2Je?zUb!%Fjbh5rxKy1v@O)ml4KVfU=Az5T_<=dR{uE^pc!J{9_o^p*0oBql+b zv`8!6ijBH`v5NVru2t`N#O{HmZtlJ&kFs%#8kcDd#3wVmT*s_t6zk*2xn~cPE)TLcXoO<@tRLX17$y)hKGtb=k}c%=()9b8b{7ThVd@0fNL`28tVzk zHw-c350D_0EZWO)_-j`nvpUa=GS@0+Kz#+*-YI|1(9cpo?Fq?XQLv+pM{Z{bRpstB z4P~*uF<+ceKFiS4_lEmY^d;vt^i60y&GBQ(=hB5D_Dq{{)4A8|BF%lIqKT=hXN&7Y zS$scLP!IZctPyfKKF`vmCZaapsZZnrs%=C_oWG&jOdMGVjeiIo)N%^-(1g8!A`BL|^KkpQQ)4JTjyVsqbw%<#Zot z!QyFq&bku(QTmAo{eyzX?&X`Z>#=(1DB_sLficVX4!J$b5J_v%`#aX?Ty|Gm?i_y{ zZKkg2q9;PZABW1F=o};dnkoz^qTRU;v=w|b6_D4vd0Rhf6BZN=bdf7zu;YgeU$9!j z4Hvr=*3{D9NI9EH@QlI>Qn+65Q$7{A1;;<84U-=jsPZWw13DHr_^`}KK(pu2wKFc6PN94But~n`GxX$ zRQtIMJ|jG87;B=qg`-ox2+n2W-RHlh|Af`y7{&I2$k0|hs=BJ1h07Hzk1h zqoyqnIO*i2gK5B8!VrI*QDwdH42>5$EI(&+^aLpoyWWH3AI788-0QLaI~%-i`QJ&(&!n_K7I+8MdfPSe=zDo`Jah^j}2aItd&+dPp?vJ!8Qf{hIm zaL4MyYUB9;AgzXd)BMu5UfvD;*0p}}qjd2(_^q&sm zu8OW6qs}$0(E+Fnd4qS{V@zXip)w^(=Jumy4D6C?*5zlfOa)%(%WyoS#>r~vUm8_N zQGK46?bljf%6NE7?qhIPNG+JZLM2JrfbA)?ww(I_<)bzo2a~@%44f}WQQpPFA_?+^ zCmq)=S+(hMYpnC_bctyx$fXBwZZO#|L!r`gh|ucy=~`^H>W#ouzIZHc0OcCTTg$At zK7GD??5bXDWwwWK0^iojMeKTxWk@0lB|S(~SuM{@@2e=MX-MXF*flo3DOAR283*aW z%+@fpn*JbN<6BfKu%=Ng)S0ifpYJj)83CX+9Q>^FOy1S~74qsVxv8gsOLQey@Ze(e zkd3Y)cZ7%7djV*5${_={uoviGl+hJlSgmVD~~41*cu zD1=#ZqbBh*)o(n};xy_R6L8nLb)k6vwSo zjR-mcv2~Flsy4OR#+x>>0f2z$$2p7su!O!|XtUICEE#F+%DXR4CvP#3YJpDR{p_0P zPSu^K=MY3r5RFuy=R8!H0(s2pG(j-VaNi6euDSwR`B6D1k3{>hz?GW?S$Ov_-cGg# z6^L?QNTzI$1mrF>IJ&TT)Njgus*f{?4W$;R6fsYIRf-*!Xxuf7zF1+)+4A9p_yNuuVljVH2W(ioR`K4)9LG2CsM zdo!83OaAJfC*?8xAgf5!SENfik+;#c$c}JkG9Do*zb+4CdoIM!4w<`VH~-w;a1(5# zGFl?dRK$D%7Cy%g7T2m}UA;y?d?t>`vI7o0Qs?Ng+(#_^hsno2f4F~Ojf641_>c1z zldxbNvD<#w{L5WWwpH5ptbR$|6*I7#xCl2?W*GRu$tqa5un6=Db!Yjz=_tUtDDTC@ z5PxBWz_?OIRFBslveiPskG{~!|I_`*abultT18EM`S2lMk7&usc*VyXcdd4e~(N)c=3!{zfiV?~niIT=^YV$n>1L{&=juM>?4(~SZ-s1G_bd~@i! z=u@3m)m_V^*tv_yvmTKzmYpS9v%Gfg@$E4Lc-XSd9$%r(t0nkC;`vg+M2EVr7KYK~ zje~$qZ?dG33_Pr35SYWhrA(x7cV6Y8#Z)}+a0%Rdu`bEm0ZNj!sK5eg4}p;+sRry_l!G`VPuh(F z+ru+-jDZ_)K5nG@3}XlkQ84(~1B{OI!M5GxZwK+zc-lk%dA!xTP2)xHJ8#SB&&cp> zax{2N^Ogtwd#W4?Eek2dF;rpF@*^0EP&XgQ$&Wm{&YBSBJ77afm!uCI0+3>U)#<(y67&frV>f;fA*sL~n-1KT8%j2-K zYl?Cd$UqqElRWUH4r0eH`kNh{^+_hDJ~&s$Sn07elndyJ!u3(W9U{rE?2|9JNh8k3 z6UEQ44S%f|#$jvg7>i|a4HifU-nf$qRRuC$?4QTn@}8!#8Df4NMT*IQU&cYQkXJY=w9Ejsy;Hy$>DYzD+w#%G{6e4{X1~ zg3X?20!`o$cPU6$oUjp!zta#A*`zQ21UV9sQB9{bIgaALkn+hHq*~N!!sSLx=Ftye z(1k@zgs+m|$*1u9zhR$MIB{63L7lAfqucwf5%0gC(28QNu~-&73?zN@H(rU<;Ze3wC9Z@KgMmY;uKHvJa=P{|TJqG|hbk&SRokQuh#D zh!XTwuY3mdB{R+v;7O4MO~Qhl+mHGlMZehrzrrIe2jR_;1#c7?Z&4rdun_3?0q9c# z@@rw)7RIJ$E#`y0qa+<2lr8Uo%xGn(Y4T*bjJqUyNdR;U z2ZzqG`gZ2KKcSVd&j{mu!eDcc6Z<5hQ(v;_$sUElz7llxE8}MzBKHYWvIu!X5qS7f z*l50B8x2$91j<$>Jf28UT4X){33n$HUfgd=-?fQE6~PpMm37E!F6P=(^GZE%L!E_` zT9x#3Px0Lk&FE%se3?mu;45G#?s3e@#03CN3LJ_IVrGKxteZI+%Lpal;-N@Y(` z#;;2&46CGy?zR(zI+=W}u(VdPwTXVT7b58QvD~tgnETW(@Z(O@ue7K1SAl;fV1Iq@ zS)l^kQQ&qgB8LE)HLf5KEla9FOkMi(*5%H)a;WeVt{r3Evy4j&&jio7!)6$_F6ySp zjM*4y1`(QsXMp~AcEkd{YFYtvt&q!&$aQph99pQwP^l-WErqH4A`3Grs=Us?ymu|> zza{!p9Yi0wzTc^F>mDS_(6&P&r+Wg-_O&>Wvn0+~(;EQyT0)I;m@qN%G!XnZbzs?; z#v}m4vS^KrYAPzY#=Vkp)30%h8?vN}LKA?jH=5c00C`)}xGde3=W&3p_UtZPE`ZhV z@UU@sGL=U>IDzNLw%tEL+7((!ccMCUYaU#E%~n%dYXf~-{yOr$wJ!Q~L=R7B4A;Nj0UTO^nRv*GKRZVFyI$M%}CR%6ukFd%$VFE{~FaeapqE z!S}G$YzVp&&tT6AY`|r`B7#|{I&vZ?peHfY@p^U;xxhI+>#aNpTc0)eD`ia%n0CMY z+(?mOv~)tpnJG5G^sLd~k7oe9Ro@dOF{(BhlME zqo3aa3=+jMh{N)^5SfU+)W?wJ6qv>)!?t)K_u>mTo(6aC{_n>?J5=y8)}IBN{1=+U zInywdCb#+{t^rrVL~Q~vqWYR@sye?C_ZbF=UlE%)nle58d9qLMhev^)BUCcr!3UAs zMw-r)l)1>JD`};nHyGSK=r6U6Gm?byRke?*xHf+x=3|=~b-`x8;0hE`sU|=UE~~2v zT<&Tae2+nu6_|Gf+a^MRp)`;0JZEGY(f_0Pc|iEGJTQZR+#@mKljYGw*sV&)=(-0|1Gg)_+w#Y6b+{>q6YU^+;OVxNnp)K zY5IzyHxZCiB4Qc~JQ;%yV~oBsOzbUHKmpw`+*=q%uVdgi!K|GE zH0d38r2Kb4ffh+XmT(^1SjIITa39uhmjG8=_FX$0)~tX2aSB#p3+2YlN32cBS3;I! zHI)kIYMJRB=iwUYL>^`2ye!0|K^oCChZUYilfz(!^mlpz8BLyNQOc877Z{1Ov&qsS znb;?){o%`nSNXs>1mrFS-iD|1m8EN-z^BRW@lj0d7|606+>!7xL{s9$o2&}V$Mii~ zYz5K}APVE1_`X}kndY{M&d&c%GXc2P%_m3sBECVUy_3n273H6lZxw`lT&-6=NzI+C zKZT_IgsEdcO~gO&B*0UYfb6LKKH zKlKAeiLuzmAb=u?fmEF`wr~W_^x|H?z_k)#U07?F3kQ_~JGl$X!8Qus43a~O3CuBO zVCa%!8N7CUgf1n&K7AcmpUnR@)ID!wf<%9pNLPf14co(;Pf$5jQP{~(Sg==PfUG1x z1zc7Brb3p^4^LNthQDa&Ks0{^OtSU`VViGcK+H|q`}R#4q$))z~xh;_%e7E}3Lmq#`Pzvg-) zR*3MWfA9%>;amuf?la^|&sfLb2+cyjBr;sm6mcU63rk+4+`jdkt&u})5i%IeA z$z6D9O<9M!`_Re^684f<_a>KQj(+LSe*(Qm$0S9Sh3q!ggOHnAB(CK({S)H;JOLhZ z#IR1Y3U{s8jzx03{Jw#P`74EKkr;mvkVi!Lz&}Js77T;qf0@Pf7bpZ9L~2gM8UT-_D(t(9Hlo{pIRsQ()W#4f^jLL6e5 za;55pimJf0_;p_M7z)sbwSwO)=$eX^*rVzvH?pHr&jic_Oy#H^!Ldprsq~nW*67?Z zlSKX`Q??}_s4AH==-!u~Os=phEAM>0N?^^_^~pTOkqDJICUH~mmzP|RpQK=O(Simz zGCDq)zG-~xK5N3U`BEEI{h_M?yQuiJvj1WV@JZ7Srb)avD9@SSNnEo~h*GhtwdUTG z`;f7_XFJppzMN%19{gY>a9Kp{!#{gLl~0qAJ`q(sVYe%_twi@oljBB5j}za^-ZNpr z08Vu;Kb9uNGU_Znq(RA zjH#3L_Aus4q8&L@eZ_#=SM@{>3=S-%9{1FZiGDp!)ic+1dS(5eHm#zKrIARRjrD)# zCcX4_hI4V!jltV|$(X7(yQTJT@04$ZZ~d$^fAC$=!8Jvs-Qk8iR47wE-!=j1HD&Mx zDwkQ+-X9E_Z*vNeIlucppr2ORIr!tUK%w8ehA-TADHAEh1Q=hqgEMWW@@k-BgYvED z-&<@n{NpoX5m7-uzMozl(! zVmUqT9qMl8_-1wt=G{tmTrOcJ6nf3uWfa;K+rBHD%Qx9o^(jvg?eejaDbN8|=2_hH zttqzX60WGZfLea_AqXM=hSy*2eUl@^{_txa6Yak3_E%Rupl#u1cM)xbl6qk0cJ(LW z_Jh9SLRxae1=OOJaR&{&kNFZnL>g%vmeBD#2X(NeXxy1d_jJaMiH&K5yiI7}J$R!` zrx`k<`CTJu$jC_Z=iGJgZpxT#isr9A$6Ggo`aH)pe|PxWf4aN!fG#F{b*5c2Vk5ie zUPNoOQD5Y?yWQ&3>8CY)XNeV0SMPm)O~>))eJ7pv`K!F?n-@?^d;ZU-8Snn+rDxu& z(Wl$}6Mq)Ij`2tR{IUHY=A{4N7U1n`Z6LdB6paEF)bP9ij|3^MNuLZB;naXwkm8By zWLm}AE`~r-TtdANKR{bW@9oFzL@{YsC{L;$d(qoOnM8s0o1FUG?=B~Pt9M1zf6(Ro zg}*I-?1~Dn)e~Tsi!@MhV@?^>7g1vJ(g}5Am4X;b*yY?><%wf!i_qK}2}-}kYk$1V zt|XhEV#@_`&}dU(4jx|M{(s2c!2h=%jfTScb!?W$n=8h$|9|Uh|MU3S z{81%Gb~3Yx#s5oJlXRJE{W`?PE@)67dv})x&RvR-7RYn?Ccg5 zskciIQE)gx{gN3#y42sZjby4{>5m07UNY-wT1!LtWp0di6f60Ti>szl*b}pZRyh6N z!3>9H>2sdvy)qb*8DK^;9J>GB|5VTtud5^BQ3ucL3KN==tLaphe=mI9!_`2-JY#75 zvDB@1J)J)?856&Th#{Z;4Bs8MeYN>fB9;H_OB(fQ%E5|yxK)=}Cds#?&-yi!-}s;z zzm_YJ>J(v}>GD#jX$u0?KFLtdR^RujxM{-A`s}T00|oy%gw@VxEs4_$`X1D`8Iq+i z%$op{-|zeZmt<729YjpYJ~q30`Oy$U{j1E#>IJN0{;Vr9j5A=jI+tC$!7?|HsWqt5 zOt53A7067#qE&%VU!WOB3vFy#rz7?KcD9~ilO;rxd3W^@zS_LOG#oFR!p!;DRodcN zj7VP-kxNq!6;>BZ3qslaK4cD8L%)jbE2bbj5IpR;W3sx9lZjQr1*T(s;_mhQYjsIj zmrda&>pGDx&W{Y1JZ(zI0Mi?`5$h2KR6M^8ql)YR11OHN3kr;;JijMpK=CVKQ6cLz zFpMF0{;Fb5U+UPZpasOe_ZyaR!pci4wGvH84t`!QD^18WoyN)G!L=F* zQ(TA=V0vmFYfD0xmy6JyRt8JzFC!US{`ZqSjM63~2j|fB>+{1UcSh;hQJQ#KEeE}y zvQ;W;v7+n$RO2}MbWYdP8=UWBXnJK6V5}@XK$WXqn@r$UoNrUY*0{oDLz*PCkU5{+ z9uE`r0b0IGVXJ2&b4Qk;BKa#ga~>ioc*#0_kA3f(j@W#OpyA;d>(PJo-WW|rj@%VR zK{*Z9(=M5y7dU@CeieZ`dGIyQB$4#(GE*LO?5egKF?B|yf_vK-^`l^o@d^~@#$P+M zd}sTiaxBs9qLlqYkJc?;eomi^rV-fHiDS|kHtfJ$2N7Y8{G{)}@~%W(0Kz@t?>VDK4Qd zYp;odf_5O<#{Z8DvR zo9vZ~lx)@?*vja|@+_W7EB!h3p>%<46esSSC=(?%5fyQkceO6%rR!F$@2t=bq2yG*J|fST9pahx$R8K8ka4#R?WmT6Zs05q2`JR!U& z3eFqHd9pLglWzlZp|R#)jYw9QiW>?9fC^duJW=x+c+N=y@^7N)ga$$J#`qx~0P{Eq zpOYPU0xFnLxuzI+g77#eWP;ZOTl+c&WsTi0o#KrY%Yxxin?rmPCvmzuDDVyZkk)c+ zj?!Kv!i7Z0#MD9}i}EwP$s63gJIMkSl8`D>eQxIw#8oX56rBy2e~C1r+-KS5KfY1l zOOC5FMcE&cE4U}{$y(26(xnaK^LR|)^8Y61?-cmdKgheLh%cXJn+0&~lg3mYHFpS6 z-&SyYIsgMFD>J>J`W#E+DN3Xd3|^InoH=u`@R#L`ENvHM#-2u!VSxDua|bc=d{D># zbP>FluW;RapQ4s}*m}uOux&a5uO9Jiw%-n%PD+nuDL8Z(Wf0<0xi=e}R_HG&V0^jfx6^qI}e11up| zO3G39?i6JgijN_+@40qA>5@lZVX#sSk=em6(1W5sWHB;d?E|Eoal;JLYZr6eKJixN5ewC z#EbOAAwA~e7(>|gE1v$!*7p~b8S~L+&%!1t%<1u+7$+m=z|XDsuymy=V;YavXt-Mk znwJ-Wfw|uhfp~ZJ0CGHsbEZ(xoa=bFfY`q?2sDVI&r_i?l>bI2&2KY-x0JNbkcINQ zk{i!^#0g2!U)kY1o}_zOP<`bcHi^G?fa3s9C#S7IKK@BDx?hg;GDF`+Q_E=8AC>1IiR~Qw z?ZJ@+K*$Y4PujG6I(fuByx{%jpdhH1;wUz+uE&*kk8_NPVI6S8d59;Qm_F)B`!IY8 zJRS58qCQy;sV7Up@4ZPWZu19bZb-q-ROmh+-5h?r2$W>U0pRys`CM^RT}DI?)iB>M zy3K*?$6vw?wMf5}X%;xNoAN$xwdsjRZ1Bw&WYBIh$MFeQWE|Er2GMWFJ}~*{s!pQS z>T`XYCAh*jc%u8+7oDNqE+|CT8L0Zh`C(1?GZ$+rQOMy33{Fm_SkoC)-P8rY{ErB# zPSfEYJv8RGF#~gl$18XZC;bDRpDj*ng@{tX3NQ4Yl@x%eG?%+55M}42nS`ccj$`nh z7h82;#{m#$x&83{&*vA`@t?xGafO;7r9WfT(zLb8SH&WB7N zg+MJq7tq7ko6+eNn+Oi}LO?x59uh=>sK@GF+>Hj1;HN~GoHEKv)@&ZFgTTRdo9u7c zKzv_^J!-W%#nbgEqZlc4`*AQW6k3Ex>l+Lo(?zimVY{e^ykDrKJK||paUv9mmlY#P z3Fz<$Ng&00UNyF6g0Q79AOIi@JVS*&B(U6>T@1nnPRzgw594TV3EzL8kK!iM;wX^k zMkppC?GnzuGK?b$Bk^Qbg#85CGEXl-ZDB)`=-Y;&*K4EmBhm_LFY1&*G5||vTU-nt zB(T7Q$d6(A0B2D~d1Da=IGBt$iUkKL%7ZylSl&P5o<~8L0JJ@8;0+8yLslp62y(7u zQwM_TD*>H}unX4dtYfP+rhI`T)hP_(KcP8uLPfGdr6`Ry9l>#mOao*F z`^zGCaWDfGU=8__`$C9HZCGNP(w(~q;nCOt3|z!MNu&uBKo*!l>o8&M&M46M1t#kP zVWVqy87J@zfYioC@ISz%i=yDV2(i9cgL%T>Jq~VYN)Av#>=Qy6uLA$pBFFKx7uHfl zfeQ%8#)Oes?*JH4vCg-Fwz+N+Nh+BNu?%My*IGI`^Rxeh`)Vm-g^Rfsr@8V>I@ib3 ztefadFt|WG2#M9ZWckoI>|vcaDhRL9rvs)vRGr4$amC4`Dj=6IbWF04Q#4$J0{eo8 zP|>tIqO{$HHk)|591oyqK5~IfOHzrOjo{G2GM*9PNoXA!8i@vS=8_`Nf7n)Ft7s$;~&NzDzyl;@z4}Sg#SdMFE$H=b7FlKgMr`6SwKVryr^pnEVjZrQ>7Nqec@*nQn z5uj*Sps3Qfh;~M-E;9e;Vo{QaeIroQTld131K-6LcYiEq;7UR;mDon0Qa;f8#$7i# zs|MPpkka(rRDhQxTm-%{2&a`E5K8T4t5zpy$y|>a%b6}1>q;y#sH^e^m4Z;`x_?lZ zdb|OCMX?P$t2W-X4HVG;EY+2r)iE3b!ZGyqD3}BuRNMs3LtC21Uc3Sj@?H#*&ef1D zUt;p1rz46TUoIjBSr9CkA|e_o$OZy}KtU3Sh;|Ax7mJwE@f$sP5+_liAQ^Y9Iwifc z;v;9_9-y*A?&9qTcCsv?U@hw7Rls(y>3k`?dqN*3QNQou@9dz)1E zcQU~XtKE|Jb zgPRM{?x&?{*A?WMBJgX?kQ<7*(C3%`w8;KJLILz-W!gY0C9MTbBZmWi@Q#sCsAp1k zWqnvbm|V{7^pZ&ucG46yE{ll5fT93)QW(a6maR&^o?R>|CptD5Bo`P}1GR|-%ft$r zfreGnD;7A1FJ#659E~=mU0s%L^-JZ+^F}L%)Y^%sX3&?Bzlxf{7Ly=`IXRN~7~x zLFD$JH(+0^eYPJ;Q=$$k@Kn7EoO`{~2v;umsk`q_E|g41r__@k3!%Tr_(n6Mb}i8& zR>Z6M2l)DHpXwL%GHb}C+T;gjxwMnkAif&<2UO+;SvA$Udj$(l-5=H3KTSd(nG`Y+ zRWE#cBY=Fo+hsR`W2m|ormNAq==DCgwJPUJvDzx*H>JPTw4^AIQ!HYQATOlTud3+E$fXu40sJb^H{bHp#l52~Dde z(SkQ^IW(!$pP;K49N@iO-On?u_X2}N(a}p<*6TnObb!LZa_LPySq~9k;=^HV+d)x2 zhq@M;2t6mld~t{+qNxG~vDXC7qNUT7>~rjH`%;fkHoc+_U_2wiJ!TU?_Ix?no$BzycD8Ou+G2^XNUM0h4BS zU2ry~gFw+Ch2NQIZJM3v6zr_2_7)WDc_efC$j84c@(aWNi>EJ-XZnBO-+h=d_s!gM z<~H}{RuVZvXpVA~`;OXWZjB@rHBl&pR1!XOhE#}BDHDm3Mk;jdx9{)wc>Mm`V~@xF z+WUAt@5odER8w(V>|lpnlRE0W6;lA``}llaBEfoSw0Z*n9blC(RAhh@#j+0S-aZ=I z@NUv1cNMa61U=*HPbT38NqK*|0?N3T0v*7!ETQDKi{sZv3~${t&ZEL_y2{yK$dyk5g0> z<7>2OO_?GSqQEdFEwXDaAaLquVAA=ZH{I;gXBiON1c-^dGxo2DWE%`{UeFT*EV6k8 z#zD=NWs7n=#<)U%2nCn(#?iOOuj;(`#u2dP8A#EO9Og??cRXXHznocU11k>d#>P7SZ_&d*X$`zNqra8VtQL~7voU4aHqHVWCb76sN zvoB6+)YodbaG<9?G$wP))wzh(zp#|+8h4oLub8kG-G|vG<2L02>z;|abI;CL^r<_~ z`5XuKc{&dnz+$Fx7aD;cfWysekhH_F39Qi&>*)Cxu-IXt8vv*s_pP5NYJnYH-;3)5 zXgvqOls6z_EcB_Lemmpfk}Ys1Hl)K(GgZZJC+aQvz?B31Kc5-TH$&XR3fid);ycC^ zHi0e){+9QaqCyI8jDRCfoQNhZ9_BFxx?w)R@`vdH<-$+K)q5nD2uR{}jT(0J5>^|r zsjz)qs0jd#(qFc1qqk@HZ+N1JDi8fU1*$|kJk{mT{X(Y#Rz0|2;%Bcurld*aVh{_p zQcLIE<_v|bi+Au33y3Ri$QmX{0t@oau~$?+l;LKZ7%GuM(DuAsq|$~0MFfve&fhN`f*b2RHM zHI@prfWIQAyrgXA@&KrUw|6FMQQc`mRZ!Il7AlBDt*CqXjV&m7OzRuVd$H)Dqhkrj`Xf}ZQR`=Tzr+uNgt-8O=Z-MjSVKf%kCgh-OYyUT&?^#h z;vmL^Ao!jf3Z34VXMK7JjgK5c!+r?s0AMT1!teYs4mX59vf(cRm2xv9);AAr5ENgw z2LwN+{KX6X@KIdhq9+J14938HTy*%c6OaAi(Qa>+yr zhwvNvL1=|HwF6Z_YcBXMd9o#9OAoUbvo{1LJkf%VDJ__OGrJ5Ivfy&t?|aA4&%-f( z1eN(xVSw_XclcB1{Kz{OxeK7sKeu`d42Z>@=`HeP&ZhQ4mk~lNM*7!Apk#zHzih*0 zqv`@eAXpnBQuhj<{Eho==%VoJGGV0MWaE#P>Zh3-qq|w>-4{%C6p#G_E9c5sqDJ%1U7xRk_fNg+%auFw|Kn=kLi%$4{)5W@uk(r?93zXidnj@T#4x+>DMAhq`ygP@^da!gkmv= zh73{Gyyo)f_Y;sTE_6k9nWnprl{OEzq0l3fs{;p*ErM4Z{lJSYkqkpe+$qo8or>{}4HCfP^NO{S!A=Is7S(oFtF@yskT3l!>eAoy15 zG;;r-xKFF3lj)p$@YZ(!(b^8*Rz#Mv%QgPtGwqJ3?vA+q;ny*~ulCO#HkqX--6Q4t zQtpYn#$}9GI-{=#>m2pDu(nw(^^c;jN*03fU_C29XlFBb>;l|EKKT8L^DLWjO7uaHrQJ@M=J| z=e?DNa9i`3mRBbpoqDjq;46FYrl;gG-)FjD_-08SMzOt7%EESo3 zNFr)Zd22M96$+K8zZx_@V*aV;e{r>(jaFx+n$Ob?E;gyNM|M*V&01?{=*#+Y=dtbSuMa-;o&NS8 z+%9|bvF3k#WzWSf=f^9)viEBt&+g3br-uK|{QmaX?(E-RpZ+_`zNxRZbO0I{sf}&+PtGNjyDV{v+PS^5s-%`cSyyk1iM6 zpHt_~LL#tG3s-yRGKiW#3TbZua+I7dqgY3%xN#d@{L0VenNW~{SkOhBDC`g(Bp87O zJq?(y*bFa+`8*t#OfB}k9dvvV;sC5A;J9!8b)WC4GuMA&c_pV_hkO)xbPhHs(n0VpO>|hF&R5PG9 z2LVhqXRp>>{X=3%XjHaUISwfOfZ%LPy~YRR$005TBYKh~ut>^z$e~dvK4}pk*37A1 zOkNQwCD77W3}9B1IG07YcH}Ze4yWw0|6QV>7Oo&=UvChbPim*vSIB=PJ+{aWeK<^K zfp7>%o49_6IL=5}VHF@#3=|H>17LcM1eZ_K7d#b;Zv85c@jcc(+x&6@$ZPpJqr!&gw5hs=^XK5h36oDR6+b*3))L422yhlp zSA3OVpY*l^^l9KY)OL>I`eW$b$1JIy_SxWcoBPxS*)({;;eEBbr0MMK5AeI=r8iVO z;b$fs6nRjt`Nm~UjT|gKo|)%y4OQh}yNGKRq7gT-)L8r$1j~Y)U+_Zfu*ZFZ zRvq>JwSfaXID&sNT#O88nwX4G@w=n6j8`4Utd$0V-M`7=CSFDC>Eck4D6k#l&qAW^ z&OR(>;M#XWn6QyNALK>|5X zkFvpvKf7po#Ca*dPc->+_)Yw+X#vZ}L&MkNW~HmzMLgyALQDYA{jfbfodlY~O+S}u zcJB#O?Cy!+tz7@m_D{rv0Ko}9pImwOA(9`^*&{ehYLM3YXGCR86$by)Ac*oZv%xO$ zm+qKv1HayPXZ?@2G@3gljTR5%ivqb9;WqGm)Zm-0D{Q$|N<6N@H2jDDy{7Xk=rg~D zLF65VZC2uO;?s+AyQHo_T@Ew?G5Bc!@7(46u1&f#u)io8C~%S$`YezpXf~&Tbm!8t z=IWIGjzR^P0#(9<{<#J<YrXBppFJDT^O4-r;8@w&~sBp)m0c$cf|U90Yz@+Uqek zzkg`t$0o3spBGFCaQs_7o=r0Exnu}Se%$i@mox0j&N3eq5=nWlN*ajoxOpzwA99=U zOyi9xujD`SgF6}QATCI%^F8!X^k0-eZ|`i^nV%CSe^GDBPrrV^Q~aKW+#L;wNh%H? ztJ%T#Ean!`+X5>e-#6}i3O=4(9e+k|`QwINDYLUys(7~b-`@}t37nAh6X{L{3I-8C z;_^fpzi*HAJKqCattbjBt5Ey>o_R?IOY##OBnm-`;lK})3(wA>BMi)nb}ALf&`g88 zfQ-VA*V%}w+~i64fqa0#MBk#Dbu-C2>#lkB`JR2>DQ8vl$Zw@TKY4gB0iS;!Z-cbS zmbO_musNq%HJfbnCb?ifwwK;!vv9g#e#!j(Bb)vzvKhu!3u{~4Z~JnGk`Qh&*haP^ z_gzx8u?;1DIgQd<>T3>@h)EPjGjF`y0mRf+P6L23$a_3F9ZT-uc@Y2*&ZN=p|C7W5 z>+OL?bMT#`Fu4DJ4x9X6!cqyazjgHFHfT~8!vJY}21mCk0ub060ANhF&-q4 zkFW^`TziT2B7su?lOU=4jTeyq7Y*t~_9qn?`$(Zi?fq)Y0y~|2vr!n_u%GpC(EPAr zaiwX!2z(SYyaa-G4eJh}z+w&ool>DePW~z4$Ny9Y*Gr~nq5M+B4|-YfZvP zV1<)Ur*quI@QLPfF$g|dW_X2Frgf<@mVz|w88$1v7+OucQdFLgb$OFPd>-zE!Vdn& z#K;zq?EoEtEZ|umsWotr6R0I<*SIqrTP#_VLbfK`9-RZ`rBn=*jT}Cy-Zy8TZBp{p!L+FmfFtA@ zFT$dCgy3x#g*ia}XVoU!#oMs-45)0?u(@^jFkW0dgPMhfij#q&(!hEuC1@4C1BM$R z9A`hE3{F?YR9y@t!DkHMT5NIWRaoXI&E^G}pS%*ioeO2>hg89n@*y$nLx%*N`Vz<< z3GjFp1dah8Yh-jaLwPL*7p%J&Nu*I#{$|%CO!X2?8rv(WEGi5{ADkREw4jFL^5Q3- zeVuuhh-W;1bP?gnm*^Nh5wIhp)b;!d2>>K)=in*)AsyTS@Fj5Dsz-9ye~FxDZ&&Ff z=TYc{Gr_4~D10KMOopOaa=L56FFIcigLB| z6?ojLATO>F7Ul^)IbS5bO8+bPKu6(4WE9w~VpMlEcdHq83oB61iZQDBY5 zA_q|_X%1?aKo;bvVa46-<{$w(RCqp6YRA={nd=ipMNG;F#NrWeJJv5{28>I9q~3IBk&c55#NZ+#uctRLKXAp zL^;$Z19*CuTw2$(chzC=F1UAZU-QAsJwStO9NY)+d=Nk}%77&`77VGw<5wZVfAiGD z`>gSdw%#iha|LGB#LI2SOwXWq>vP#RfCn)GY5749dKuPa2_7ngo`^6S^L;n2kmtJ7 zqw30N%MTv@3KP(iK<)5*+wzhL^Y%&VHkXHX~(sILaPk^o941lf`$(XQaQ$vo8q z`SczOz}=&1?0!#R?yda!dSZ~u62lJvBF`8eu@kaX4o}aR@{5w~$p`wd=7)~w{eiY+ zPr~q%-ubEw1JC=sq^WpZ?#M?0%qk=fKc9&&NS20&kwLtaqL*US1O8BRR|=fucF~pW ziOAib5&BYR%)vj`jR`Aef@Ji{pk)EDun6Q zJ4tp$RR2E3fhrco^RKLA&DiOYF1l4%2`~)6n@Inp@*7412 zXTEz|1s3Wnx?7B*{c2Sh7S(L)1+)U}bU)q$Isyqb(ESu9lLgH_hmVIXdeaQG= z93`Bcm)Ho7i4Z)L@`jxsnB!U+ixmzf!IIhVG(Kv1dZcO)9^42^CBZ@oFa?JKuSuz@ zQBZyVl}J1z0)tAI&NInB%FAs#=j{rMV6PURfo%=Hy_W!3w~mY;K>b}|d<%RkJ~!A5 zgIj&VyDoSFU<6Xko$DYQt>zXv!>TIb3!_mHuCOp1J-?+0!J)=>y}t-EN|S~k#BH2P<97~$O9kG-F4(vaxMkP;z& zPGv0u1H)s=s+h3z8?aD3^k@d-kyc)0dqouhI{OzE!Obn{V}t_mzH%Zsz+35JiWw;{ zJ|XXt{yTfpRHn{5BiAp*t*|3+r$srmtM{kVyIwwo&44nANg0fCTSl$2RXRS;9@F_K zA4phTi)lpikTqXI05nj6YYrBEf*cc8mD{U8O46KLvg=U- z5X}VGbLbAPRCp9nF$k#K7-~KWIG;_C7lJB=^iGcgP_94~voL`+_ls(D&z(4vDykMY z&Vvb6&Zk@o8ZpPiNxYE=A7^ZkmH}+$)-kedhd30Nle*#sByJgu0%f{yURdtC<=kf;s zGE8=WN;^PBEG)he6D;Ij2M!p>SIb3EoK%3)1Ym;YN;o6$3?h%z zjs7ZSS{UFhJDHnK5M{98(%$8lg}%q)paf?|X-uGJN@QZ+boO_k**;oCRo;=S_*RL6 zb(>TrGBw0g_5>oX(D|wFS(pKys)Psan+gVqpFj6Gb>FWo1pp*FA+OX7J;R1aV8Gn0 z7RyFP_72R}wO6?6{pqxh5Z(`O?6D*O?Q{Xqj7L$3qDAIEFrNd4+oe5@`=YvVdup$Va^7GXi}CQf`ye?EY8Lt3 zj4W7(n|{PJIyQIPp$K?@l(%#fsI3QmrB8fi@JoqB`8?g!fZh#{gsiH<^fUHMUG7Mk zz|Ejw?iNs!z$olxtoIe&ivR8cFgi9$ZFz7*OJ*a9!-$;RQ{V!%$T8`SjJIhqIgJc! z*XCEUv~X;ke@5WLIaf;#-HA)PkkVW32-cM3ibVC6r_dBOLSKTzP^%j%wqYJgZV(pD zi3727r6}YBWnF>FbM$Y{Ajl-Z=`8Zz0>w_+0z=H?l}MQ=xIvp|p_=5(nXcB#!}+Ef z8y>Ft*3x;I{w31nlkG{Mi=Lb5JFs2MKhsyf;YIWYy;mP&`x^2APeTgXmOqqS!G?o& zY2K$5nVH!bSW9~PQA^=Wsqa4i$vt+UgN^>t0E8m;pNMW07dvoPax3AMz(0-}oi+iuXM9ymWr2I@XOvKdM=VA7r+rPaFSF$kWl~%lP23K@@ zTS;PHm`}Jl(y(Ekq zlMm82K4&v`LqQiKcKZwqJtwIWN#D8yfL;OMbCus`(lnw@Yb3x=aUUMIFTF^QSs$Ua zTYC>e4lHc1sr`uuRmFerxv_gHGtVG-$72fT{~;ZsKe26y5(DmxzAq7T_B0k+Fg1Lp z_ZvU55v-{#VM3If<*1%hzwz3PBG$KTETr8kvMgr49+f=g`aFj-j^BgeF+>rz@%4QswO}r+r); zdjA+uN;hRph%$R!O9vH=Y<|(q*E!xJcK#<`;}XQkj6-_XtSS}6mXkrA?YF4!45-W* z&JdoLm^caQ?izfiDki;0fyM^W&Y9Tx|5~-v?;;b#iV{FbQ1|COHu!>%=zfq)v%xwz zk8V@|k?kRP!o=#^keYGWO@gyZJ`-?1uAWPPEeDbTvVHG2*@&)z{1CZUtI2}m7GdK{ zA~!0v)DHDZBfTS069dmp&*I6KO}=e+u;C`1M#2`ywbBQ7*80*v+$rp&p5b{VrgmmC^6c?9|5ZYbw|X3&>4wT3mkukO(whRETjbw%kW*~1(f8sPFhnx1ZXoiFFE|$pbK(}- zu2)=7Roty`aQ_N9m{3?&Gl{j#iRXMTO++*?zgdlPxs-Qlhp;2YX8XOYiIOw5=Pbt@ zv3u}T&Y-X{&xJ&;mil67JOT;PEJGTA&OENVM)Uz7a#mGktaiL9-JP%&Cl+Q*l>yFv z0NU5%pwQ<@M2EI_VO27#{5A{x!t3hi^Pw>7nANPrs4Bo@qZ=Ra}x+T&fqPQf#gB!XC*|}_=9iC>3t=q)^5IRA>h1CY|;kw~D%jHd_ z({2pgdM^ede-h-v&9!ZG4pm zWX$Wme(-uF<*X|~@&aKHtj(l^R-%w`{&c1C3lvfOXD_wti{dGbWs4Pcl9HH3#CHxl zr{}{th=_Fm3WkDYmMYvI#iE^ohNdabQ1R1`t;b1}`xYdjEqmCeXa}Y2!aDA^&!P}D z${a>}vZMqMVOXAcH%;-@3?sMjJQC-?%V&Y+=Ws8qc{TD~PRCZeFM% z83DGM%-s-}vZ4aw4-c`KL`gtlHU})3@(yrJF-0I+bQw(UI;YnYP=ScLgOAfA%8V)t z`$v(0SO4lx&4CFtai)B?XPrP46K0x0B)~5bc#cozuGu~n-NWYTcs>G~Hd0Wny&e?V zRp^K%OK7(WZe--jl%A=j)g-VZ?S9kbTAvqqP~uXg41l4d257L)AUfG!e4;j2^!1Ns zvDPx-FwTv3lgV7$o+(+)J*-T_l@DKZ4H&n3`Gc?0k1e7|p8DiA=Zu+rnU57Cbt#?7 zry$E@kc3@J69;@}bX7IV;BZg?`P>q*#(}gP@q&sf9oo{U_V0HUq9;j-K!EU(SPd#UyZ-KpYjl-ywfp?BI~Dl zWA@wEld2}fImYKio^Bd}^osG{Kr9wI8?jWoAU|h1uMQnB#aHeq zMtC&Q#N@5tv=?j6k>jvC{rCwllteXEp&_3~k?2V*QH`jT{nMCeuWKRrfjKCZVlxgR zO<6t=Fi6{LyY-ULMhjRi6;U2!*KZHSQt<>au1Rxz6srK98g?JsIEY`F8lk*u>v(5{ zK)fLcr3b0XjPBq^&rdy$tR~u@&Kx=wDPpq#k#HhFX*>;lRYVM}2Py zRZPAUjzMNK3)V*stZYjcAwMa`&z96`ET8S3OR=ALbiBFByqU21eRrQA6$Z5Ht^E<= z0uZ>&h0YdKTPJ{}sxEH>>>bw5Ig{8z)zt52p_iC&Qra0hr7%by;VN58DLotIY^@_e58?p|-d92s~=q-IL_gNjC& zs*!`FtM@lH&^XFPRX^+ksYc8L@M^c(nXF*7?4YfEeV+zce0B28Jq7cwtE$8A=8=53 zNHndY>CBw7!qNn~Kvpb!!Fq~06D$=$Ld(9V$_zKy(9J{OOBRYFPVbkYM?e0U`q)dt zjujYWC>G}Ou5L$AOh#$e6Jgp$7z={|>1TPZGoqUE_F`Bzs)w-87xdMJz0pF}>7Oq5 zD!NC1a$j)BKAj)@v&uoY6vGTwr76H`>c;AIWa6ANB0mfZ4*&#C6$HA5W1eH6;EeApT`?G?0 z4q6)_Mz!_Qj@v|bc4WFjSh0`k1ul~4-FA6)qssB8?v-N>55Z@ z$)oUfvZ0FVzcB@ips_F6Y!P{yl{^@c0OpJ8A%Sc~cBioIhrE6D_LM%5Zn3>|+iKk^PXL6FF;Zqj zhS=ghR9yrxs2hNERO?iWcp#`$VM92KE7~%wSDNgvx=y@Q8ZElc)(<$=LpX2VH>tYg zX(ZT0k)%TVA|U<*i?Il;<`+Zr%PsC~>D6V&Wu>#zE`cjFD{BWmOq9+x)oj$EE|mqv zlInq#j=GKDay{zj%1OoCI3xLtpUSqKB1dE1 zC%kl19;fNc1JUc`e#PegX>x4MvYO?KRO*+BQ<~3GKWSDj(JLA(>p{X;-N%)Ak$=dv z>On(tzp(ha&?F%@ZSoArS3j`-3TU;flscAla-c(-)*ZZUy}DLR0jwR>o)kbJXqMsw z0ue7wC)rxngU5cvE^0~lDnOdTK7JTOT7HHW$IaDEG+MoETzMB&DmzsAGF&wpU~4uh zJp_2F(cIWwRQ^*y6EgtzBnZk6w5yR3)x{UO%gb}ws0jM`fclH&1lSOv%7X}!*9Tz< zAhnIft88#H*@yC4ZnUVXR||b|LG-Ea)2#I?xjgTy8*5>cglji*Hvylo32L97J60?C z=8Y_b*yL<6XD_)!9vdNNwS@q0%GFzlzcBLykGxW4oqDrD`0~tUMkU(bvvG#>^^5ai zgrwu`4#sB!(cO12Kr~3r-6eHK`;fvdKrUb>4Iluaa@^lSiV5)geawe!5dW%HljwNq zpl{F*VX{$lr^Cg$k9sh;>Qdn<2a71_%M*i2b5zSV6~`7bIG@tvLzBoRD00A7KHyI= z^yrQ+6E|vO24Z8&2V-R+y-8mkaq@kw^u8?}?7!HfG1bK`WQ|>Y%|^NXp02 zC%eK!uq#6=L6Ld@Az{~H#oR;UHI@~;0lT3#(L1D`=LBUvppdd}KMK`H){Ym8| z-vYYmV8W`$oaq{@5Jy(u?l656XA8yH@uH zwG>ZBePdKv-}0KHzMm@(0S6EvDeZz^$}XHaj5|ezUV`dp6In zT@G43M~!|`H~tVu=?T~u)hTf*+B+wd=Uw#Fq6APXy(N^B@`FGA4GQ?P(Sxpe@BQ$y zLn0Ma9Runm?Bl@`pZ@&=tIzxCb~*#qw*@!7hS+i`p8MoK3%HZP@)JVH{7Rj&UK0EzAAnHm}OX|_@$n8EUuJfUD27_y^?$2TS&FMf3rbDJXIm@lzcp0pC zYOcWco^!%oXEx7ksW-~m$-eks#mi@qDJS;M00PRi)fyQciscDV#58`pad<= zlOP4%HReY%WEVl>*qX*2dz|9|;qChfcY+wf{yvut_B;S{Wo!Ekhyz~leJ(tuII-Eg zwcNdSRuUB011jpccQhVSUEr<%>h)epYv6X01?k#$egCz4A3j&Q8`eF=F=@6FpwTY< zTc*Z00&nS8qzyz5%%*@M|E1=b@4woId=YcMxBRksgr*y2@Dy+W#6EtoDz@(3INX|M zIXb8{Nr&EsMJLr{c~BQJc8%MQUj`e`6&~uO%-|{euW20k zGT2v0kK7@w6@$Z0!{py@(<=yaJ5VF`cDZ{buD*jbWXKc%)hq1f zsmM<)Q}p9|0E@U4cR47qV^A7{1I@gff5^>qCGkm^kbxv4wFH7zK?cRTYpE$ zCg(hjk(u8dRErv8$b@^WJM?hRkV4rmPhXsqa zLG$fmM?4!>L9<=87xaJZl+1@A3}Xkqdh|)`wY)`(tJ&^sxhN2>(+|GqDBEMN2N>{r zaPA&$MmU>h#iWT9pU;5JK8}arxPJ`)kki_K*!d5fwH|CegivjxSryYXDku^O{c;9_ zrcrmAH0ejv;@gf7iOo|CaSoU_VCy-W;j%rJ?+E(?-b*8+rMDMnXodzn3O_uAqyx~E z0PzXhXb0^%j|L;i8#aE-6LiguyRIITA^L)C=-Q?q@d@hv=+WF;$hF^iJtHij#N4NC z?LUhE%*?$rG}(;Y3`>G^(BQ4&{zu<;vH#qRaQn3<$#Yf&!PNmPuERdHlI?{4=K0_Z zX9CY~&|(>^e)4y$KTs{$K>^U7Q7Tq#>

yzdUyF6wDVA0VG(5=biH^7Uf|)qP!0( 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 From a3c02363cab2191044d957f6ce6fdc81dd671658 Mon Sep 17 00:00:00 2001 From: Aaron Klinker Date: Sat, 28 Sep 2024 16:24:03 -0500 Subject: [PATCH 04/23] Cleanup --- docs/.vitepress/theme/custom.css | 26 ----------- docs/.vitepress/utils/menus.ts | 2 +- docs/api/entrypoints/unlisted-pages.md | 49 -------------------- docs/api/entrypoints/unlisted-scripts.md | 37 --------------- docs/guide/essentials/content-scripts.md | 4 +- docs/guide/essentials/entrypoints.md | 14 +++--- docs/guide/essentials/frontend-frameworks.md | 19 +++++--- docs/guide/essentials/i18n.md | 11 ++++- docs/guide/essentials/project-structure.md | 45 ++++++++++++++---- docs/guide/get-started/installation.md | 4 +- 10 files changed, 71 insertions(+), 140 deletions(-) delete mode 100644 docs/api/entrypoints/unlisted-pages.md delete mode 100644 docs/api/entrypoints/unlisted-scripts.md diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index 8089da934..6659a0544 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -84,29 +84,3 @@ body { .VPSidebar { user-select: none; } - -/* .VPSidebarItem.level-0.collapsible { - padding-bottom: 0.5rem; -} - -.VPSidebarItem.level-1 { - padding-left: 0.75rem; -} - -.VPSidebar .group + .group { - border-top: none; - padding-top: 0; -} - -.VPSidebarItem .badge { - display: inline-block; - min-width: 1.6em; - padding: 0.3em 0.4em 0.2em; - border-radius: 1rem; - font-size: 0.75em; - line-height: 1; - margin-left: 0.5rem; - text-align: center; - vertical-align: middle; - background-color: var(--vp-c-default-2); -} */ diff --git a/docs/.vitepress/utils/menus.ts b/docs/.vitepress/utils/menus.ts index 63d2b3e1c..8395cabb2 100644 --- a/docs/.vitepress/utils/menus.ts +++ b/docs/.vitepress/utils/menus.ts @@ -68,7 +68,7 @@ export function menuItems(items: SidebarItem[]) { export function menuItem( text: string, - link?: string, + link: string, items?: SidebarItem[], ): SidebarItem { if (items) { diff --git a/docs/api/entrypoints/unlisted-pages.md b/docs/api/entrypoints/unlisted-pages.md deleted file mode 100644 index c9812e991..000000000 --- a/docs/api/entrypoints/unlisted-pages.md +++ /dev/null @@ -1,49 +0,0 @@ -# Unlisted Pages - -HTML pages that are bundled and shipped with the extension, but are not included in the manifest. - -If you plan on using the page in an iframe, don't forget to add the page to [`web_accessible_resources`](https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources). - -### Examples - -- Onboarding -- Dashboard -- FAQ -- Help -- Changelog - -## Filenames - - - -Pages are accessible at `'/.html'`: - -```ts -const url = browser.runtime.getURL('/.html', ''); - -console.log(url); // "chrome-extension:///.html" -``` - -## Definition - -```html - - - - - - Title - - - - - - - - -``` diff --git a/docs/api/entrypoints/unlisted-scripts.md b/docs/api/entrypoints/unlisted-scripts.md deleted file mode 100644 index 89a2da53f..000000000 --- a/docs/api/entrypoints/unlisted-scripts.md +++ /dev/null @@ -1,37 +0,0 @@ -# Unlisted Scripts - -TypeScript files that are bundled and shipped with the extension, but are not included in the manifest. - -You are responsible for loading/running these scripts where needed. If necessary, don't forget to add the script and/or any related stylesheets to [`web_accessible_resources`](https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources). - -## Filenames - - - -## Definition - -```ts -export default defineUnlistedScript(() => { - // Executed when script is loaded -}); -``` - -or - -```ts -export default defineUnlistedScript({ - // Set include/exclude if the script should be removed from some builds - include: undefined | string[], - exclude: undefined | string[], - - // Executed when script is loaded - main() { - // ... - }, -}); -``` diff --git a/docs/guide/essentials/content-scripts.md b/docs/guide/essentials/content-scripts.md index e91097001..ed4662350 100644 --- a/docs/guide/essentials/content-scripts.md +++ b/docs/guide/essentials/content-scripts.md @@ -542,8 +542,8 @@ To use `injectScript`, we need two entrypoints, one content script and one unlis ```html 📂 entrypoints/ - example.content.ts - example-main-world.ts + 📄 example.content.ts + 📄 example-main-world.ts ``` ```ts diff --git a/docs/guide/essentials/entrypoints.md b/docs/guide/essentials/entrypoints.md index 43303aae9..642f75c3f 100644 --- a/docs/guide/essentials/entrypoints.md +++ b/docs/guide/essentials/entrypoints.md @@ -12,11 +12,11 @@ Here's an example set of entrypoints: ```html 📂 entrypoints/ 📂 popup/ - index.html - main.ts - style.css - background.ts - content.ts + 📄 index.html + 📄 main.ts + 📄 style.css + 📄 background.ts + 📄 content.ts ``` [[toc]] @@ -54,14 +54,14 @@ An entrypoint can be defined as a single file or directory with an `index` file ```html [Single File] 📂 entrypoints/ - background.ts + 📄 background.ts ``` ```html [Directory] 📂 entrypoints/ 📂 background/ - index.ts + 📄 index.ts ``` ::: diff --git a/docs/guide/essentials/frontend-frameworks.md b/docs/guide/essentials/frontend-frameworks.md index e16951557..e841b835e 100644 --- a/docs/guide/essentials/frontend-frameworks.md +++ b/docs/guide/essentials/frontend-frameworks.md @@ -74,12 +74,19 @@ Usually, this means each entrypoint should be a directory with it's own files in ```html -📂 {srcDir}/ 📂 assets/ <------------------ Put shared assets here 📄 -tailwind.css 📂 components/ 📄 Button.tsx 📂 entrypoints/ 📂 options/ <--------- -Use a folder with an index.html file in it 📁 pages/ <--------- A good place to -put your router pages if you have them 📄 index.html 📄 App.tsx 📄 main.tsx -<--------- Create and mount your app here 📄 style.css <--------- Have -entrypoint-specific styles to apply? 📄 router.ts +📂 {srcDir}/ + 📂 assets/ <---------- Put shared assets here + 📄 tailwind.css + 📂 components/ + 📄 Button.tsx + 📂 entrypoints/ + 📂 options/ <--------- Use a folder with an index.html file in it + 📁 pages/ <--------- A good place to put your router pages if you have them + 📄 index.html + 📄 App.tsx + 📄 main.tsx <--------- Create and mount your app here + 📄 style.css <--------- Have entrypoint-specific styles to apply? + 📄 router.ts ``` ## Configuring Routers diff --git a/docs/guide/essentials/i18n.md b/docs/guide/essentials/i18n.md index 2f52a2309..7b14192eb 100644 --- a/docs/guide/essentials/i18n.md +++ b/docs/guide/essentials/i18n.md @@ -20,8 +20,15 @@ This page discusses how to setup internationalization using the vanilla `browser ```html - 📂 {srcDir}/ 📂 public/ 📂 _locales/ 📂 en/ 📄 messages.json 📂 de/ 📄 - messages.json 📂 ko/ 📄 messages.json + 📂 {srcDir}/ + 📂 public/ + 📂 _locales/ + 📂 en/ + 📄 messages.json + 📂 de/ + 📄 messages.json + 📂 ko/ + 📄 messages.json ``` ```jsonc diff --git a/docs/guide/essentials/project-structure.md b/docs/guide/essentials/project-structure.md index 8d8b1bd8b..ed38d7855 100644 --- a/docs/guide/essentials/project-structure.md +++ b/docs/guide/essentials/project-structure.md @@ -4,10 +4,24 @@ WXT follows a strict project structure. By default, it's a flat folder structure ```html -📂 {rootDir}/ 📁 .output/ 📁 .wxt/ 📁 assets/ 📁 components/ 📁 composables/ 📁 -entrypoints/ 📁 hooks/ 📁 modules/ 📁 public/ 📁 utils/ 📄 .env 📄 .env.publish -📄 app.config.ts 📄 package.json 📄 tsconfig.json 📄 web-ext.config.ts 📄 -wxt.config.ts +📂 {rootDir}/ + 📁 .output/ + 📁 .wxt/ + 📁 assets/ + 📁 components/ + 📁 composables/ + 📁 entrypoints/ + 📁 hooks/ + 📁 modules/ + 📁 public/ + 📁 utils/ + 📄 .env + 📄 .env.publish + 📄 app.config.ts + 📄 package.json + 📄 tsconfig.json + 📄 web-ext.config.ts + 📄 wxt.config.ts ``` Here's a brief summary of each of these files and directories: @@ -43,10 +57,25 @@ After enabling it, your project structure should look like this: ```html -📂 {rootDir}/ 📁 .output/ 📁 .wxt/ 📂 src/ 📁 assets/ 📁 components/ 📁 -composables/ 📁 entrypoints/ 📁 hooks/ 📁 modules/ 📁 public/ 📁 utils/ 📄 -app.config.ts 📄 .env 📄 .env.publish 📄 package.json 📄 tsconfig.json 📄 -web-ext.config.ts 📄 wxt.config.ts +📂 {rootDir}/ +📁 .output/ +📁 .wxt/ +📂 src/ + 📁 assets/ + 📁 components/ + 📁 composables/ + 📁 entrypoints/ + 📁 hooks/ + 📁 modules/ + 📁 public/ + 📁 utils/ + 📄 app.config.ts +📄 .env +📄 .env.publish +📄 package.json +📄 tsconfig.json +📄 web-ext.config.ts +📄 wxt.config.ts ``` You can configure some other project folders as well. See the [wxt.config.ts file](/guide/config/wxt#directories) docs for more details. diff --git a/docs/guide/get-started/installation.md b/docs/guide/get-started/installation.md index 09698c3be..ea4bf5a61 100644 --- a/docs/guide/get-started/installation.md +++ b/docs/guide/get-started/installation.md @@ -118,6 +118,6 @@ Once you've ran the `dev` command, continue to [Next Steps](#next-steps)! ## Next Steps -- Read the [Core Concepts](/guide/core-concepts/project-structure) to learn the basics of your new project -- Configure automatic browser startup during dev mode: [Configuration > Browser Startup](/guide/config/browser-startup) +- Keep reading on about WXT's [Project Structure](/guide/essentials/project-structure) and other essential concepts to learn +- Configure [automatic browser startup](/guide/config/browser-startup) during dev mode - Explore [WXT's example library](/examples) to see how to use specific APIs or perform common tasks From 0194f05490ed64255015579d5fb0e5e63bac5e5b Mon Sep 17 00:00:00 2001 From: Aaron Date: Sun, 29 Sep 2024 09:14:02 -0500 Subject: [PATCH 05/23] Cleanup --- docs/.vitepress/config.ts | 10 +- .../config/{wxt.md => auto-imports.md} | 70 +--------- .../essentials/config/entrypoint-loaders.md | 120 ++++++++++++++++++ docs/guide/essentials/config/hooks.md | 22 ++++ docs/guide/essentials/config/manifest.md | 33 ++--- docs/guide/essentials/config/runtime.md | 6 +- docs/guide/essentials/content-scripts.md | 2 - docs/guide/essentials/entrypoints.md | 4 +- docs/guide/essentials/project-structure.md | 34 ++++- docs/guide/essentials/wxt-modules.md | 4 +- docs/guide/{get-started => }/installation.md | 2 +- docs/guide/{get-started => }/introduction.md | 0 docs/guide/resources/migrate.md | 1 + docs/index.md | 4 +- docs/public/_redirects | 2 +- .../src/client/content-scripts/ui/index.ts | 6 +- 16 files changed, 214 insertions(+), 106 deletions(-) rename docs/guide/essentials/config/{wxt.md => auto-imports.md} (61%) create mode 100644 docs/guide/essentials/config/entrypoint-loaders.md create mode 100644 docs/guide/essentials/config/hooks.md rename docs/guide/{get-started => }/installation.md (96%) rename docs/guide/{get-started => }/introduction.md (100%) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 93ba6d090..823b4c254 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -66,7 +66,7 @@ export default defineConfig({ ], nav: [ - navItem('Guide', '/guide/get-started/installation'), + navItem('Guide', '/guide/installation'), navItem('Examples', '/examples'), navItem('API', '/api/reference/wxt'), navItem('---', [ @@ -89,7 +89,7 @@ export default defineConfig({ sidebar: { '/guide/': menuRoot([ - menuGroup('Get Started', '/guide/get-started/', [ + menuGroup('Get Started', '/guide/', [ menuItem('Introduction', 'introduction.md'), menuItem('Installation', 'installation.md'), ]), @@ -100,12 +100,14 @@ export default defineConfig({ 'Configuration', '/guide/essentials/config/', [ - menuItem('wxt.config.ts', 'wxt.md'), menuItem('Manifest', 'manifest.md'), menuItem('Browser Startup', 'browser-startup.md'), + menuItem('Auto-imports', 'auto-imports.md'), + menuItem('Vite', 'vite.md'), menuItem('Runtime Config', 'runtime.md'), menuItem('TypeScript', 'typescript.md'), - menuItem('Vite', 'vite.md'), + menuItem('Hooks', 'hooks.md'), + menuItem('Entrypoint Loaders', 'entrypoint-loaders.md'), ], true, ), diff --git a/docs/guide/essentials/config/wxt.md b/docs/guide/essentials/config/auto-imports.md similarity index 61% rename from docs/guide/essentials/config/wxt.md rename to docs/guide/essentials/config/auto-imports.md index c3b732032..e764618b1 100644 --- a/docs/guide/essentials/config/wxt.md +++ b/docs/guide/essentials/config/auto-imports.md @@ -1,42 +1,4 @@ ---- -outline: deep ---- - -# wxt.config.ts - -> See the [API Reference](/api/reference/wxt/interfaces/InlineConfig) for all options. This page only discusses the setup and a few features. - -The `wxt.config.ts` file contains the main build configuration for your project. Here's what it looks like: - -```ts -import { defineConfig } from 'wxt'; - -export default defineConfig({ - // Config goes here -}); -``` - -## Directories - -You can configure the following directories: - - -```ts -export default defineConfig({ - // Relative to project root - srcDir: "src", // default: "." - outDir: "dist", // default: ".output" - - // Relative to srcDir - entrypointsDir: "entries", // default: "entrtypoints" - modulesDir: "wxt-modules", // default: "modules" - publicDir: "static", // default: "public" -}) -``` - -You can use absolute or relative paths. - -## Auto-imports +# Auto-imports WXT uses [`unimport`](https://www.npmjs.com/package/unimport), the same tool as Nuxt, to setup auto-imports. @@ -68,9 +30,9 @@ WXT also adds some project directories as auto-import sources automatically: - `/hooks/*` - `/utils/*` -All named and default exports from files in these directories are available anywhere else in your project without having to import them. +All named and default exports from files in these directories are available everywhere else in your project without having to import them. -### TypeScript +## TypeScript For TypeScript and your editor to recognize auto-imported variables, you need to run the [`wxt prepare` command](/api/cli/wxt-prepare). @@ -85,7 +47,7 @@ Add this command to your `postinstall` script so your editor has everything it n } ``` -### ESLint +## ESLint ESLint doesn't know about the auto-imported variables unless they are explicitly defined in the ESLint's `globals`. By default, WXT will generate the config if it detects ESLint is installed in your project. If the config isn't generated automatically, you can manually tell WXT to generate it. @@ -139,7 +101,7 @@ export default { ::: -### Disabling Auto-imports +## Disabling Auto-imports Not all developers like auto-imports. To disable them, set `imports` to `false`. @@ -148,25 +110,3 @@ export default defineConfig({ imports: false, // [!code ++] }); ``` - -## Hooks - -WXT includes an in-depth system that let's you hook into the build process and make changes. - -Here's an example hook that modifies the `manifest.json` file before it is written to the output directory: - -```ts -export default defineConfig({ - hooks: { - 'build:manifestGenerated': (wxt, manifest) => { - if (wxt.config.mode === 'development') { - manifest.title += ' (DEV)'; - } - }, - }, -}); -``` - -> Most hooks provide the `wxt` object as the first argument. If contains the resolved config and other info about the current build. - -Putting one-off hooks like this in your config file is simple, but if you find yourself writing lots of hooks, you should extract them into [WXT Modules](/guide/wxt-modules/writing-modules) instead. diff --git a/docs/guide/essentials/config/entrypoint-loaders.md b/docs/guide/essentials/config/entrypoint-loaders.md new file mode 100644 index 000000000..4f2953903 --- /dev/null +++ b/docs/guide/essentials/config/entrypoint-loaders.md @@ -0,0 +1,120 @@ +# Entrypoint Loaders + +Because entrypoint options, like content script `matches`, are listed in the entrypoint's JS file, WXT has to import them during the build process to use those options when generating the manifest. + +There are two options for loading your entrypoints: + +1. `vite-node` - default as of `v0.19.0` +2. `jiti` (**DEPRECATED, will be removed in `v0.20.0`**) - Default before `v0.19.0` + +## vite-node + +Since 0.19.0, WXT uses `vite-node`, the same tool that powers Vitest and Nuxt, to import your entrypoint files. + +If you use any runtime packages that depend on `webextension-polyfill`, you need to add them to [Vite's `ssr.noExternal` option](https://vitejs.dev/config/ssr-options#ssr-noexternal): + +```ts +export default defineConfig({ + vite: () => ({ + ssr: { + noExternal: ['@webext-core/messaging', '@webext-core/proxy-service'], + }, + }), +}); +``` + +:::details Why? +This tells Vite it needs process these module's, letting WXT properly disable the polyfill in the NodeJS environment so it doesn't cause any build errors like this: + +``` +ERROR This script should only be loaded in a browser extension +``` + +::: + +To get a list of installed packages that use on `webextension-polyfill`, run your package manager's `list` command. Here's an example with PNPM: + +```sh +$ pnpm why webextension-polyfill + +dependencies: +@webext-core/messaging 1.4.0 +└── webextension-polyfill 0.10.0 +@webext-core/proxy-service 1.2.0 +├─┬ @webext-core/messaging 1.4.0 peer +│ └── webextension-polyfill 0.10.0 +└── webextension-polyfill 0.12.0 peer + +devDependencies: +@wxt-dev/module-vue 1.0.0 +└─┬ wxt 0.19.0-alpha1 peer + └── webextension-polyfill 0.12.0 +webextension-polyfill 0.12.0 +wxt 0.19.0-alpha1 +└── webextension-polyfill 0.12.0 +``` + +Ignoring WXT itself (it's added automatically for you), there are three packages that depend on the polyfill: `@wxt-dev/module-vue`, `@webext-core/messaging`, and `@webext-core/proxy-service`. Since the vue module is a build dependency, with no runtime code, you don't have to add it. That means for this case, you need to add `@webext-core/messaging`, and `@webext-core/proxy-service`, as shown in the original code snippet. + +## jiti + +The original method WXT used to import TS files. However, because it doesn't support vite plugins like `vite-node`, there is one main caveot to it's usage: **_module side-effects_**. + +To enable `jiti`: + +```ts +export default defineConfig({ + entrypointLoader: 'jiti', +}); +``` + +You cannot use imported variables outside the `main` function in JS entrypoints. This includes options, as shown below: + +```ts +// entrypoints/content.ts +import { GOOGLE_MATCHES } from '~/utils/match-patterns'; + +export default defineContentScript({ + matches: GOOGLE_MATCHES, + main() { + // ... + }, +}); +``` + +``` +$ wxt build +wxt build + +WXT 0.14.1 +ℹ Building chrome-mv3 for production with Vite 5.0.5 +✖ Command failed after 360 ms + +[8:55:54 AM] ERROR entrypoints/content.ts: Cannot use imported variable "GOOGLE_MATCHES" before main function. See https://wxt.dev/guide/entrypoints.html#side-effects +``` + +This throws an error because WXT needs to import each entrypoint during the build process to extract its definition (containing the `match`, `runAt`, `include`/`exclude`, etc.) to render the `manifest.json` correctly. Before loading an entrypoint, a transformation is applied to remove all imports. This prevents imported modules (local or NPM) with side-effects from running during the build process, potentially throwing an error. + +:::details Why? + +When importing your entrypoint to get its definition, the file is imported in a **_node environment_**, and doesn't have access to the `window`, `chrome`, or `browser` globals a web extension usually has access to. If WXT doesn't remove all the imports from the file, the imported modules could try and access one of these variables, throwing an error. + +::: + +:::warning +See [`wxt-dev/wxt#336`](https://github.com/wxt-dev/wxt/issues/336) to track the status of this bug. +::: + +Usually, this error occurs when you try to extract options into a shared file or try to run code outside the `main` function. To fix the example from above, use literal values when defining an entrypoint instead of importing them: + +```ts +import { GOOGLE_MATCHES } from '~/utils/match-patterns'; // [!code --] + +export default defineContentScript({ + matches: GOOGLE_MATCHES, // [!code --] + matches: ['*//*.google.com/*'], // [!code ++] + main() { + // ... + }, +}); +``` diff --git a/docs/guide/essentials/config/hooks.md b/docs/guide/essentials/config/hooks.md new file mode 100644 index 000000000..747b499d4 --- /dev/null +++ b/docs/guide/essentials/config/hooks.md @@ -0,0 +1,22 @@ +# Hooks + +WXT includes an in-depth system that let's you hook into the build process and make changes. + +Here's an example hook that modifies the `manifest.json` file before it is written to the output directory: + +```ts +// wxt.config.ts +export default defineConfig({ + hooks: { + 'build:manifestGenerated': (wxt, manifest) => { + if (wxt.config.mode === 'development') { + manifest.title += ' (DEV)'; + } + }, + }, +}); +``` + +> Most hooks provide the `wxt` object as the first argument. If contains the resolved config and other info about the current build. + +Putting one-off hooks like this in your config file is simple, but if you find yourself writing lots of hooks, you should extract them into [WXT Modules](/guide/essentials/wxt-modules) instead. diff --git a/docs/guide/essentials/config/manifest.md b/docs/guide/essentials/config/manifest.md index cd15837b1..dfb0b4ecf 100644 --- a/docs/guide/essentials/config/manifest.md +++ b/docs/guide/essentials/config/manifest.md @@ -28,7 +28,7 @@ export default defineConfig({ ### MV2 and MV3 Compatibility -When adding properties to the manifest, when possible, always define the property in it's MV3 format. When targetting MV2, WXT will automatically convert these properties to their MV2 format. +When adding properties to the manifest, always define the property in it's MV3 format when possible. When targetting MV2, WXT will automatically convert these properties to their MV2 format. For example, for this config: @@ -191,8 +191,6 @@ export default defineConfig({ ## Default Locale -> See [Extension APIs > I18n](/guide/extension-apis/i18n) for a full guide on internationalizing your extension. - ```ts export default defineConfig({ manifest: { @@ -203,27 +201,32 @@ export default defineConfig({ }); ``` +> See [I18n docs](/guide/essentials/i18n) for a full guide on internationalizing your extension. + ## Actions -In MV2, you had two options: [`browser_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) and [`page_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action). In MV3, they were merged into a single [`action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/action) API. +In MV2, you have two options: [`browser_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) and [`page_action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action). In MV3, they were merged into a single [`action`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/action) API. By default, whenever an `action` is generated, WXT falls back to `browser_action` when targetting MV2. ### Action With Popup -To generate a manifest where a UI appears after clicking the icon, just create a [Popup entrypoint](/guide/entrypoint-types/popup). +To generate a manifest where a UI appears after clicking the icon, just create a [Popup entrypoint](/guide/essentials/entrypoints#popup). + +```ts export default defineConfig({ -hooks: { -build: { -manifestGenerated(manifest) { -// Update the manifest variable by reference -manifest.name = 'Overriden name'; -}, -}, -}, + hooks: { + build: { + manifestGenerated(manifest) { + // Update the manifest variable by reference + manifest.name = 'Overriden name'; + }, + }, + }, }); +``` -If you want to use a page_action for MV2, add the following meta tag to the HTML document's head: +If you want to use a `page_action` for MV2, add the following meta tag to the HTML document's head: ```html @@ -233,7 +236,7 @@ If you want to use a page_action for MV2, add the following meta tag to the HTML If you want to use the `activeTab` permission or the `browser.action.onClicked` event, but don't want to show a popup: -1. Delete the [Popup entrypoint](/guide/entrypoint-types/popup) if it exists +1. Delete the [Popup entrypoint](/guide/essentials/entrypoints#popup) if it exists 2. Add the `action` key to your manifest: ```ts export default defineConfig({ diff --git a/docs/guide/essentials/config/runtime.md b/docs/guide/essentials/config/runtime.md index bbc736192..2a44f083f 100644 --- a/docs/guide/essentials/config/runtime.md +++ b/docs/guide/essentials/config/runtime.md @@ -29,7 +29,7 @@ export default defineAppConfig({ ``` :::warning -This file is commited to the repo, so don't put any secrets here. Instead, use [Environment Variables](#environment variables) +This file is commited to the repo, so don't put any secrets here. Instead, use [Environment Variables](#environment-variables) ::: To access runtime config, WXT provides the `useAppConfig` function: @@ -62,13 +62,13 @@ You can use them in the `app.config.ts` file. declare module 'wxt/sandbox' { export interface WxtAppConfig { apiKey?: string; - skipTutorial: boolean; + skipWelcome: boolean; } } export default defineAppConfig({ apiKey: import.meta.env.VITE_API_KEY, - skipTutorial: import.meta.env.VITE_SKIP_WELCOME === 'true', + skipWelcome: import.meta.env.VITE_SKIP_WELCOME === 'true', }); ``` diff --git a/docs/guide/essentials/content-scripts.md b/docs/guide/essentials/content-scripts.md index ed4662350..a7d813ca6 100644 --- a/docs/guide/essentials/content-scripts.md +++ b/docs/guide/essentials/content-scripts.md @@ -4,8 +4,6 @@ outline: deep # Content Scripts -To add a content script, refer to [Entrypoint Types > Content Script](/guide/entrypoint-types/content-script). This page discusses the nuonces of writing content scripts with WXT. - ## Context The first argument to a content script's `main` function is it's "context". diff --git a/docs/guide/essentials/entrypoints.md b/docs/guide/essentials/entrypoints.md index 642f75c3f..a886ee67c 100644 --- a/docs/guide/essentials/entrypoints.md +++ b/docs/guide/essentials/entrypoints.md @@ -163,7 +163,7 @@ export default defineBackground({ [Chrome Docs](https://developer.chrome.com/docs/extensions/mv3/content_scripts/) • [Firefox Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts) -See [Content Script UI](/guide/content-scripts/ui) for more info on creating UIs and including CSS in content scripts. +See [Content Script UI](/guide/essentials/content-scripts) for more info on creating UIs and including CSS in content scripts. +```ts +// wxt.config.ts +export default defineConfig({ + // Relative to project root + srcDir: "src", // default: "." + outDir: "dist", // default: ".output" + + // Relative to srcDir + entrypointsDir: "entries", // default: "entrtypoints" + modulesDir: "wxt-modules", // default: "modules" + publicDir: "static", // default: "public" +}) +``` + +You can use absolute or relative paths. diff --git a/docs/guide/essentials/wxt-modules.md b/docs/guide/essentials/wxt-modules.md index e928564ef..16d740c16 100644 --- a/docs/guide/essentials/wxt-modules.md +++ b/docs/guide/essentials/wxt-modules.md @@ -22,7 +22,7 @@ There are two ways to add a module to your project: modules/ my-module.ts ``` - > To learn more about writing your own modules, read the [Writing Modules](/guide/wxt-modules/writing-modules) docs. + > To learn more about writing your own modules, read the [Writing Modules](/guide/essentials/wxt-modules) docs. ## Module Options @@ -31,7 +31,7 @@ WXT modules may require or allow setting custom options to change their behavior 1. **Build-time**: Any config used during the build process, like feature flags 2. **Runtime**: Any config accessed at runtime, like callback functions -Build-time options is placed in your `wxt.config.ts`, while runtime options is placed in the [`app.config.ts` file](/guide/config/runtime). Refer to each module's documentation about what options are required and where they should be placed. +Build-time options is placed in your `wxt.config.ts`, while runtime options is placed in the [`app.config.ts` file](/guide/essentials/config/runtime). Refer to each module's documentation about what options are required and where they should be placed. If you use TypeScript, modules augment WXT's types so you will get type errors if options are missing or incorrect. diff --git a/docs/guide/get-started/installation.md b/docs/guide/installation.md similarity index 96% rename from docs/guide/get-started/installation.md rename to docs/guide/installation.md index ea4bf5a61..c5c007096 100644 --- a/docs/guide/get-started/installation.md +++ b/docs/guide/installation.md @@ -119,5 +119,5 @@ Once you've ran the `dev` command, continue to [Next Steps](#next-steps)! ## Next Steps - Keep reading on about WXT's [Project Structure](/guide/essentials/project-structure) and other essential concepts to learn -- Configure [automatic browser startup](/guide/config/browser-startup) during dev mode +- Configure [automatic browser startup](/guide/essentials/config/browser-startup) during dev mode - Explore [WXT's example library](/examples) to see how to use specific APIs or perform common tasks diff --git a/docs/guide/get-started/introduction.md b/docs/guide/introduction.md similarity index 100% rename from docs/guide/get-started/introduction.md rename to docs/guide/introduction.md diff --git a/docs/guide/resources/migrate.md b/docs/guide/resources/migrate.md index 8ef96d714..a8723e2a4 100644 --- a/docs/guide/resources/migrate.md +++ b/docs/guide/resources/migrate.md @@ -18,6 +18,7 @@ pnpm dlx wxt@latest init example-wxt --template vanilla In general, you'll need to:   Install `wxt`
+  [Extend `.wxt/tsconfig.json`](/guide/essentials/config/typescript.html#typescript-configuration) in your project's `tsconfig.json`   Update/create `package.json` scripts to use `wxt` (don't forget about `postinstall`)
Move entrypoints into `entrypoints/` directory
Move assets into either the `assets/` or `public/` directories
diff --git a/docs/index.md b/docs/index.md index 5ec382ff7..b46633d0e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,10 +13,10 @@ hero: actions: - theme: brand text: Get Started - link: /guide/get-started/installation + link: /guide/installation - theme: alt text: Learn More - link: /guide/get-started/introduction + link: /guide/introduction features: - icon: 🌐 diff --git a/docs/public/_redirects b/docs/public/_redirects index 204977990..825f5f9ce 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -44,7 +44,7 @@ /guide/i18n/messages-file-format.html /TODO /guide/i18n/editor-support.html /TODO /guide/i18n/installation.html /TODO -/guide/key-concepts/content-script-ui.html /guide/content-scripts/ui.html +/guide/key-concepts/content-script-ui.html /guide/essentials/content-scripts.html#ui /guide/key-concepts/manifest.html /TODO /guide/key-concepts/wxt-submit.html /TODO /guide/key-concepts/auto-imports.html /TODO diff --git a/packages/wxt/src/client/content-scripts/ui/index.ts b/packages/wxt/src/client/content-scripts/ui/index.ts index 4aef61e0b..6c7a614a8 100644 --- a/packages/wxt/src/client/content-scripts/ui/index.ts +++ b/packages/wxt/src/client/content-scripts/ui/index.ts @@ -17,7 +17,7 @@ export * from './types'; /** * Create a content script UI without any isolation. * - * @see https://wxt.dev/guide/content-scripts/ui.html#integrated + * @see https://wxt.dev/guide/essentials/content-scripts.html#integrated */ export function createIntegratedUi( ctx: ContentScriptContext, @@ -53,7 +53,7 @@ export function createIntegratedUi( /** * Create a content script UI using an iframe. * - * @see https://wxt.dev/guide/content-scripts/ui.html#iframe + * @see https://wxt.dev/guide/essentials/content-scripts.html#iframe */ export function createIframeUi( ctx: ContentScriptContext, @@ -96,7 +96,7 @@ export function createIframeUi( * * > This function is async because it has to load the CSS via a network call. * - * @see https://wxt.dev/guide/content-scripts/ui.html#shadowroot + * @see https://wxt.dev/guide/essentials/content-scripts.html#shadowroot */ export async function createShadowRootUi( ctx: ContentScriptContext, From 791143345f477f786e3020c4ce6a072fe77cfcc6 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sun, 29 Sep 2024 09:20:17 -0500 Subject: [PATCH 06/23] Fix other links --- README.md | 2 +- docs/guide/essentials/project-structure.md | 4 +--- docs/guide/installation.md | 2 +- docs/guide/introduction.md | 2 +- docs/guide/resources/upgrading.md | 6 +++--- docs/index.md | 2 +- docs/public/_redirects | 4 ++-- packages/i18n/README.md | 10 +++++----- packages/wxt/README.md | 2 +- 9 files changed, 16 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3808327cd..bfc6d6c0f 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get - 🦾 Auto-imports - 🤖 Automated publishing - 🎨 Frontend framework agnostic: works with Vue, React, Svelte, etc -- 📦 Modular architecture with [WXT modules](https://wxt.dev/guide/go-further/reusable-modules.html#overview) +- 📦 Modular architecture with [WXT modules](https://wxt.dev/guide/essentials/wxt-modules.html#overview) - 🖍️ Quickly bootstrap a new project - 📏 Bundle analysis - ⬇️ Download and bundle remote URL imports diff --git a/docs/guide/essentials/project-structure.md b/docs/guide/essentials/project-structure.md index a18240ec4..f7eea9b8c 100644 --- a/docs/guide/essentials/project-structure.md +++ b/docs/guide/essentials/project-structure.md @@ -41,7 +41,7 @@ Here's a brief summary of each of these files and directories: - `package.json`: The standard file used by your package manager - `tsconfig.json`: Config telling TypeScript how to behave - `web-ext.config.ts`: Configure [Browser Startup](/guide/essentials/config/browser-startup) -- `wxt.config.ts`: The [main config file](/guide/essentials/config/wxt) for WXT projects +- `wxt.config.ts`: The main config file for WXT projects ## Adding a `src/` Directory @@ -79,8 +79,6 @@ After enabling it, your project structure should look like this: 📄 wxt.config.ts ``` -You can configure some other project folders as well. See the [wxt.config.ts file](/guide/essentials/config/wxt#directories) docs for more details. - ## Customizing Other Directories You can configure the following directories: diff --git a/docs/guide/installation.md b/docs/guide/installation.md index c5c007096..f79e06f37 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -1,6 +1,6 @@ # Installation -Bootstrap a new project, start from scratch, or [migrate an existing project](./migrate). +Bootstrap a new project, start from scratch, or [migrate an existing project](/guide/resources/migrate). [[toc]] diff --git a/docs/guide/introduction.md b/docs/guide/introduction.md index 442e506a3..5424a07b8 100644 --- a/docs/guide/introduction.md +++ b/docs/guide/introduction.md @@ -23,4 +23,4 @@ You should also be aware of [Chrome's extension docs](https://developer.chrome.c
-Alright, got a basic understanding of how web extensions are structured? Do you know how to access the extension APIs? Then continue to the [Installation page](/guide/get-started/installation) to create your first WXT extension. +Alright, got a basic understanding of how web extensions are structured? Do you know how to access the extension APIs? Then continue to the [Installation page](/guide/installation) to create your first WXT extension. diff --git a/docs/guide/resources/upgrading.md b/docs/guide/resources/upgrading.md index fc2ae3a24..4583193fd 100644 --- a/docs/guide/resources/upgrading.md +++ b/docs/guide/resources/upgrading.md @@ -27,7 +27,7 @@ export default defineConfig({ }); ``` -> [Read the full docs](/guide/go-further/entrypoint-loaders#vite-node) for more information. +> [Read the full docs](/guide/essentials/config/entrypoint-loaders#vite-node) for more information. :::details This change enables: @@ -92,7 +92,7 @@ Vite also provides steps for migrating to ESM. Check them out for more details: ### New `modules/` Directory -WXT now recognizes the `modules/` directory as a folder containing [WXT modules](/guide/go-further/reusable-modules). +WXT now recognizes the `modules/` directory as a folder containing [WXT modules](/guide/essentials/wxt-modules). If you already have `/modules` or `/Modules` directory, `wxt prepare` and other commands will fail. @@ -113,7 +113,7 @@ You have two options: ### New `modules/` Directory -WXT now recognizes the `modules/` directory as a folder containing [WXT modules](/guide/go-further/reusable-modules). +WXT now recognizes the `modules/` directory as a folder containing [WXT modules](/guide/essentials/wxt-modules). If you already have `/modules` or `/Modules` directory, `wxt prepare` and other commands will fail. diff --git a/docs/index.md b/docs/index.md index b46633d0e..0d5ab3962 100644 --- a/docs/index.md +++ b/docs/index.md @@ -56,7 +56,7 @@ features: - icon: 📦 title: Modular Architecture details: Reuse build-time and runtime-code across multiple extensions. - link: /guide/go-further/reusable-modules + link: /guide/essentials/wxt-modules linkText: Read docs - icon: 🖍️ title: Bootstrap a New Project diff --git a/docs/public/_redirects b/docs/public/_redirects index 825f5f9ce..30a4db698 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -51,7 +51,7 @@ /guide/key-concepts/web-extension-polyfill.html /TODO /guide/key-concepts/frontend-frameworks.html /TODO /guide/key-concepts/multiple-browsers.html /TODO -/guide/go-further/entrypoint-loaders.html /TODO +/guide/go-further/entrypoint-loaders.html /guide/essentials/config/entrypoint-loaders.html /guide/go-further/es-modules.html /TODO /guide/go-further/handling-updates.html /TODO /guide/go-further/custom-events.html /TODO @@ -60,7 +60,7 @@ /guide/go-further/vite.html /TODO /guide/go-further/testing.html /TODO /guide/go-further/how-wxt-works.html /TODO -/guide/go-further/reusable-modules.html /TODO +/guide/go-further/reusable-modules.html /guide/essentials/wxt-modules.html /guide/extension-apis/messaging.html /TODO /guide/extension-apis/i18n.html /TODO /guide/extension-apis/storage.html /TODO diff --git a/packages/i18n/README.md b/packages/i18n/README.md index 670c95033..01a9be821 100644 --- a/packages/i18n/README.md +++ b/packages/i18n/README.md @@ -1,13 +1,13 @@ # `@wxt-dev/i18n` > [!IMPORTANT] -> You don't have to use `wxt` to use this package - it will work in any bundler setup. See [Installation without WXT](./installation#without-wxt) for more details. +> You don't have to use `wxt` to use this package - it will work in any bundler setup. See [Installation without WXT](#without-wxt) for more details. `@wxt-dev/i18n` is a simple, type-safe wrapper around the `browser.i18n` APIs. It provides several benefits over the standard API: 1. Simple messages file format 2. Plural form support -3. Integrates with the [I18n Ally VS Code extension](./editor-support#vscode) +3. Integrates with the [I18n Ally VS Code extension](#vscode) It also provides several benefits over other non-web extension specific i18n packages: @@ -84,7 +84,7 @@ And you're done! Using WXT, you get type-safety out of the box. > 2. Simple messages file format > 3. Type safety > - > See [Build Integrations](./build-integrations) to set it up. + > See [Build Integrations](#build-integrations) to set it up. 3. Create the `i18n` object, export it, and use it wherever you want! @@ -99,7 +99,7 @@ And you're done! Using WXT, you get type-safety out of the box. ## Messages File Format > [!DANGER] -> You can only use the file format discussed on this page if you have [integrated `@wxt-dev/i18n` into your build process](./build-integrations). If you have not integrated it into your build process, you must use JSON files in the `_locales` directory, like a normal web extension. +> You can only use the file format discussed on this page if you have [integrated `@wxt-dev/i18n` into your build process](#build-integrations). If you have not integrated it into your build process, you must use JSON files in the `_locales` directory, like a normal web extension. ### File Extensions @@ -255,7 +255,7 @@ To use the custom messages file format, you'll need to use `@wxt-dev/i18n/build` ### WXT -See [Installation with WXT](./installation#with-wxt). +See [Installation with WXT](#with-wxt). But TLDR, all you need is: diff --git a/packages/wxt/README.md b/packages/wxt/README.md index f629dbd0d..9a3a45870 100644 --- a/packages/wxt/README.md +++ b/packages/wxt/README.md @@ -71,7 +71,7 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get - 🦾 Auto-imports - 🤖 Automated publishing - 🎨 Frontend framework agnostic: works with Vue, React, Svelte, etc -- 📦 Modular architecture with [WXT modules](https://wxt.dev/guide/go-further/reusable-modules.html#overview) +- 📦 Modular architecture with [WXT modules](https://wxt.dev/guide/essentials/wxt-modules.html#overview) - 🖍️ Quickly bootstrap a new project - 📏 Bundle analysis - ⬇️ Download and bundle remote URL imports From 6f74d22a40ad02182243579b1c2ca1e3c46363bd Mon Sep 17 00:00:00 2001 From: Aaron Date: Sun, 29 Sep 2024 09:25:13 -0500 Subject: [PATCH 07/23] Add missing declaration file docs --- docs/guide/essentials/config/typescript.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/guide/essentials/config/typescript.md b/docs/guide/essentials/config/typescript.md index 3e1b111ac..b2981f51c 100644 --- a/docs/guide/essentials/config/typescript.md +++ b/docs/guide/essentials/config/typescript.md @@ -11,6 +11,12 @@ At a minimum, you need to create a TSConfig in your root directory that looks li } ``` +Or if you're in a monorepo, you may not want to extend the config. If you don't extend it, you need to add `.wxt/wxt.d.ts` to the TypeScript project: + +```ts +/// +``` + Additionally, if you need to specify custom compiler options, you should add them in `/tsconfig.json`, NOT `/.wxt/tsconfig.json`. ```jsonc From 7d0ddd704b0cf4f9fb741aed458a2938dd077b9c Mon Sep 17 00:00:00 2001 From: Aaron Date: Sun, 29 Sep 2024 09:35:34 -0500 Subject: [PATCH 08/23] Cleanup version drop-down --- docs/.vitepress/config.ts | 13 ++++++------- docs/storage.md | 6 +++--- packages/auto-icons/README.md | 2 ++ packages/i18n/README.md | 6 ++++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 823b4c254..0728ebb6e 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -10,6 +10,7 @@ import { import { meta, script } from './utils/head'; import { version as wxtVersion } from '../../packages/wxt/package.json'; import { version as i18nVersion } from '../../packages/i18n/package.json'; +import { version as autoIconsVersion } from '../../packages/auto-icons/package.json'; const title = 'Next-gen Web Extension Framework'; const titleSuffix = ' – WXT'; @@ -69,7 +70,7 @@ export default defineConfig({ navItem('Guide', '/guide/installation'), navItem('Examples', '/examples'), navItem('API', '/api/reference/wxt'), - navItem('---', [ + navItem(`v${wxtVersion}`, [ navItem('wxt', [ navItem(`v${wxtVersion}`, '/'), navItem( @@ -77,12 +78,10 @@ export default defineConfig({ 'https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md', ), ]), - navItem('@wxt-dev/i18n', [ - navItem(`v${i18nVersion}`, '/i18n'), - navItem( - `Changelog`, - 'https://github.com/wxt-dev/wxt/blob/main/packages/i18n/CHANGELOG.md', - ), + navItem('Other Packages', [ + navItem(`wxt/storage — ${wxtVersion}`, '/storage'), + navItem(`@wxt-dev/auto-icons — ${autoIconsVersion}`, '/auto-icons'), + navItem(`@wxt-dev/i18n — ${i18nVersion}`, '/i18n'), ]), ]), ], diff --git a/docs/storage.md b/docs/storage.md index 6121da042..6fb876d3e 100644 --- a/docs/storage.md +++ b/docs/storage.md @@ -2,7 +2,9 @@ outline: deep --- -# `wxt/storage` API +# WXT Storage + +[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md) WXT provides a simplified API to replace the `browser.storage.*` APIs. Use the `storage` auto-import from `wxt/storage` or import it manually to get started: @@ -22,8 +24,6 @@ import { storage } from 'wxt/storage'; > }); > ``` -[[toc]] - ## Basic Usage All storage keys must be prefixed by their storage area. diff --git a/packages/auto-icons/README.md b/packages/auto-icons/README.md index 0cef29935..3ee347735 100644 --- a/packages/auto-icons/README.md +++ b/packages/auto-icons/README.md @@ -1,5 +1,7 @@ # WXT Auto Icons +[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/auto-icons/CHANGELOG.md) + ## Features - Generate extension icons with the correct sizes diff --git a/packages/i18n/README.md b/packages/i18n/README.md index 01a9be821..d1fc05dce 100644 --- a/packages/i18n/README.md +++ b/packages/i18n/README.md @@ -1,7 +1,6 @@ # `@wxt-dev/i18n` -> [!IMPORTANT] -> You don't have to use `wxt` to use this package - it will work in any bundler setup. See [Installation without WXT](#without-wxt) for more details. +[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/i18n/CHANGELOG.md) `@wxt-dev/i18n` is a simple, type-safe wrapper around the `browser.i18n` APIs. It provides several benefits over the standard API: @@ -19,6 +18,9 @@ However, it does have one major downside: 1. Like the `browser.i18n` API, to change the language, users must change the browser's language +> [!IMPORTANT] +> You don't have to use `wxt` to use this package - it will work in any bundler setup. See [Installation without WXT](#without-wxt) for more details. + ## Installation ### With WXT From dab3c81160b1e5e3e53bbc3468746b722b8c7262 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sun, 29 Sep 2024 20:52:09 -0500 Subject: [PATCH 09/23] Update entrypoints wording --- docs/guide/essentials/entrypoints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/essentials/entrypoints.md b/docs/guide/essentials/entrypoints.md index a886ee67c..ec045d0a6 100644 --- a/docs/guide/essentials/entrypoints.md +++ b/docs/guide/essentials/entrypoints.md @@ -4,7 +4,7 @@ outline: deep # Entrypoints -All files inside the `entrypoints/` directory are built by WXT and bundled into the `.output` directory. They can be HTML, JS, CSS, or any variant of those file types supported by Vite (Pug, TS, JSX, SCSS, etc). +WXT uses the files inside the `entrypoints/` directory as inputs when bundling your extension. They can be HTML, JS, CSS, or any variant of those file types supported by Vite (Pug, TS, JSX, SCSS, etc). Here's an example set of entrypoints: From 3cdf25cdf99dc558bc0623356185746c2d004cbd Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 30 Sep 2024 09:25:56 -0500 Subject: [PATCH 10/23] Add docs around windows data persistence --- docs/guide/essentials/config/browser-startup.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/guide/essentials/config/browser-startup.md b/docs/guide/essentials/config/browser-startup.md index 475aae71d..8f1c8e4aa 100644 --- a/docs/guide/essentials/config/browser-startup.md +++ b/docs/guide/essentials/config/browser-startup.md @@ -49,12 +49,25 @@ Right now, Chromium based browsers are the only browsers that support overriding To persist data, set the `--user-data-dir` flag: -```ts +:::code-group + +```ts [Mac/Linux] export default defineRunnerConfig({ chromiumArgs: ['--user-data-dir=./.wxt/chrome-data'], }); ``` +```ts [Windows] +// WARNING: This doesn't seem to work on windows, chrome doesn't respect the +// --user-data-dir. If you figure out a way to do this, please share so we can +// update these docs. +export default defineRunnerConfig({ + chromiumArgs: ['--user-data-dir=.\\.wxt\\chrome-data'], +}); +``` + +::: + Now, next timne you run the `dev` script, a persistent profile will be created in `.wxt/chrome-data/{profile-name}`. With a persistent profile, you can install devtools extensions to help with development, allow the browser to remember logins, etc, without worrying about the profile being reset the next time you run the `dev` script. ### Disable Opening Browser From 5dd077607815f874cb16042449079577befcb9b7 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 1 Oct 2024 09:27:21 -0500 Subject: [PATCH 11/23] Update TSConfig paths aliases --- docs/guide/essentials/config/typescript.md | 25 +++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/guide/essentials/config/typescript.md b/docs/guide/essentials/config/typescript.md index b2981f51c..9d283096f 100644 --- a/docs/guide/essentials/config/typescript.md +++ b/docs/guide/essentials/config/typescript.md @@ -17,7 +17,9 @@ Or if you're in a monorepo, you may not want to extend the config. If you don't /// ``` -Additionally, if you need to specify custom compiler options, you should add them in `/tsconfig.json`, NOT `/.wxt/tsconfig.json`. +## Compiler Options + +To specify custom compiler options, add them in `/tsconfig.json`: ```jsonc // /tsconfig.json @@ -31,16 +33,33 @@ Additionally, if you need to specify custom compiler options, you should add the ## TSConfig Paths -`/.wxt/tsconfig.json` includes a default set of path aliases. To add your own, DO NOT add them to either `tsconfig.json` by hand. +WXT provides a default set of path aliases. + +| Alias | To | Example | +| ----- | ------------- | ----------------------------------------------- | +| `~~` | `/*` | `import "~~/scripts"` | +| `@@` | `/*` | `import "@@/scripts"` | +| `~` | `/*` | `import { toLowerCase } from "~/utils/strings"` | +| `@` | `/*` | `import { toLowerCase } from "@/utils/strings"` | + +To add your own, DO NOT add them to your `tsconfig.json`! Instead, use the [`alias` option](/api/reference/wxt/interfaces/InlineConfig#alias) in `wxt.config.ts`. -Instead, use the [`alias` config](/api/reference/wxt/interfaces/InlineConfig#alias) in `wxt.config.ts`. This will add your custom aliases to the generated `/.wxt/tsconfig.json` file next time you run `wxt prepare`. +This will add your custom aliases to `/.wxt/tsconfig.json` next time you run `wxt prepare`. It also adds your alias to the bundler so it can resolve imports ```ts import { resolve } from 'node:path'; export default defineConfig({ alias: { + // Directory: testing: resolve('utils/testing'), + // File: + strings: resolve('utils/strings.ts'), }, }); ``` + +```ts +import { fakeTab } from 'testing/fake-objects'; +import { toLowerCase } from 'strings'; +``` From 026ee3750a6079d414a3707d1e96c09f1444aa09 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 1 Oct 2024 09:51:07 -0500 Subject: [PATCH 12/23] Add back badge styles --- docs/.vitepress/theme/custom.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index 6659a0544..a7aa59809 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -84,3 +84,16 @@ body { .VPSidebar { user-select: none; } + +.VPSidebarItem .badge { + display: inline-block; + min-width: 1.6em; + padding: 0.3em 0.4em 0.2em; + border-radius: 1rem; + font-size: 0.75em; + line-height: 1; + margin-left: 0.5rem; + text-align: center; + vertical-align: middle; + background-color: var(--vp-c-default-2); +} From 4d7b5db9bf74f5a660dbc6f94dcb4b6a59fb0b37 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 1 Oct 2024 09:57:08 -0500 Subject: [PATCH 13/23] Fix links and typo --- README.md | 2 +- docs/guide/essentials/content-scripts.md | 2 +- docs/index.md | 16 ++++++++-------- packages/wxt/README.md | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bfc6d6c0f..295b4d778 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get - 🦾 Auto-imports - 🤖 Automated publishing - 🎨 Frontend framework agnostic: works with Vue, React, Svelte, etc -- 📦 Modular architecture with [WXT modules](https://wxt.dev/guide/essentials/wxt-modules.html#overview) +- 📦 [Module system](https://wxt.dev/guide/essentials/wxt-modules.html#overview) for reusing code between extensions - 🖍️ Quickly bootstrap a new project - 📏 Bundle analysis - ⬇️ Download and bundle remote URL imports diff --git a/docs/guide/essentials/content-scripts.md b/docs/guide/essentials/content-scripts.md index a7d813ca6..b49fb8fa4 100644 --- a/docs/guide/essentials/content-scripts.md +++ b/docs/guide/essentials/content-scripts.md @@ -564,7 +564,7 @@ export default defineContentScript(async () => { `injectScript` returns a promise, that when resolved, means the script has been evaluated by the browser and you can start communicating with it. -:::warning Warning: `run_at` Caveots +:::warning Warning: `run_at` Caveat For MV3, `injectScript` is synchronous and the injected script will be evaluated at the same time as your the content script's `run_at`. However for MV2, `injectScript` has to `fetch` the script's text content and create an inline ` + +``` + +## Background + +In your background script, set `type: "module"`: + +```ts +export default defineBackground({ + type: 'module', // !code ++ + main() { + // ... + }, +}); +``` + +:::warning +Only MV3 supports ESM background scripts/service workers. When targeting MV2, the `type` option is ignored and the background is always bundled into a single file as IIFE. +::: + +## Content Scripts + +WXT does not yet include built-in support for ESM content scripts. The plan is to add support for chunking to reduce bundle size, but not support HMR for now. There are several technical issues that make implementing a generic solution for HMR impossible. See [Content Script ESM Support #357](https://github.com/wxt-dev/wxt/issues/357) for details. + +If you can't wait, and need ESM support right now, you can implement ESM support manually. See the [ESM Content Script UI](https://github.com/wxt-dev/examples/tree/main/examples/esm-content-script-ui) example to get started. diff --git a/docs/public/_redirects b/docs/public/_redirects index 30a4db698..ccc1a02a3 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -39,67 +39,67 @@ # https://github.com/wxt-dev/wxt/issues/704 # Generated via `pnpm docs:build && find docs/.vitepress/dist -type f -name "*.html"` -/guide/i18n/build-integrations.html /TODO -/guide/i18n/introduction.html /TODO -/guide/i18n/messages-file-format.html /TODO -/guide/i18n/editor-support.html /TODO -/guide/i18n/installation.html /TODO +/guide/i18n/build-integrations.html /i18n#build-integrations +/guide/i18n/introduction.html /i18n +/guide/i18n/messages-file-format.html /i18n#messages-file-format +/guide/i18n/editor-support.html /i18n#editor-support +/guide/i18n/installation.html /i18n#installation /guide/key-concepts/content-script-ui.html /guide/essentials/content-scripts.html#ui -/guide/key-concepts/manifest.html /TODO -/guide/key-concepts/wxt-submit.html /TODO -/guide/key-concepts/auto-imports.html /TODO -/guide/key-concepts/web-extension-polyfill.html /TODO -/guide/key-concepts/frontend-frameworks.html /TODO -/guide/key-concepts/multiple-browsers.html /TODO +/guide/key-concepts/manifest.html /guide/essentials/config/manifest.html +/guide/key-concepts/wxt-submit.html /api/cli/wxt-submit.html +/guide/key-concepts/auto-imports.html /guide/essentials/config/auto-imports.html +/guide/key-concepts/web-extension-polyfill.html /guide/essentials/extension-apis.html +/guide/key-concepts/frontend-frameworks.html /guide/essentials/frontend-frameworks.html +/guide/key-concepts/multiple-browsers.html /guide/essentials/target-different-browsers.html /guide/go-further/entrypoint-loaders.html /guide/essentials/config/entrypoint-loaders.html -/guide/go-further/es-modules.html /TODO -/guide/go-further/handling-updates.html /TODO -/guide/go-further/custom-events.html /TODO +/guide/go-further/es-modules.html /guide/essentials/es-modules.html +/guide/go-further/handling-updates.html /guide/essentials/testing-updates.html +/guide/go-further/custom-events.html /guide/essentials/content-scripts.html#dealing-with-spas /guide/go-further/debugging.html /TODO -/guide/go-further/remote-code.html /TODO -/guide/go-further/vite.html /TODO -/guide/go-further/testing.html /TODO -/guide/go-further/how-wxt-works.html /TODO +/guide/go-further/remote-code.html /guide/essentials/remote-code.html +/guide/go-further/vite.html /guide/essentials/config/vite.html +/guide/go-further/testing.html /guide/essentials/unit-testing.html +/guide/go-further/how-wxt-works.html /guide/resources/how-wxt-works.html /guide/go-further/reusable-modules.html /guide/essentials/wxt-modules.html -/guide/extension-apis/messaging.html /TODO -/guide/extension-apis/i18n.html /TODO -/guide/extension-apis/storage.html /TODO -/guide/extension-apis/scripting.html /TODO -/guide/extension-apis/others.html /TODO -/guide/upgrade-guide/wxt.html /TODO -/guide/directory-structure/components.html /TODO -/guide/directory-structure/hooks.html /TODO -/guide/directory-structure/assets.html /TODO -/guide/directory-structure/package.html /TODO -/guide/directory-structure/env.html /TODO -/guide/directory-structure/wxt-config.html /TODO -/guide/directory-structure/wxt.html /TODO -/guide/directory-structure/public/locales.html /TODO -/guide/directory-structure/public/index.html /TODO -/guide/directory-structure/entrypoints/devtools.html /TODO -/guide/directory-structure/entrypoints/sidepanel.html /TODO -/guide/directory-structure/entrypoints/content-scripts.html /TODO -/guide/directory-structure/entrypoints/newtab.html /TODO -/guide/directory-structure/entrypoints/bookmarks.html /TODO -/guide/directory-structure/entrypoints/unlisted-pages.html /TODO -/guide/directory-structure/entrypoints/unlisted-scripts.html /TODO -/guide/directory-structure/entrypoints/options.html /TODO -/guide/directory-structure/entrypoints/background.html /TODO -/guide/directory-structure/entrypoints/popup.html /TODO -/guide/directory-structure/entrypoints/history.html /TODO -/guide/directory-structure/entrypoints/sandbox.html /TODO -/guide/directory-structure/entrypoints/css.html /TODO -/guide/directory-structure/web-ext-config.html /TODO -/guide/directory-structure/tsconfig.html /TODO -/guide/directory-structure/utils.html /TODO -/guide/directory-structure/app-config.html /TODO -/guide/directory-structure/composables.html /TODO -/guide/directory-structure/output.html /TODO -/get-started/assets.html /TODO -/get-started/introduction.html /TODO -/get-started/configuration.html /TODO -/get-started/publishing.html /TODO -/get-started/migrate-to-wxt.html /TODO -/get-started/compare.html /guide/resources/compare -/get-started/entrypoints.html /TODO -/get-started/installation.html /TODO +/guide/extension-apis/messaging.html /guide/essentials/messaging.html +/guide/extension-apis/i18n.html /guide/essentials/i18n.html +/guide/extension-apis/storage.html /guide/essentials/storage.html +/guide/extension-apis/scripting.html /guide/essentials/scripting.html +/guide/extension-apis/others.html /guide/essentials/extension-apis.html +/guide/upgrade-guide/wxt.html /guide/resources/upgrading.html +/guide/directory-structure/components.html /guide/essentials/project-structure.html +/guide/directory-structure/hooks.html /guide/essentials/config/hooks.html +/guide/directory-structure/assets.html /guide/essentials/assets.html#assets-directory +/guide/directory-structure/package.html /guide/essentials/project-structure.html +/guide/directory-structure/env.html /guide/essentials/config/runtime.html +/guide/directory-structure/wxt-config.html /guide/essentials/project-structure.html +/guide/directory-structure/wxt.html /guide/essentials/project-structure.html +/guide/directory-structure/public/locales.html /guide/essentials/project-structure.html +/guide/directory-structure/public/index.html /guide/essentials/assets.html#public-directory +/guide/directory-structure/entrypoints/devtools.html /guide/essentials/entrypoints.html#devtools +/guide/directory-structure/entrypoints/sidepanel.html /guide/essentials/entrypoints.html#sidepanel +/guide/directory-structure/entrypoints/content-scripts.html /guide/essentials/entrypoints.html#content-scripts +/guide/directory-structure/entrypoints/newtab.html /guide/essentials/entrypoints.html#newtab +/guide/directory-structure/entrypoints/bookmarks.html /guide/essentials/entrypoints.html#bookmarks +/guide/directory-structure/entrypoints/unlisted-pages.html /guide/essentials/entrypoints.html#unlisted-pages +/guide/directory-structure/entrypoints/unlisted-scripts.html /guide/essentials/entrypoints.html#unlisted-scripts +/guide/directory-structure/entrypoints/options.html /guide/essentials/entrypoints.html#options +/guide/directory-structure/entrypoints/background.html /guide/essentials/entrypoints.html#background +/guide/directory-structure/entrypoints/popup.html /guide/essentials/entrypoints.html#popup +/guide/directory-structure/entrypoints/history.html /guide/essentials/entrypoints.html#history +/guide/directory-structure/entrypoints/sandbox.html /guide/essentials/entrypoints.html#sandbox +/guide/directory-structure/entrypoints/css.html /guide/essentials/entrypoints.html#unlisted-css +/guide/directory-structure/web-ext-config.html /guide/essentials/config/browser-startup.html +/guide/directory-structure/tsconfig.html /guide/essentials/config/typescript.html +/guide/directory-structure/utils.html /guide/essentials/project-structure.html +/guide/directory-structure/app-config.html /guide/essentials/config/runtime.html +/guide/directory-structure/composables.html /guide/essentials/project-structure.html +/guide/directory-structure/output.html /guide/essentials/project-structure.html +/get-started/assets.html /guide/essentials/assets.html +/get-started/introduction.html /guide/introduction.html +/get-started/configuration.html /guide/essentials/config/manifest.html +/get-started/publishing.html /guide/essentials/publishing.html +/get-started/migrate-to-wxt.html /guide/resources/migrate.html +/get-started/compare.html /guide/resources/compare.html +/get-started/entrypoints.html /guide/essentials/entrypoints.html +/get-started/installation.html /guide/installation.html From 9d03fcacc4d4119718e74f3dc895b1d1336c8f2b Mon Sep 17 00:00:00 2001 From: Aaron Date: Fri, 18 Oct 2024 09:22:51 -0500 Subject: [PATCH 23/23] Break env vars out into it's own file so it's easier to find --- docs/.vitepress/config.ts | 3 +- .../config/environment-variables.md | 54 +++++++++++++++++ docs/guide/essentials/config/runtime.md | 60 ------------------- 3 files changed, 56 insertions(+), 61 deletions(-) create mode 100644 docs/guide/essentials/config/environment-variables.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index d8e5d51ed..87f398dc6 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -102,8 +102,9 @@ export default defineConfig({ menuItem('Manifest', 'manifest.md'), menuItem('Browser Startup', 'browser-startup.md'), menuItem('Auto-imports', 'auto-imports.md'), - menuItem('Vite', 'vite.md'), + menuItem('Environment Variables', 'environment-variables.md'), menuItem('Runtime Config', 'runtime.md'), + menuItem('Vite', 'vite.md'), menuItem('Build Mode', 'build-mode.md'), menuItem('TypeScript', 'typescript.md'), menuItem('Hooks', 'hooks.md'), diff --git a/docs/guide/essentials/config/environment-variables.md b/docs/guide/essentials/config/environment-variables.md new file mode 100644 index 000000000..be97952f1 --- /dev/null +++ b/docs/guide/essentials/config/environment-variables.md @@ -0,0 +1,54 @@ +# Environment Variables + +## Dotenv Files + +WXT supports [dotenv files the same way as Vite](https://vite.dev/guide/env-and-mode.html#env-files). Create any of the following files: + +``` +.env +.env.local +.env.[mode] +.env.[mode].local +``` + +And any environment variables listed inside them will be available at runtime: + +```sh +# .env +VITE_API_KEY=... +``` + +```ts +await fetch(`/some-api?apiKey=${import.meta.env.VITE_API_KEY}`); +``` + +Remember to prefix any environment variables with `VITE_`, otherwise they won't be available at runtime, as per [Vite's convention](https://vite.dev/guide/env-and-mode.html#env-files). + +## Built-in Environment Variables + +WXT provides some custom environment variables based on the current command: + +| Usage | Type | Description | +| ---------------------------------- | --------- | ----------------------------------------------------- | +| `import.meta.env.MANIFEST_VERSION` | `2 │ 3` | The target manifest version | +| `import.meta.env.BROWSER` | `string` | The target browser | +| `import.meta.env.CHROME` | `boolean` | Equivalent to `import.meta.env.BROWSER === "chrome"` | +| `import.meta.env.FIREFOX` | `boolean` | Equivalent to `import.meta.env.BROWSER === "firefox"` | +| `import.meta.env.SAFARI` | `boolean` | Equivalent to `import.meta.env.BROWSER === "safari"` | +| `import.meta.env.EDGE` | `boolean` | Equivalent to `import.meta.env.BROWSER === "edge"` | +| `import.meta.env.OPERA` | `boolean` | Equivalent to `import.meta.env.BROWSER === "opera"` | + +You can also access all of [Vite's environment variables](https://vite.dev/guide/env-and-mode.html#env-variables): + +| Usage | Type | Description | +| ---------------------- | --------- | --------------------------------------------------------------------------- | +| `import.meta.env.MODE` | `string` | The [mode](/guide/essentials/config/build-mode) the extension is running in | +| `import.meta.env.PROD` | `boolean` | When `NODE_ENV='production'` | +| `import.meta.env.DEV` | `boolean` | Opposite of `import.meta.env.PROD` | + +:::details Other Vite Environment Variables +Vite provides two other environment variables, but they aren't useful in WXT projects: + +- `import.meta.env.BASE_URL`: Use `browser.runtime.getURL` instead. +- `import.meta.env.SSR`: Always `false`. + ::: diff --git a/docs/guide/essentials/config/runtime.md b/docs/guide/essentials/config/runtime.md index ce392e84d..084a43f5f 100644 --- a/docs/guide/essentials/config/runtime.md +++ b/docs/guide/essentials/config/runtime.md @@ -1,12 +1,5 @@ # Runtime Config -There are two ways to configure runtime behavior: - -- App Config File -- Environment Variables - -## App Config File - > This API is still a WIP, with more features coming soon! Define runtime configuration in a single place, `/app.config.ts`: @@ -38,59 +31,6 @@ import { useAppConfig } from 'wxt/sandbox'; console.log(useAppConfig()); // { theme: "dark" } ``` -## Environment Variables - -WXT provides some custom environment variables based on the current command: - -| Usage | Type | Description | -| ---------------------------------- | --------- | ---------------------------------------------------- | -| `import.meta.env.MANIFEST_VERSION` | `2 │ 3` | The target manifest version | -| `import.meta.env.BROWSER` | `string` | The target browser | -| `import.meta.env.CHROME` | `boolean` | Shortcut for `import.meta.env.BROWSER === "chrome"` | -| `import.meta.env.FIREFOX` | `boolean` | Shortcut for `import.meta.env.BROWSER === "firefox"` | -| `import.meta.env.SAFARI` | `boolean` | Shortcut for `import.meta.env.BROWSER === "safari"` | -| `import.meta.env.EDGE` | `boolean` | Shortcut for `import.meta.env.BROWSER === "edge"` | -| `import.meta.env.OPERA` | `boolean` | Shortcut for `import.meta.env.BROWSER === "opera"` | - -You can also access all of [Vite's environment variables](https://vite.dev/guide/env-and-mode.html#env-variables): - -| Usage | Type | Description | -| ---------------------- | --------- | --------------------------------------------------------------------------- | -| `import.meta.env.MODE` | `string` | The [mode](/guide/essentials/config/build-mode) the extension is running in | -| `import.meta.env.PROD` | `boolean` | When `NODE_ENV='production'` | -| `import.meta.env.DEV` | `boolean` | Opposite of `import.meta.env.PROD` | - -:::details Other Vite Environment Variables -Vite provides two other environment variables, but they aren't useful in WXT projects: - -- `import.meta.env.BASE_URL`: Use `browser.runtime.getURL` instead. -- `import.meta.env.SSR`: Always `false`. - ::: - -### Dotenv Files - -WXT supports [dotenv files the same way as Vite](https://vite.dev/guide/env-and-mode.html#env-files). Create any of the following files: - -``` -.env -.env.local -.env.[mode] -.env.[mode].local -``` - -And any environment variables listed inside them will be available at runtime: - -```sh -# .env -VITE_API_KEY=... -``` - -```ts -await fetch(`/some-api?apiKey=${import.meta.env.VITE_API_KEY}`); -``` - -Remember to prefix any environment variables with `VITE_`, otherwise they won't be available at runtime, as per [Vite's convention](https://vite.dev/guide/env-and-mode.html#env-files). - ## Environment Variables in App Config You can use environment variables in the `app.config.ts` file.

Input PatternFilename Output Path
+ entrypoints/{{ pattern[0] }} @@ -31,7 +31,7 @@ const props = defineProps<{ /> + /{{ pattern[1] }}