From 17e2ab8f1ae6c3e8efa1e67df38032f1bb1d3929 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 03:15:11 +0000 Subject: [PATCH 01/12] feat: add Agrifine browser extension scaffold (Phase 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manifest V3 Chrome extension with a persistent side-panel dashboard for farm data management. Includes: - Background service worker that proxies all Anthropic API calls (API key stored in chrome.storage.session, never in content scripts) - Content script that extracts page text for reading-list summarisation - Sidebar UI with bottom tab bar and settings panel (API key entry) - Five module stubs wired to live storage: 1. ReadingList — save pages with AI summary + topic tagging 2. DataIngest — drag-and-drop CSV/Excel/PDF → AI-structured JSON 3. FieldProfile — per-field cards with CLU, acres, soil, coordinates 4. Dashboard — unified filterable view + natural-language AI query bar 5. CarbonEstimator — Phase 7 stub with feature preview - Shared storage schema (chrome.storage.local) with context-bundle builder for passing reading-list + field data as AI system context - Tailwind CSS + Webpack 5 build pipeline; builds successfully Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01KBD2dN2KEjzz3UQFa9hEpu --- agrifine-extension/.babelrc | 8 + agrifine-extension/.gitignore | 3 + agrifine-extension/manifest.json | 45 + agrifine-extension/package-lock.json | 5282 +++++++++++++++++ agrifine-extension/package.json | 30 + agrifine-extension/postcss.config.js | 6 + agrifine-extension/public/icons/icon128.png | Bin 0 -> 306 bytes agrifine-extension/public/icons/icon16.png | Bin 0 -> 79 bytes agrifine-extension/public/icons/icon32.png | Bin 0 -> 99 bytes agrifine-extension/public/icons/icon48.png | Bin 0 -> 123 bytes agrifine-extension/src/background/index.js | 42 + agrifine-extension/src/content/index.js | 25 + .../src/modules/carbon-estimator/index.js | 56 + .../src/modules/dashboard/index.js | 183 + .../src/modules/data-ingest/index.js | 234 + .../src/modules/field-profile/index.js | 179 + .../src/modules/reading-list/index.js | 154 + agrifine-extension/src/sidebar/index.js | 90 + agrifine-extension/src/sidebar/sidebar.css | 60 + agrifine-extension/src/sidebar/sidebar.html | 94 + agrifine-extension/src/utils/api.js | 66 + agrifine-extension/src/utils/storage.js | 136 + agrifine-extension/tailwind.config.js | 35 + agrifine-extension/webpack/webpack.config.js | 57 + 24 files changed, 6785 insertions(+) create mode 100644 agrifine-extension/.babelrc create mode 100644 agrifine-extension/.gitignore create mode 100644 agrifine-extension/manifest.json create mode 100644 agrifine-extension/package-lock.json create mode 100644 agrifine-extension/package.json create mode 100644 agrifine-extension/postcss.config.js create mode 100644 agrifine-extension/public/icons/icon128.png create mode 100644 agrifine-extension/public/icons/icon16.png create mode 100644 agrifine-extension/public/icons/icon32.png create mode 100644 agrifine-extension/public/icons/icon48.png create mode 100644 agrifine-extension/src/background/index.js create mode 100644 agrifine-extension/src/content/index.js create mode 100644 agrifine-extension/src/modules/carbon-estimator/index.js create mode 100644 agrifine-extension/src/modules/dashboard/index.js create mode 100644 agrifine-extension/src/modules/data-ingest/index.js create mode 100644 agrifine-extension/src/modules/field-profile/index.js create mode 100644 agrifine-extension/src/modules/reading-list/index.js create mode 100644 agrifine-extension/src/sidebar/index.js create mode 100644 agrifine-extension/src/sidebar/sidebar.css create mode 100644 agrifine-extension/src/sidebar/sidebar.html create mode 100644 agrifine-extension/src/utils/api.js create mode 100644 agrifine-extension/src/utils/storage.js create mode 100644 agrifine-extension/tailwind.config.js create mode 100644 agrifine-extension/webpack/webpack.config.js diff --git a/agrifine-extension/.babelrc b/agrifine-extension/.babelrc new file mode 100644 index 0000000..7dc2569 --- /dev/null +++ b/agrifine-extension/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": [ + ["@babel/preset-env", { + "targets": { "chrome": "109" }, + "modules": false + }] + ] +} diff --git a/agrifine-extension/.gitignore b/agrifine-extension/.gitignore new file mode 100644 index 0000000..a567f9e --- /dev/null +++ b/agrifine-extension/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +*.map diff --git a/agrifine-extension/manifest.json b/agrifine-extension/manifest.json new file mode 100644 index 0000000..a24c3d3 --- /dev/null +++ b/agrifine-extension/manifest.json @@ -0,0 +1,45 @@ +{ + "manifest_version": 3, + "name": "Agrifine", + "version": "0.1.0", + "description": "Farm data dashboard — reading list, data ingestion, field profiles, and AI-powered insights.", + "permissions": [ + "storage", + "sidePanel", + "activeTab", + "scripting", + "tabs" + ], + "host_permissions": [ + "" + ], + "background": { + "service_worker": "dist/background.js", + "type": "module" + }, + "content_scripts": [ + { + "matches": [""], + "js": ["dist/content.js"], + "run_at": "document_idle" + } + ], + "side_panel": { + "default_path": "dist/sidebar.html" + }, + "action": { + "default_title": "Open Agrifine", + "default_icon": { + "16": "icons/icon16.png", + "32": "icons/icon32.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } + }, + "icons": { + "16": "icons/icon16.png", + "32": "icons/icon32.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } +} diff --git a/agrifine-extension/package-lock.json b/agrifine-extension/package-lock.json new file mode 100644 index 0000000..1bc27de --- /dev/null +++ b/agrifine-extension/package-lock.json @@ -0,0 +1,5282 @@ +{ + "name": "agrifine-extension", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "agrifine-extension", + "version": "0.1.0", + "dependencies": { + "papaparse": "^5.4.1", + "pdfjs-dist": "^4.2.67", + "xlsx": "^0.18.5" + }, + "devDependencies": { + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "autoprefixer": "^10.4.19", + "babel-loader": "^9.1.3", + "copy-webpack-plugin": "^12.0.2", + "css-loader": "^7.1.2", + "mini-css-extract-plugin": "^2.9.0", + "postcss": "^8.4.38", + "postcss-loader": "^8.1.1", + "tailwindcss": "^3.4.3", + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz", + "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz", + "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-wrap-function": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz", + "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.29.7.tgz", + "integrity": "sha512-j8SrR0zLZrRsC09DlszEx8FpMiwukKffYXMK0d5LmOglO7vGG6sz/BR/20yHqWH+Lnn31JTt2PE3hIWNgM2J6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.29.7.tgz", + "integrity": "sha512-r8j8escF+U2FUHo0KOhPUdMzUO+jp9fInva6+ACVAF3Y97Ev+5iNZwiqTghmzNeWwDkOPlYuTcfb1vDaoZKmAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.29.7.tgz", + "integrity": "sha512-GE1TFSiuFeGsCxmYXZl8HwoPrVlwe4rHPFE8weieGKZqnDORK+Ar3vgWMgW+AOxQ6/2TgLSKx9p6W7O4rC6qgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.7.tgz", + "integrity": "sha512-oBNVCvnO5tND+xSopWvV8WNGfpTfgP4Zr/YXXSj8zfmcPktp5Ku/aZlsIowgSD4fjmgHn6sGmB9APVsU5zOdhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.29.7.tgz", + "integrity": "sha512-QQt9qKHZ2sg/kivaLr7lnQr8HVrQDdBNSfCsTjiDxRuX/K5ORyKq+Bu8Xr0cDE3Dfkv0cw28Ve0EKyKMvulkOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-transform-optional-chaining": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.29.7.tgz", + "integrity": "sha512-pn6QacGLgvCcwc+syUhKE/qSjV2D1IHDB84RNxWYSt1mW3K/SCtjinZ2p0cETJxAWBjPy3K/1lHwG5BjjPxNlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.29.7.tgz", + "integrity": "sha512-/An1OCBN93thpBAGyfsK2pcf0jvju1SAtKkL2Ny++B5Sy6sqgzXDQH1cZxWbF96Wuk+bn41MDA9bLd4VVAw6rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.29.7.tgz", + "integrity": "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz", + "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz", + "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.29.7.tgz", + "integrity": "sha512-cUSmjh72N+rN4PrkFlN1dJwNCwjVp5d38/CQrEsFggkD10UiFlBFgdH3tv5dNsLuHY+3S8db2xCHjhZcv5WgvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz", + "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.29.7.tgz", + "integrity": "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz", + "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz", + "integrity": "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.29.7.tgz", + "integrity": "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/template": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz", + "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.29.7.tgz", + "integrity": "sha512-3qc18hsD2RdZiyJNDNc7HQpv6xbncwh8FYtxNFFzclSyh/trPD9KkVR9BDECUjDLvb7yJVF15GfYUuC+LMkkiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.29.7.tgz", + "integrity": "sha512-6IvRRriEMqnBwD6chtxdLpMYCHWEzN+oL5cyQtjykya19UgzbmKhxmhZgKC/LHxS2nYr9Q/qYPZ5Lr6jOL9+yQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-2wiIyo2BjtgU7HufSeDnL9L2O7zr8jmhFKuSr65VpRkUiRKRNpb0mdlk56+XPPKoIrfHqzbMuglDvZun0RISsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.29.7.tgz", + "integrity": "sha512-giOlEm/EFjfjr+te9NsdjkUo2v4f8rS/SXPumRVHAtbNcyNlvtREkU1dZzaIDclNpnaVhlCqRdFKhJBjBikzLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.29.7.tgz", + "integrity": "sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.29.7.tgz", + "integrity": "sha512-zFpMOTLZBdW5LfObqcSbL6kefg4R4eLdmvS0wbN9M6D5Mym/sKm9toOoWyVOa+xDjvCnuWcHls2YonXwHvH3CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", + "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz", + "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.29.7.tgz", + "integrity": "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.29.7.tgz", + "integrity": "sha512-RRnE2+eon1rJAq8MnoF1b5kTpY1vU88twHcvcKMrsqP/jxIRqDVs9iJB5fqPuqyeFAW0wJo4MlUIPpQCq/aRsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.29.7.tgz", + "integrity": "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz", + "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.29.7.tgz", + "integrity": "sha512-hl1kwFZCCiDyfH25Xmco9jTrkPgnS9pmOzSG7W5I4SaGbLeqKv417hcU2RKmaxoPEgsoJh7ZPOrnPGq99bHoUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.29.7.tgz", + "integrity": "sha512-fxtQoH3m5ywUSIfaH0FGCzWu4McsYon5bD3K4XnskC7f+OyQMj7rsOMi4NvvmJ83WwBAg4UCe+ov4VZlqEvyew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz", + "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.7.tgz", + "integrity": "sha512-TM2ZcQLoG2/y4HODiStCo10DibYhWhGWAwVv+EQKmG/7GFl0N+AAmUiXOMKM+aiJ9XBJ9AHVZBvTzMnJ2sM3cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.29.7.tgz", + "integrity": "sha512-B4UkaTK3QpgCwJnrxKfMPKdo92CN7OKXAlpAAnM3UPu0Q0lCCk57ylA9AJbRy2v8dDKOPAAWcoR6CMyeoHwRCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.29.7.tgz", + "integrity": "sha512-fEo41GmsOUhOBlw8ioo6zvjX5Xc2Lqkzlyfqbpsk3eB6TReV18uhxZ0esfEokVbY2+PVJAQHNKxER6lGrzNd3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.29.7.tgz", + "integrity": "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.29.7.tgz", + "integrity": "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz", + "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.29.7.tgz", + "integrity": "sha512-Ea/diGcw0twB5IlZPO5sgET6fJsLJqPABqTuFWIR+iMPGPZJkATEIWx0wa+aEQ5UY1CBQyP/gkAiLEqn1vBiQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz", + "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.29.7.tgz", + "integrity": "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz", + "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz", + "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz", + "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.29.7.tgz", + "integrity": "sha512-bOMRLQuI0A5ZqHq3OWJ89/rXpJ/NJrbVhXiP4zwPGMs6kpcVsuTUNjwoE30K0Qm3mf48a/TnRYYD6vPNqcg6jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.7.tgz", + "integrity": "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.29.7.tgz", + "integrity": "sha512-mB5Fs0VWrJ42ZCmc8114v60qetdaUVNkj9PmSZRmanCZM3S9hm0CFRLjRmYIsuXav14l2jvZ+4T8iiCGnhj3nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.29.7.tgz", + "integrity": "sha512-5+YhdpVgmfSmwZyLMftfaiffLRMHjzIRHFHHLdibcSyJm2pasMrKHrO3Ptrt2DRshjvpgjEJJ1zVW14WPq/6QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.29.7.tgz", + "integrity": "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.29.7.tgz", + "integrity": "sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.29.7.tgz", + "integrity": "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.29.7.tgz", + "integrity": "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.29.7.tgz", + "integrity": "sha512-223mNGoTkBiTEWFoK+Q6Go3tueMRclO8vxxxxquNCYuNI4jWOofFKJRRDu6SDrB8Sgo1UEGW9T4GAQ8ZyRso1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.29.7.tgz", + "integrity": "sha512-jCfXxSjf94lf4E0hKE0AByxF6F3/pVFqRdUUNkDJhsY0m1ZKjnN6ZYyMeHNpzflxb/0q5b7t3p+BE+SLF1WOtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.29.7.tgz", + "integrity": "sha512-OgZ+zoAJgZLUCunsTRQ5LAjOywDv5zzZ2/hQ5aMw1pGXyY2rtE8/chXYUmu3AlVHKpm10KEdG9aMwbI/K76ZGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.29.7.tgz", + "integrity": "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.29.7.tgz", + "integrity": "sha512-BLOhLht9DOJwIxlmp91wHvkXv1lguuHS3/FwUO8HL1H0u8s4hR1gASVFyilu9iGtcTRYqjTZmlsFFeQletntEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.7.tgz", + "integrity": "sha512-GYzX36n1nsciIb0uyH0GHwxwtNwPQIcpxSeiVLDtG/B7jB5xXgchnmL1f/jCX5o+pwnaDBtO60ONSJhEBJfxYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.29.7", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.29.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.29.7", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.29.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.29.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.29.7", + "@babel/plugin-syntax-import-attributes": "^7.29.7", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.29.7", + "@babel/plugin-transform-async-generator-functions": "^7.29.7", + "@babel/plugin-transform-async-to-generator": "^7.29.7", + "@babel/plugin-transform-block-scoped-functions": "^7.29.7", + "@babel/plugin-transform-block-scoping": "^7.29.7", + "@babel/plugin-transform-class-properties": "^7.29.7", + "@babel/plugin-transform-class-static-block": "^7.29.7", + "@babel/plugin-transform-classes": "^7.29.7", + "@babel/plugin-transform-computed-properties": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-dotall-regex": "^7.29.7", + "@babel/plugin-transform-duplicate-keys": "^7.29.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.7", + "@babel/plugin-transform-dynamic-import": "^7.29.7", + "@babel/plugin-transform-explicit-resource-management": "^7.29.7", + "@babel/plugin-transform-exponentiation-operator": "^7.29.7", + "@babel/plugin-transform-export-namespace-from": "^7.29.7", + "@babel/plugin-transform-for-of": "^7.29.7", + "@babel/plugin-transform-function-name": "^7.29.7", + "@babel/plugin-transform-json-strings": "^7.29.7", + "@babel/plugin-transform-literals": "^7.29.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.29.7", + "@babel/plugin-transform-member-expression-literals": "^7.29.7", + "@babel/plugin-transform-modules-amd": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-modules-systemjs": "^7.29.7", + "@babel/plugin-transform-modules-umd": "^7.29.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.7", + "@babel/plugin-transform-new-target": "^7.29.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.29.7", + "@babel/plugin-transform-numeric-separator": "^7.29.7", + "@babel/plugin-transform-object-rest-spread": "^7.29.7", + "@babel/plugin-transform-object-super": "^7.29.7", + "@babel/plugin-transform-optional-catch-binding": "^7.29.7", + "@babel/plugin-transform-optional-chaining": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/plugin-transform-private-methods": "^7.29.7", + "@babel/plugin-transform-private-property-in-object": "^7.29.7", + "@babel/plugin-transform-property-literals": "^7.29.7", + "@babel/plugin-transform-regenerator": "^7.29.7", + "@babel/plugin-transform-regexp-modifiers": "^7.29.7", + "@babel/plugin-transform-reserved-words": "^7.29.7", + "@babel/plugin-transform-shorthand-properties": "^7.29.7", + "@babel/plugin-transform-spread": "^7.29.7", + "@babel/plugin-transform-sticky-regex": "^7.29.7", + "@babel/plugin-transform-template-literals": "^7.29.7", + "@babel/plugin-transform-typeof-symbol": "^7.29.7", + "@babel/plugin-transform-unicode-escapes": "^7.29.7", + "@babel/plugin-transform-unicode-property-regex": "^7.29.7", + "@babel/plugin-transform-unicode-regex": "^7.29.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.29.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/canvas": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.100.tgz", + "integrity": "sha512-xglYA6q3XO5P3BNJYxVZ1IV7DLVjp1Py6nwag88YntrS+3vKHyYcMqXVS4ZztJmwz2uGvz1FWhI/4LgbR5uQDA==", + "license": "MIT", + "optional": true, + "workspaces": [ + "e2e/*" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "0.1.100", + "@napi-rs/canvas-darwin-arm64": "0.1.100", + "@napi-rs/canvas-darwin-x64": "0.1.100", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.100", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.100", + "@napi-rs/canvas-linux-arm64-musl": "0.1.100", + "@napi-rs/canvas-linux-riscv64-gnu": "0.1.100", + "@napi-rs/canvas-linux-x64-gnu": "0.1.100", + "@napi-rs/canvas-linux-x64-musl": "0.1.100", + "@napi-rs/canvas-win32-arm64-msvc": "0.1.100", + "@napi-rs/canvas-win32-x64-msvc": "0.1.100" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.100.tgz", + "integrity": "sha512-hjhCKhntPv9+t4ckHymdx0phYNcVW+GKQR6Lzw2zE+pOVjOplSmtx9nNNknTjbEDLcuLZqA1y8ufKg1XfgftzQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.100.tgz", + "integrity": "sha512-2PcswRaC7Ly645DGt88///zuFDhJxJYdKAs1uU3mfk1atYkXufgcgLfBpk6Tm12nCQBaNt1wpybuPZ4qOhTo8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.100.tgz", + "integrity": "sha512-ePNZtj7pNIva/siZMg+HmbeozkIjqUIYdoymH8HaA3qK7LfzFN4WMBM8G6HQ9ZC+H3+Dnn5pqtiXpgLykaPOhw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.100.tgz", + "integrity": "sha512-d5cDB48oWFGU8/XPhUOFAlySgb/VAu7D+s8fi55K1Pcfg8aPplHWqMgibhVLU8ky7Pyg/fuiVLz4Nf3JrSTuUA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.100.tgz", + "integrity": "sha512-rDxgxRu69RvDlX/bh9o22DxLsGr8EqsNgotL9+RwQE1S0b0cqeatqsw6aW45mukm0B42DIAaAacKaYQ8cqS1nw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.100.tgz", + "integrity": "sha512-K3mDW66N+xT2/V439u1alFANiBUjdEx2gLiNYnCmUsva5jZMxWTjafBYwTzYK+EMFMHrUoabuU+T1BIP5CgbYQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-riscv64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.100.tgz", + "integrity": "sha512-mooqUBTIsccZpnoQC4NgrC1v6C1vof39etLNMnBwCY+p0gajWJvAHLGQ6g/gGyS5YrpDW+GefSN4+Cvcr08UWw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.100.tgz", + "integrity": "sha512-1eCvkDCazm7FFhsT7DfGOdSaHgZVK3bt/dSBl5EWHOWmnz+I7j8tPseJqqD81NF+MH21jKUK4wQSDjN0mdhnTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.100.tgz", + "integrity": "sha512-20arT6lnI19S68qNlii73TSEDbECNgzMz2EpldC1V3mZFuRkeujXkcebRk0LRJe9SEUAooYiLokfMViY8IX7yA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-arm64-msvc": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.100.tgz", + "integrity": "sha512-DZFFT1wIAg37LJw37yhMRFfjATd3vTQzjZ1Yki8u2vhO6Hi5VE6BVaGQ1aaDu7xb4iMErz+9EOwjpS7xcxFeBw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.100.tgz", + "integrity": "sha512-MyT1j3mHC2+Lu4pBi9mKyMJhtP6U7k7EldY7sj/uS5gJA65gTXt8MefJQXLJo5d/vZbuWmfxzkEUNc/urV3pHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.0.1.tgz", + "integrity": "sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/autoprefixer": { + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz", + "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.4", + "caniuse-lite": "^1.0.30001799", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.40", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.40.tgz", + "integrity": "sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz", + "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.38", + "caniuse-lite": "^1.0.30001799", + "electron-to-chromium": "^1.5.376", + "node-releases": "^2.0.48", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001799", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", + "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true, + "license": "ISC" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz", + "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.4.tgz", + "integrity": "sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.40", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.6.3" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-loader/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.380", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.380.tgz", + "integrity": "sha512-W6d5AbuEoRayO447cqrg6lKJIlscgRnnxOZl/08kfV71BQDoEBC7Wwis68z87LjyK6f4kWyTaubuDbhHKrZkbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.24.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.1.tgz", + "integrity": "sha512-7DdUaTjmNwMcH2gLr1qycesKII3BK4RLy/mdAb7x10Lq7bR4aNKHt1BR1ZALSv0rPM/hF5wYF0PhGop/rJm8vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", + "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.2.tgz", + "integrity": "sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimizer-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/papaparse": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.4.tgz", + "integrity": "sha512-SwzWD9gl/ElwYLCI0nUja1mFJzjq2D8ziShfNBa7zCHzkOozeOGDwHWQ+tvCzEZcewecWZ5U7kUopDnG+DFYEQ==", + "license": "MIT" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pdfjs-dist": { + "version": "4.10.38", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.10.38.tgz", + "integrity": "sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "@napi-rs/canvas": "^0.1.65" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-loader": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.2.1.tgz", + "integrity": "sha512-k98jtRzthjj3f76MYTs9JTpRqV1RaaMhEU0Lpw9OTmQZQdppg4B30VZ74BojuBHt3F4KyubHJoXCMUeM8Bqeow==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^2.5.1", + "semver": "^7.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-loader/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz", + "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "license": "Apache-2.0", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", + "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/watchpack": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.108.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.1.tgz", + "integrity": "sha512-UUCihHQK3O7483Woa0SulNLDeAiOhHI2PN2PAPU4fVWJqbzhv04EJ8FaWtB9WWh3i8fRt28543U7VfuJTOrpgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.22.2", + "es-module-lexer": "^2.1.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "graceful-fs": "^4.2.11", + "loader-runner": "^4.3.2", + "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.6.1", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "watchpack": "^2.5.2", + "webpack-sources": "^3.5.0" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz", + "integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/agrifine-extension/package.json b/agrifine-extension/package.json new file mode 100644 index 0000000..a33d9c5 --- /dev/null +++ b/agrifine-extension/package.json @@ -0,0 +1,30 @@ +{ + "name": "agrifine-extension", + "version": "0.1.0", + "description": "Browser extension farm data dashboard", + "private": true, + "scripts": { + "build": "webpack --config webpack/webpack.config.js", + "watch": "webpack --config webpack/webpack.config.js --watch", + "build:prod": "NODE_ENV=production webpack --config webpack/webpack.config.js" + }, + "devDependencies": { + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "autoprefixer": "^10.4.19", + "babel-loader": "^9.1.3", + "copy-webpack-plugin": "^12.0.2", + "css-loader": "^7.1.2", + "mini-css-extract-plugin": "^2.9.0", + "postcss": "^8.4.38", + "postcss-loader": "^8.1.1", + "tailwindcss": "^3.4.3", + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4" + }, + "dependencies": { + "papaparse": "^5.4.1", + "pdfjs-dist": "^4.2.67", + "xlsx": "^0.18.5" + } +} diff --git a/agrifine-extension/postcss.config.js b/agrifine-extension/postcss.config.js new file mode 100644 index 0000000..12a703d --- /dev/null +++ b/agrifine-extension/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/agrifine-extension/public/icons/icon128.png b/agrifine-extension/public/icons/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..f05b9b66c0608aa2680d833127f8c8b61228276b GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1SEZ8zRdwrKRsO>Ln`LHz39lxpultBz)T0e zdlUM4Y^yw3O?Fzo&)OJi-@(q{V9mgAi;>|1A45YK1H%?(h6S<=3~w12GKQ{{-7}?T VUW1NgMPMK>c)I$ztaD0e0ssl)OE~}l literal 0 HcmV?d00001 diff --git a/agrifine-extension/public/icons/icon16.png b/agrifine-extension/public/icons/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..61470ed02ac77f35ea53559dab5838901dc9941e GIT binary patch literal 79 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|VxBIJAr*6y1#&m2avJtzNnACk bF=b$=y?=>uo!+7^Kotz0u6{1-oD!M=1= literal 0 HcmV?d00001 diff --git a/agrifine-extension/public/icons/icon32.png b/agrifine-extension/public/icons/icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..3be3c78b46871f3c34d56bd7c13de60620357f36 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1SJ1Ryj={Wv^-rLLn`JZ3*>HCs+lCQHQ`EA iAh(+?I-{+Nl|iiAL+|MMv)h5X7(8A5T-G@yGywp+VH~9Z literal 0 HcmV?d00001 diff --git a/agrifine-extension/public/icons/icon48.png b/agrifine-extension/public/icons/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..61d2f0fd5c01f419bb630a3d13dbb3ae213672ff GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@HmdKI;Vst00ed?H~;_u literal 0 HcmV?d00001 diff --git a/agrifine-extension/src/background/index.js b/agrifine-extension/src/background/index.js new file mode 100644 index 0000000..76e83d2 --- /dev/null +++ b/agrifine-extension/src/background/index.js @@ -0,0 +1,42 @@ +import { sessionGet, sessionSet, KEYS } from '../utils/storage.js'; +import { fetchAnthropic } from '../utils/api.js'; + +// Open the side panel when the action icon is clicked +chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true }).catch(console.error); + +// ── Message router ──────────────────────────────────────────────────────────── +chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { + switch (message.type) { + case 'ANTHROPIC_REQUEST': + handleAnthropicRequest(message.payload).then(sendResponse).catch((err) => + sendResponse({ error: err.message }) + ); + return true; // keep channel open for async response + + case 'SET_API_KEY': + sessionSet(KEYS.API_KEY, message.payload.key) + .then(() => sendResponse({ ok: true })) + .catch((err) => sendResponse({ error: err.message })); + return true; + + case 'GET_PAGE_CONTENT': + // Content script relays page text; background stores it temporarily + sendResponse({ ok: true }); + return false; + + default: + return false; + } +}); + +async function handleAnthropicRequest({ system, userMessage, maxTokens }) { + const text = await fetchAnthropic({ system, userMessage, maxTokens }); + return { text }; +} + +// Keep service worker alive during active side-panel sessions +chrome.runtime.onConnect.addListener((port) => { + if (port.name === 'keepalive') { + port.onDisconnect.addListener(() => {}); + } +}); diff --git a/agrifine-extension/src/content/index.js b/agrifine-extension/src/content/index.js new file mode 100644 index 0000000..a9fb43b --- /dev/null +++ b/agrifine-extension/src/content/index.js @@ -0,0 +1,25 @@ +// Content script — minimal surface. Relays page metadata to background on request. + +chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { + if (message.type === 'GET_PAGE_INFO') { + sendResponse({ + url: window.location.href, + title: document.title, + text: extractMainText(), + }); + } +}); + +function extractMainText() { + const selectors = ['article', 'main', '[role="main"]', '.content', '#content', 'body']; + for (const sel of selectors) { + const el = document.querySelector(sel); + if (el) { + // Strip scripts and styles, return first 8000 chars + const clone = el.cloneNode(true); + clone.querySelectorAll('script,style,nav,header,footer,aside').forEach((n) => n.remove()); + return clone.innerText.trim().slice(0, 8000); + } + } + return document.body?.innerText?.slice(0, 8000) ?? ''; +} diff --git a/agrifine-extension/src/modules/carbon-estimator/index.js b/agrifine-extension/src/modules/carbon-estimator/index.js new file mode 100644 index 0000000..097e456 --- /dev/null +++ b/agrifine-extension/src/modules/carbon-estimator/index.js @@ -0,0 +1,56 @@ +// Carbon Estimator — Phase 7 stub +// Full implementation: soil organic matter, Scope 3 emissions, USDA NRCS eFOTG API, PDF export + +export function CarbonEstimatorModule() { + return { + id: 'carbon-estimator', + label: 'Carbon', + + render(container) { + container.innerHTML = ` +
Carbon Estimator
+ +
+ +
+
+
🌿
+
+

Carbon Estimator

+ Coming in Phase 7 +
+
+

+ The Carbon Estimator will calculate your operation's Scope 3 emissions profile + and estimate carbon sequestration potential per field using USDA emission factors. +

+
+ + +
+ ${[ + ['📊', 'Scope 3 Emissions Profile', 'Based on fuel use, crop type, and animal operations'], + ['🌱', 'Sequestration Potential', 'Per-field estimate using soil type and land cover'], + ['🏛️', 'USDA Program Matcher', 'Match your practices to EQIP, CSP, and CRP programs'], + ['📄', 'Carbon Credit PDF', 'Downloadable eligibility summary for carbon marketplaces'], + ['📡', 'Marketplace Handoff', 'Send your credit profile to Nori, Pachama, or others (Phase 8)'], + ].map(([icon, title, desc]) => ` +
+ ${icon} +
+

${title}

+

${desc}

+
+
`).join('')} +
+ + +
+

Your field profile data is already being collected.

+

Carbon estimates will populate automatically when Phase 7 lands.

+
+
+ `; + }, + }; +} diff --git a/agrifine-extension/src/modules/dashboard/index.js b/agrifine-extension/src/modules/dashboard/index.js new file mode 100644 index 0000000..390d7db --- /dev/null +++ b/agrifine-extension/src/modules/dashboard/index.js @@ -0,0 +1,183 @@ +import { + getReadingList, getIngestedFiles, getFieldProfiles, buildContextBundle, +} from '../../utils/storage.js'; +import { callAnthropic } from '../../utils/api.js'; + +const CATEGORIES = ['all', 'land', 'equipment', 'harvest', 'finance', 'carbon', 'weather']; + +function tagCategory(item) { + const tags = item.tags ?? []; + const data = JSON.stringify(item.structuredData ?? {}).toLowerCase(); + if (tags.includes('land') || data.includes('field') || data.includes('acre')) return 'land'; + if (tags.includes('equipment') || data.includes('equipment')) return 'equipment'; + if (data.includes('harvest') || data.includes('yield')) return 'harvest'; + if (tags.includes('finance') || data.includes('financ') || data.includes('expense')) return 'finance'; + if (tags.includes('carbon') || data.includes('carbon')) return 'carbon'; + if (tags.includes('weather') || data.includes('weather')) return 'weather'; + return 'other'; +} + +export function DashboardModule() { + let activeCategory = 'all'; + let keyword = ''; + let aiAnswer = ''; + let aiLoading = false; + + return { + id: 'dashboard', + label: 'Dashboard', + + async render(container) { + container.innerHTML = ` +
Farm Dashboard
+ + +
+
+ + +
+ +
+ + +
+
+ ${CATEGORIES.map((c) => ` + `).join('')} +
+ +
+ + +
+ `; + + this._bindEvents(container); + await this._renderDashboard(container); + }, + + _bindEvents(container) { + container.querySelectorAll('.cat-btn').forEach((btn) => { + btn.addEventListener('click', async () => { + activeCategory = btn.dataset.cat; + container.querySelectorAll('.cat-btn').forEach((b) => { + b.className = `cat-btn text-xs px-2.5 py-1 rounded-full border transition border-gray-300 text-gray-600 hover:border-agri-400`; + }); + btn.className = `cat-btn text-xs px-2.5 py-1 rounded-full border transition bg-agri-600 text-white border-agri-600`; + await this._renderDashboard(container); + }); + }); + + container.querySelector('#dash-search').addEventListener('input', async (e) => { + keyword = e.target.value.toLowerCase(); + await this._renderDashboard(container); + }); + + container.querySelector('#dash-ai-btn').addEventListener('click', () => this._runAIQuery(container)); + container.querySelector('#dash-ai-input').addEventListener('keydown', (e) => { + if (e.key === 'Enter') this._runAIQuery(container); + }); + }, + + async _runAIQuery(container) { + if (aiLoading) return; + const input = container.querySelector('#dash-ai-input'); + const question = input.value.trim(); + if (!question) return; + + aiLoading = true; + const answerEl = container.querySelector('#dash-ai-answer'); + answerEl.classList.remove('hidden'); + answerEl.innerHTML = ' Thinking…'; + + try { + const contextBundle = await buildContextBundle(); + const [readingList, ingestedFiles, fieldProfiles] = await Promise.all([ + getReadingList(), getIngestedFiles(), getFieldProfiles(), + ]); + + const dataContext = [ + contextBundle, + '', + 'INGESTED FILES:', + ingestedFiles.map((f) => `${f.filename}: ${JSON.stringify(f.structuredData ?? {}).slice(0, 400)}`).join('\n') || '(none)', + ].join('\n'); + + const answer = await callAnthropic({ + system: `You are a farm management AI assistant with access to this farm's data:\n\n${dataContext}`, + userMessage: question, + maxTokens: 512, + }); + + answerEl.innerHTML = `

Answer

${answer}`; + } catch (err) { + answerEl.textContent = `Error: ${err.message}`; + } finally { + aiLoading = false; + } + }, + + async _renderDashboard(container) { + const [readingList, ingestedFiles, fieldProfiles] = await Promise.all([ + getReadingList(), getIngestedFiles(), getFieldProfiles(), + ]); + + const allItems = [ + ...readingList.map((i) => ({ ...i, _source: 'reading', _category: tagCategory(i) })), + ...ingestedFiles.map((f) => ({ ...f, _source: 'file', _category: tagCategory(f) })), + ...fieldProfiles.map((p) => ({ + ...p, _source: 'field', _category: 'land', tags: ['land'], + title: `Field: ${p.name}`, summary: `${p.acres ?? '?'} ac — ${p.soilType ?? 'unknown soil'}`, + })), + ]; + + const filtered = allItems.filter((item) => { + const catMatch = activeCategory === 'all' || item._category === activeCategory; + const kwMatch = !keyword || + (item.title ?? '').toLowerCase().includes(keyword) || + (item.summary ?? '').toLowerCase().includes(keyword) || + (item.filename ?? '').toLowerCase().includes(keyword) || + (item.name ?? '').toLowerCase().includes(keyword); + return catMatch && kwMatch; + }); + + const listEl = container.querySelector('#dash-list'); + + if (filtered.length === 0) { + listEl.innerHTML = `

No data matches your filters.

`; + return; + } + + listEl.innerHTML = filtered.map((item) => { + const sourceIcon = { reading: '📖', file: '📄', field: '🌱' }[item._source] ?? '•'; + const title = item.title ?? item.filename ?? item.name ?? 'Untitled'; + const sub = item.summary ?? item.preview?.slice(0, 120) ?? ''; + const date = item.savedAt ?? item.uploadedAt ?? item.createdAt ?? ''; + return ` +
+
+ ${sourceIcon} +
+

${title}

+ ${sub ? `

${sub}

` : ''} +
+ ${item._category} + ${(item.tags ?? []).filter((t) => t !== item._category).slice(0, 2).map((t) => `${t}`).join('')} + ${date ? `${new Date(date).toLocaleDateString()}` : ''} +
+
+
+
`; + }).join(''); + }, + }; +} diff --git a/agrifine-extension/src/modules/data-ingest/index.js b/agrifine-extension/src/modules/data-ingest/index.js new file mode 100644 index 0000000..dce5edb --- /dev/null +++ b/agrifine-extension/src/modules/data-ingest/index.js @@ -0,0 +1,234 @@ +import { getIngestedFiles, saveIngestedFile, deleteIngestedFile } from '../../utils/storage.js'; +import { callAnthropic } from '../../utils/api.js'; + +const SUPPORTED_TYPES = { + 'text/csv': 'CSV', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel', + 'application/vnd.ms-excel': 'Excel', + 'application/pdf': 'PDF', +}; + +export function DataIngestModule() { + return { + id: 'data-ingest', + label: 'Data Ingest', + + async render(container) { + container.innerHTML = ` +
Data Ingest
+ + +
+
+ + + +

Drop CSV, Excel, or PDF here

+

or click to select a file

+ +
+
+
+ + +
+ `; + + this._bindEvents(container); + await this._renderFileList(container); + }, + + _bindEvents(container) { + const dropZone = container.querySelector('#drop-zone'); + const fileInput = container.querySelector('#file-input'); + + dropZone.addEventListener('click', () => fileInput.click()); + + dropZone.addEventListener('dragover', (e) => { + e.preventDefault(); + dropZone.classList.add('border-agri-600', 'bg-agri-50'); + }); + + dropZone.addEventListener('dragleave', () => { + dropZone.classList.remove('border-agri-600', 'bg-agri-50'); + }); + + dropZone.addEventListener('drop', (e) => { + e.preventDefault(); + dropZone.classList.remove('border-agri-600', 'bg-agri-50'); + const file = e.dataTransfer.files[0]; + if (file) this._processFile(file, container); + }); + + fileInput.addEventListener('change', () => { + if (fileInput.files[0]) this._processFile(fileInput.files[0], container); + }); + }, + + async _processFile(file, container) { + const status = container.querySelector('#ingest-status'); + const typeName = SUPPORTED_TYPES[file.type] ?? (file.name.endsWith('.csv') ? 'CSV' : null); + + if (!typeName) { + status.textContent = 'Unsupported file type.'; + return; + } + + status.textContent = `Parsing ${typeName}…`; + let extractedText = ''; + + try { + if (typeName === 'CSV') { + extractedText = await this._parseCSV(file); + } else if (typeName === 'Excel') { + extractedText = await this._parseExcel(file); + } else if (typeName === 'PDF') { + extractedText = await this._parsePDF(file); + } + } catch (err) { + status.textContent = `Parse error: ${err.message}`; + return; + } + + status.textContent = 'Extracting structured data with AI…'; + let structuredData = null; + + try { + const raw = await callAnthropic({ + system: 'You are an agricultural data analyst. Extract and return structured JSON from this document. Identify: operation type, field names, dates, quantities, equipment, crop types, financial figures, and any carbon or emissions data. Return only valid JSON.', + userMessage: extractedText.slice(0, 6000), + maxTokens: 1024, + }); + structuredData = JSON.parse(raw); + } catch (_) { + structuredData = { raw_preview: extractedText.slice(0, 500), parse_error: 'AI extraction unavailable' }; + } + + const record = { + id: `file_${Date.now()}`, + filename: file.name, + type: typeName, + uploadedAt: new Date().toISOString(), + structuredData, + preview: Object.entries(structuredData ?? {}) + .filter(([k]) => k !== 'raw_preview') + .slice(0, 5) + .map(([k, v]) => `${k}: ${JSON.stringify(v).slice(0, 80)}`) + .join('\n'), + }; + + await saveIngestedFile(record); + status.textContent = 'File processed!'; + setTimeout(() => { status.textContent = ''; }, 2000); + await this._renderFileList(container); + }, + + _parseCSV(file) { + return new Promise((resolve, reject) => { + // PapaParse is loaded dynamically to keep the background bundle lean + import('papaparse').then(({ default: Papa }) => { + Papa.parse(file, { + complete: (results) => { + const rows = results.data.slice(0, 200); + resolve(rows.map((r) => r.join(',')).join('\n')); + }, + error: reject, + }); + }); + }); + }, + + _parseExcel(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = async (e) => { + try { + const { read, utils } = await import('xlsx'); + const wb = read(e.target.result, { type: 'array' }); + const lines = []; + wb.SheetNames.slice(0, 3).forEach((name) => { + const ws = wb.Sheets[name]; + lines.push(`Sheet: ${name}`); + lines.push(utils.sheet_to_csv(ws).split('\n').slice(0, 100).join('\n')); + }); + resolve(lines.join('\n')); + } catch (err) { + reject(err); + } + }; + reader.onerror = reject; + reader.readAsArrayBuffer(file); + }); + }, + + _parsePDF(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = async (e) => { + try { + const pdfjsLib = await import('pdfjs-dist'); + pdfjsLib.GlobalWorkerOptions.workerSrc = chrome.runtime.getURL('pdf.worker.js'); + const pdf = await pdfjsLib.getDocument({ data: e.target.result }).promise; + const pages = Math.min(pdf.numPages, 10); + const texts = []; + for (let i = 1; i <= pages; i++) { + const page = await pdf.getPage(i); + const content = await page.getTextContent(); + texts.push(content.items.map((s) => s.str).join(' ')); + } + resolve(texts.join('\n')); + } catch (err) { + reject(err); + } + }; + reader.onerror = reject; + reader.readAsArrayBuffer(file); + }); + }, + + async _renderFileList(container) { + const files = await getIngestedFiles(); + const listEl = container.querySelector('#file-list'); + + if (files.length === 0) { + listEl.innerHTML = ` +
+ + + +

No files ingested yet.

+

Upload a CSV, Excel, or PDF file above.

+
`; + return; + } + + listEl.innerHTML = files.map((f) => ` +
+
+
+ ${f.type} +

${f.filename}

+

${new Date(f.uploadedAt).toLocaleDateString()}

+
+ +
+ ${f.preview ? `
${f.preview}
` : ''} +
+ `).join(''); + + listEl.querySelectorAll('.file-delete-btn').forEach((btn) => { + btn.addEventListener('click', async () => { + await deleteIngestedFile(btn.dataset.id); + await this._renderFileList(container); + }); + }); + }, + }; +} diff --git a/agrifine-extension/src/modules/field-profile/index.js b/agrifine-extension/src/modules/field-profile/index.js new file mode 100644 index 0000000..646f650 --- /dev/null +++ b/agrifine-extension/src/modules/field-profile/index.js @@ -0,0 +1,179 @@ +import { getFieldProfiles, saveFieldProfile, deleteFieldProfile } from '../../utils/storage.js'; + +export function FieldProfileModule() { + let showForm = false; + let expandedId = null; + + return { + id: 'field-profile', + label: 'Field Profiles', + + async render(container) { + container.innerHTML = ` +
Field Profiles
+ +
+ +
+ + + + + +
+ `; + + this._bindEvents(container); + await this._renderList(container); + }, + + _bindEvents(container) { + container.querySelector('#fp-new-btn').addEventListener('click', () => { + showForm = !showForm; + container.querySelector('#fp-form').classList.toggle('hidden', !showForm); + }); + + container.querySelector('#fp-cancel-btn').addEventListener('click', () => { + showForm = false; + container.querySelector('#fp-form').classList.add('hidden'); + }); + + container.querySelector('#fp-save-btn').addEventListener('click', async () => { + const name = container.querySelector('#fp-name').value.trim(); + if (!name) return; + + const profile = { + id: `fp_${Date.now()}`, + name, + cluId: container.querySelector('#fp-clu').value.trim() || null, + acres: parseFloat(container.querySelector('#fp-acres').value) || null, + soilType: container.querySelector('#fp-soil').value.trim() || null, + coordinates: { + lat: parseFloat(container.querySelector('#fp-lat').value) || null, + lon: parseFloat(container.querySelector('#fp-lon').value) || null, + }, + notes: container.querySelector('#fp-notes').value.trim() || null, + cropHistory: [], // populated from ingested data in Phase 3 + harvestRecords: [], // populated from ingested CSVs in Phase 3 + weatherData: null, // Phase 6 + carbonPotential: null, // Phase 7 + createdAt: new Date().toISOString(), + }; + + await saveFieldProfile(profile); + showForm = false; + container.querySelector('#fp-form').classList.add('hidden'); + await this._renderList(container); + }); + }, + + async _renderList(container) { + const profiles = await getFieldProfiles(); + const listEl = container.querySelector('#fp-list'); + + if (profiles.length === 0) { + listEl.innerHTML = ` +
+ + + +

No field profiles yet.

+

Create a profile for each field in your operation.

+
`; + return; + } + + listEl.innerHTML = profiles.map((p) => ` +
+
+
+

${p.name}

+
+ ${p.acres ? `${p.acres} ac` : ''} + ${p.soilType ? `${p.soilType}` : ''} + ${p.cluId ? `CLU ${p.cluId}` : ''} +
+
+
+ + + + +
+
+ + +
+ ${p.coordinates?.lat ? `

📍 ${p.coordinates.lat.toFixed(4)}, ${p.coordinates.lon.toFixed(4)}

` : ''} + ${p.notes ? `

📝 ${p.notes}

` : ''} +

Weather data: Phase 6

+

Carbon potential: Phase 7

+

Added ${new Date(p.createdAt).toLocaleDateString()}

+
+
+ `).join(''); + + listEl.querySelectorAll('.agri-card').forEach((card) => { + card.addEventListener('click', async (e) => { + if (e.target.closest('.fp-delete-btn')) return; + const id = card.dataset.id; + expandedId = expandedId === id ? null : id; + await this._renderList(container); + }); + }); + + listEl.querySelectorAll('.fp-delete-btn').forEach((btn) => { + btn.addEventListener('click', async (e) => { + e.stopPropagation(); + await deleteFieldProfile(btn.dataset.id); + if (expandedId === btn.dataset.id) expandedId = null; + await this._renderList(container); + }); + }); + }, + }; +} diff --git a/agrifine-extension/src/modules/reading-list/index.js b/agrifine-extension/src/modules/reading-list/index.js new file mode 100644 index 0000000..8c3db7c --- /dev/null +++ b/agrifine-extension/src/modules/reading-list/index.js @@ -0,0 +1,154 @@ +import { getReadingList, saveReadingItem, deleteReadingItem } from '../../utils/storage.js'; +import { callAnthropic, AGRICULTURE_TAGS } from '../../utils/api.js'; + +export function ReadingListModule() { + let currentTag = 'all'; + + return { + id: 'reading-list', + label: 'Reading List', + + async render(container) { + container.innerHTML = ` +
Reading List
+ + +
+ +
+
+ + +
+ + ${AGRICULTURE_TAGS.map((t) => ``).join('')} +
+ + +
+ `; + + this._bindEvents(container); + await this._renderList(container); + }, + + _bindEvents(container) { + container.querySelector('#rl-save-btn').addEventListener('click', () => this._savePage(container)); + + container.querySelectorAll('.tag-filter-btn').forEach((btn) => { + btn.addEventListener('click', async () => { + currentTag = btn.dataset.tag; + container.querySelectorAll('.tag-filter-btn').forEach((b) => { + b.classList.remove('bg-agri-600', 'text-white'); + b.classList.add('bg-agri-100', 'text-agri-800'); + }); + btn.classList.add('bg-agri-600', 'text-white'); + btn.classList.remove('bg-agri-100', 'text-agri-800'); + await this._renderList(container); + }); + }); + }, + + async _savePage(container) { + const status = container.querySelector('#rl-save-status'); + status.textContent = 'Fetching page info…'; + + const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); + if (!tab) { + status.textContent = 'No active tab found.'; + return; + } + + let pageText = ''; + try { + const resp = await chrome.tabs.sendMessage(tab.id, { type: 'GET_PAGE_INFO' }); + pageText = resp?.text ?? ''; + } catch (_) { + pageText = ''; + } + + status.textContent = 'Summarising with AI…'; + let summary = ''; + let tags = []; + + try { + const rawResponse = await callAnthropic({ + system: 'You are an agricultural research assistant. Given web page text, return a JSON object with two fields: "summary" (2-3 sentence plain English summary focused on agricultural relevance) and "tags" (array of relevant tags from: agriculture, equipment, land, carbon, USDA, dairy, finance, weather). Return only valid JSON.', + userMessage: `Title: ${tab.title}\nURL: ${tab.url}\n\nContent:\n${pageText.slice(0, 4000)}`, + maxTokens: 256, + }); + + const parsed = JSON.parse(rawResponse); + summary = parsed.summary ?? ''; + tags = parsed.tags ?? []; + } catch (_) { + summary = '(AI summary unavailable)'; + tags = ['agriculture']; + } + + const item = { + id: `rl_${Date.now()}`, + url: tab.url, + title: tab.title, + savedAt: new Date().toISOString(), + summary, + tags, + }; + + await saveReadingItem(item); + status.textContent = 'Saved!'; + setTimeout(() => { status.textContent = ''; }, 2000); + await this._renderList(container); + }, + + async _renderList(container) { + const list = await getReadingList(); + const filtered = currentTag === 'all' ? list : list.filter((i) => i.tags?.includes(currentTag)); + const listEl = container.querySelector('#rl-list'); + + if (filtered.length === 0) { + listEl.innerHTML = ` +
+ + + +

No saved pages yet.

+

Browse to a page and click "Save current page".

+
`; + return; + } + + listEl.innerHTML = filtered.map((item) => ` +
+
+ ${item.title} + +
+ ${item.summary ? `

${item.summary}

` : ''} +
+ ${(item.tags ?? []).map((t) => `${t}`).join('')} +
+

${new Date(item.savedAt).toLocaleDateString()}

+
+ `).join(''); + + listEl.querySelectorAll('.rl-delete-btn').forEach((btn) => { + btn.addEventListener('click', async () => { + await deleteReadingItem(btn.dataset.id); + await this._renderList(container); + }); + }); + }, + }; +} diff --git a/agrifine-extension/src/sidebar/index.js b/agrifine-extension/src/sidebar/index.js new file mode 100644 index 0000000..72d1209 --- /dev/null +++ b/agrifine-extension/src/sidebar/index.js @@ -0,0 +1,90 @@ +import './sidebar.css'; +import { ReadingListModule } from '../modules/reading-list/index.js'; +import { DataIngestModule } from '../modules/data-ingest/index.js'; +import { FieldProfileModule } from '../modules/field-profile/index.js'; +import { DashboardModule } from '../modules/dashboard/index.js'; +import { CarbonEstimatorModule } from '../modules/carbon-estimator/index.js'; +import { sessionSet, sessionGet, KEYS } from '../utils/storage.js'; + +// ── Module registry ─────────────────────────────────────────────────────────── +const MODULES = [ + ReadingListModule(), + DataIngestModule(), + FieldProfileModule(), + DashboardModule(), + CarbonEstimatorModule(), +]; + +const moduleMap = Object.fromEntries(MODULES.map((m) => [m.id, m])); +let activeModuleId = 'reading-list'; + +// ── Tab navigation ──────────────────────────────────────────────────────────── +function setupTabs() { + document.querySelectorAll('.tab-btn').forEach((btn) => { + btn.addEventListener('click', () => activateTab(btn.dataset.tab)); + }); +} + +async function activateTab(id) { + if (!moduleMap[id]) return; + activeModuleId = id; + + document.querySelectorAll('.tab-btn').forEach((btn) => { + btn.classList.toggle('active-tab', btn.dataset.tab === id); + }); + + const main = document.getElementById('main-content'); + main.innerHTML = ''; + await moduleMap[id].render(main); +} + +// ── Settings panel ──────────────────────────────────────────────────────────── +function setupSettings() { + const btn = document.getElementById('btn-settings'); + const panel = document.getElementById('settings-panel'); + const saveBtn = document.getElementById('btn-save-key'); + const input = document.getElementById('api-key-input'); + const status = document.getElementById('api-key-status'); + + btn.addEventListener('click', async () => { + panel.classList.toggle('hidden'); + if (!panel.classList.contains('hidden')) { + const existing = await sessionGet(KEYS.API_KEY); + if (existing) { + input.value = ''; + input.placeholder = 'Key set — enter new key to replace'; + status.textContent = '✓ API key is active this session'; + } + } + }); + + saveBtn.addEventListener('click', async () => { + const key = input.value.trim(); + if (!key.startsWith('sk-ant-')) { + status.textContent = 'Key must start with sk-ant-'; + return; + } + await chrome.runtime.sendMessage({ type: 'SET_API_KEY', payload: { key } }); + input.value = ''; + input.placeholder = 'Key set — enter new key to replace'; + status.textContent = '✓ Saved for this session'; + }); +} + +// ── Keepalive port (prevents service worker from being killed) ──────────────── +function keepAlive() { + try { + const port = chrome.runtime.connect({ name: 'keepalive' }); + port.onDisconnect.addListener(() => { + setTimeout(keepAlive, 5000); + }); + } catch (_) {} +} + +// ── Init ────────────────────────────────────────────────────────────────────── +document.addEventListener('DOMContentLoaded', async () => { + setupTabs(); + setupSettings(); + keepAlive(); + await activateTab(activeModuleId); +}); diff --git a/agrifine-extension/src/sidebar/sidebar.css b/agrifine-extension/src/sidebar/sidebar.css new file mode 100644 index 0000000..a4b1429 --- /dev/null +++ b/agrifine-extension/src/sidebar/sidebar.css @@ -0,0 +1,60 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Active tab highlight */ +.tab-btn.active-tab { + @apply text-agri-700; +} + +.tab-btn.active-tab svg { + @apply stroke-agri-700; +} + +/* Card styles shared across modules */ +.agri-card { + @apply bg-white rounded-xl shadow-sm border border-gray-100 p-4 mb-3; +} + +.agri-card:hover { + @apply shadow-md; +} + +/* Tag pill */ +.tag-pill { + @apply inline-block text-xs px-2 py-0.5 rounded-full bg-agri-100 text-agri-800 font-medium mr-1 mb-1; +} + +/* Section heading */ +.section-heading { + @apply text-xs uppercase tracking-widest font-semibold text-gray-400 mb-2 px-4 pt-4; +} + +/* Empty state */ +.empty-state { + @apply flex flex-col items-center justify-center py-16 text-gray-400 text-sm text-center px-6; +} + +/* Spinner */ +.spinner { + @apply inline-block w-5 h-5 border-2 border-agri-300 border-t-agri-700 rounded-full animate-spin; +} + +/* Coming soon badge */ +.coming-soon { + @apply inline-block text-xs px-2 py-0.5 rounded-full bg-earth-100 text-earth-700 font-semibold; +} + +/* Scrollbar styling */ +::-webkit-scrollbar { + width: 4px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: #bbf7d0; + border-radius: 2px; +} diff --git a/agrifine-extension/src/sidebar/sidebar.html b/agrifine-extension/src/sidebar/sidebar.html new file mode 100644 index 0000000..db557ca --- /dev/null +++ b/agrifine-extension/src/sidebar/sidebar.html @@ -0,0 +1,94 @@ + + + + + + Agrifine + + + + + +
+
+ 🌾 Agrifine +
+ +
+ + + + + +
+ +
+ + + + + + + diff --git a/agrifine-extension/src/utils/api.js b/agrifine-extension/src/utils/api.js new file mode 100644 index 0000000..dc09b16 --- /dev/null +++ b/agrifine-extension/src/utils/api.js @@ -0,0 +1,66 @@ +import { sessionGet, KEYS } from './storage.js'; + +const ANTHROPIC_URL = 'https://api.anthropic.com/v1/messages'; +const MODEL = 'claude-sonnet-4-6'; + +/** + * Send a message to the Anthropic API via the background service worker. + * Content scripts and sidebar cannot call external APIs directly due to CSP, + * so all API calls are proxied through the background worker. + */ +export async function callAnthropic({ system, userMessage, maxTokens = 1024 }) { + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage( + { type: 'ANTHROPIC_REQUEST', payload: { system, userMessage, maxTokens } }, + (response) => { + if (chrome.runtime.lastError) { + reject(new Error(chrome.runtime.lastError.message)); + return; + } + if (response?.error) { + reject(new Error(response.error)); + return; + } + resolve(response?.text ?? ''); + } + ); + }); +} + +/** + * Direct fetch from background worker — keeps API key off content scripts. + */ +export async function fetchAnthropic({ system, userMessage, maxTokens = 1024 }) { + const apiKey = await sessionGet(KEYS.API_KEY); + if (!apiKey) throw new Error('No API key set. Open Agrifine settings to add your key.'); + + const body = { + model: MODEL, + max_tokens: maxTokens, + system, + messages: [{ role: 'user', content: userMessage }], + }; + + const res = await fetch(ANTHROPIC_URL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'x-api-key': apiKey, + 'anthropic-version': '2023-06-01', + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + const errText = await res.text(); + throw new Error(`Anthropic API error ${res.status}: ${errText}`); + } + + const data = await res.json(); + return data.content?.[0]?.text ?? ''; +} + +export const AGRICULTURE_TAGS = [ + 'agriculture', 'equipment', 'land', 'carbon', + 'USDA', 'dairy', 'finance', 'weather', +]; diff --git a/agrifine-extension/src/utils/storage.js b/agrifine-extension/src/utils/storage.js new file mode 100644 index 0000000..f5f6b95 --- /dev/null +++ b/agrifine-extension/src/utils/storage.js @@ -0,0 +1,136 @@ +/** + * Agrifine storage schema + * + * chrome.storage.local keys: + * agrifine_reading_list — Array + * agrifine_ingested_files — Array + * agrifine_field_profiles — Array + * agrifine_settings — Settings + * + * chrome.storage.session keys: + * agrifine_api_key — string (never persisted to local) + */ + +export const KEYS = { + READING_LIST: 'agrifine_reading_list', + INGESTED_FILES: 'agrifine_ingested_files', + FIELD_PROFILES: 'agrifine_field_profiles', + SETTINGS: 'agrifine_settings', + API_KEY: 'agrifine_api_key', // session only +}; + +// ── Generic helpers ────────────────────────────────────────────────────────── + +export async function localGet(key) { + return new Promise((resolve) => { + chrome.storage.local.get(key, (result) => resolve(result[key] ?? null)); + }); +} + +export async function localSet(key, value) { + return new Promise((resolve) => { + chrome.storage.local.set({ [key]: value }, resolve); + }); +} + +export async function sessionGet(key) { + return new Promise((resolve) => { + chrome.storage.session.get(key, (result) => resolve(result[key] ?? null)); + }); +} + +export async function sessionSet(key, value) { + return new Promise((resolve) => { + chrome.storage.session.set({ [key]: value }, resolve); + }); +} + +// ── Reading List ───────────────────────────────────────────────────────────── + +export async function getReadingList() { + return (await localGet(KEYS.READING_LIST)) ?? []; +} + +export async function saveReadingItem(item) { + const list = await getReadingList(); + list.unshift(item); + await localSet(KEYS.READING_LIST, list); +} + +export async function deleteReadingItem(id) { + const list = await getReadingList(); + await localSet(KEYS.READING_LIST, list.filter((i) => i.id !== id)); +} + +// ── Ingested Files ─────────────────────────────────────────────────────────── + +export async function getIngestedFiles() { + return (await localGet(KEYS.INGESTED_FILES)) ?? []; +} + +export async function saveIngestedFile(file) { + const files = await getIngestedFiles(); + files.unshift(file); + await localSet(KEYS.INGESTED_FILES, files); +} + +export async function deleteIngestedFile(id) { + const files = await getIngestedFiles(); + await localSet(KEYS.INGESTED_FILES, files.filter((f) => f.id !== id)); +} + +// ── Field Profiles ─────────────────────────────────────────────────────────── + +export async function getFieldProfiles() { + return (await localGet(KEYS.FIELD_PROFILES)) ?? []; +} + +export async function saveFieldProfile(profile) { + const profiles = await getFieldProfiles(); + const idx = profiles.findIndex((p) => p.id === profile.id); + if (idx >= 0) { + profiles[idx] = profile; + } else { + profiles.unshift(profile); + } + await localSet(KEYS.FIELD_PROFILES, profiles); +} + +export async function deleteFieldProfile(id) { + const profiles = await getFieldProfiles(); + await localSet(KEYS.FIELD_PROFILES, profiles.filter((p) => p.id !== id)); +} + +// ── Settings ───────────────────────────────────────────────────────────────── + +export async function getSettings() { + return (await localGet(KEYS.SETTINGS)) ?? { theme: 'light', defaultState: 'all' }; +} + +export async function saveSettings(patch) { + const current = await getSettings(); + await localSet(KEYS.SETTINGS, { ...current, ...patch }); +} + +// ── Context bundle (used as AI system context) ─────────────────────────────── + +export async function buildContextBundle() { + const list = await getReadingList(); + const profiles = await getFieldProfiles(); + + const readingCtx = list.slice(0, 20).map((item) => + `[${item.tags?.join(', ') ?? 'general'}] ${item.title}: ${item.summary ?? ''}` + ).join('\n'); + + const fieldCtx = profiles.map((p) => + `Field "${p.name}" (${p.acres ?? '?'} ac, ${p.soilType ?? 'unknown soil'}): ${p.notes ?? ''}` + ).join('\n'); + + return [ + 'USER READING LIST CONTEXT:', + readingCtx || '(none)', + '', + 'FIELD PROFILES:', + fieldCtx || '(none)', + ].join('\n'); +} diff --git a/agrifine-extension/tailwind.config.js b/agrifine-extension/tailwind.config.js new file mode 100644 index 0000000..9c7b05e --- /dev/null +++ b/agrifine-extension/tailwind.config.js @@ -0,0 +1,35 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ['./src/**/*.{js,html}'], + theme: { + extend: { + colors: { + agri: { + 50: '#f0fdf4', + 100: '#dcfce7', + 200: '#bbf7d0', + 300: '#86efac', + 400: '#4ade80', + 500: '#22c55e', + 600: '#16a34a', + 700: '#15803d', + 800: '#166534', + 900: '#14532d', + }, + earth: { + 50: '#fdf8f0', + 100: '#fbefd8', + 200: '#f5d9a8', + 300: '#eebb6a', + 400: '#e59b38', + 500: '#d97f1a', + 600: '#c06212', + 700: '#9f4b12', + 800: '#813c15', + 900: '#6a3214', + }, + }, + }, + }, + plugins: [], +}; diff --git a/agrifine-extension/webpack/webpack.config.js b/agrifine-extension/webpack/webpack.config.js new file mode 100644 index 0000000..0463964 --- /dev/null +++ b/agrifine-extension/webpack/webpack.config.js @@ -0,0 +1,57 @@ +const path = require('path'); +const CopyPlugin = require('copy-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + +const rootDir = path.resolve(__dirname, '..'); +const srcDir = path.join(rootDir, 'src'); +const distDir = path.join(rootDir, 'dist'); +const publicDir = path.join(rootDir, 'public'); + +module.exports = { + mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', + devtool: process.env.NODE_ENV === 'production' ? false : 'cheap-module-source-map', + entry: { + background: path.join(srcDir, 'background', 'index.js'), + content: path.join(srcDir, 'content', 'index.js'), + sidebar: path.join(srcDir, 'sidebar', 'index.js'), + }, + output: { + path: distDir, + filename: '[name].js', + clean: true, + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env'], + }, + }, + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'], + }, + ], + }, + plugins: [ + new MiniCssExtractPlugin({ filename: '[name].css' }), + new CopyPlugin({ + patterns: [ + { from: path.join(publicDir, 'icons'), to: path.join(distDir, 'icons') }, + { from: path.join(rootDir, 'manifest.json'), to: distDir }, + { from: path.join(srcDir, 'sidebar', 'sidebar.html'), to: path.join(distDir, 'sidebar.html') }, + ], + }), + ], + resolve: { + extensions: ['.js'], + alias: { + '@': srcDir, + }, + }, +}; From 86775eacbd6a9d6f018734e38534820d8b3ae99c Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 03:50:57 +0000 Subject: [PATCH 02/12] fix: correct manifest paths for dist/ load context --- agrifine-extension/manifest.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agrifine-extension/manifest.json b/agrifine-extension/manifest.json index a24c3d3..54b3235 100644 --- a/agrifine-extension/manifest.json +++ b/agrifine-extension/manifest.json @@ -14,18 +14,18 @@ "" ], "background": { - "service_worker": "dist/background.js", + "service_worker": "background.js", "type": "module" }, "content_scripts": [ { "matches": [""], - "js": ["dist/content.js"], + "js": ["content.js"], "run_at": "document_idle" } ], "side_panel": { - "default_path": "dist/sidebar.html" + "default_path": "sidebar.html" }, "action": { "default_title": "Open Agrifine", From 6f94bd7c79196d98b95acf2a7dc3c2a3f958cca3 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 03:58:28 +0000 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20add=20AgriAgent=20=E2=80=94=20rea?= =?UTF-8?q?l=20agentic=20loop=20with=20tool=20use?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multi-step AI agent in src/ag-refine/: - agent.js: Claude tool-use loop (up to 10 iterations), streams events to UI as it thinks and calls tools - tools.js: 6 live tools — get_reading_list, get_field_profiles, get_ingested_files, get_weather (Open-Meteo), lookup_usda_soil (USDA SDA API), calculate_gdd - index.js: chat UI with streaming tool-call display, suggested prompts, clear conversation - Wired as new Agent tab in sidebar (6th tab) - Also fixes manifest.json paths (dist/ prefix removed) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01KBD2dN2KEjzz3UQFa9hEpu --- agrifine-extension/src/ag-refine/agent.js | 127 ++++++++ agrifine-extension/src/ag-refine/index.js | 234 +++++++++++++++ agrifine-extension/src/ag-refine/tools.js | 304 ++++++++++++++++++++ agrifine-extension/src/sidebar/index.js | 2 + agrifine-extension/src/sidebar/sidebar.html | 9 + 5 files changed, 676 insertions(+) create mode 100644 agrifine-extension/src/ag-refine/agent.js create mode 100644 agrifine-extension/src/ag-refine/index.js create mode 100644 agrifine-extension/src/ag-refine/tools.js diff --git a/agrifine-extension/src/ag-refine/agent.js b/agrifine-extension/src/ag-refine/agent.js new file mode 100644 index 0000000..75af4ba --- /dev/null +++ b/agrifine-extension/src/ag-refine/agent.js @@ -0,0 +1,127 @@ +import { sessionGet, KEYS, buildContextBundle } from '../utils/storage.js'; +import { TOOL_DEFINITIONS, executeTool } from './tools.js'; + +const MODEL = 'claude-sonnet-4-6'; +const ANTHROPIC_URL = 'https://api.anthropic.com/v1/messages'; +const MAX_ITERATIONS = 10; + +/** + * AgrifineAgent — agentic loop with tool use. + * + * Runs entirely in the sidebar context via the background worker proxy. + * Each call to run() streams back events via an onEvent callback so the + * UI can update incrementally as the agent thinks and calls tools. + */ +export class AgrifineAgent { + constructor({ onEvent }) { + this.onEvent = onEvent; // ({ type, data }) => void + } + + async run(userMessage) { + const apiKey = await sessionGet(KEYS.API_KEY); + if (!apiKey) { + this.onEvent({ type: 'error', data: 'No API key set. Open ⚙ Settings to add your Anthropic key.' }); + return; + } + + const contextBundle = await buildContextBundle(); + + const systemPrompt = [ + 'You are AgriAgent, an expert AI assistant for farm operations management.', + 'You have access to the user\'s farm data through tools — always use them before answering.', + 'When answering questions about fields, weather, yields, or finances: first query the relevant data, then synthesize a clear answer.', + 'Be specific: cite field names, dates, acreage, and numbers from the actual data.', + 'For weather queries on a field, always look up the field profile first to get coordinates.', + '', + 'FARM CONTEXT (reading list summaries + field profiles):', + contextBundle, + ].join('\n'); + + const messages = [{ role: 'user', content: userMessage }]; + + this.onEvent({ type: 'thinking', data: 'Analysing your question…' }); + + for (let i = 0; i < MAX_ITERATIONS; i++) { + const body = { + model: MODEL, + max_tokens: 2048, + system: systemPrompt, + tools: TOOL_DEFINITIONS, + messages, + }; + + let response; + try { + response = await this._callAPI(apiKey, body); + } catch (err) { + this.onEvent({ type: 'error', data: err.message }); + return; + } + + // Append assistant turn + messages.push({ role: 'assistant', content: response.content }); + + if (response.stop_reason === 'end_turn') { + // Extract final text + const text = response.content + .filter((b) => b.type === 'text') + .map((b) => b.text) + .join('\n'); + this.onEvent({ type: 'answer', data: text }); + return; + } + + if (response.stop_reason === 'tool_use') { + const toolUseBlocks = response.content.filter((b) => b.type === 'tool_use'); + const toolResults = []; + + for (const block of toolUseBlocks) { + this.onEvent({ type: 'tool_call', data: { name: block.name, input: block.input } }); + + let result; + try { + result = await executeTool(block.name, block.input); + } catch (err) { + result = { error: err.message }; + } + + this.onEvent({ type: 'tool_result', data: { name: block.name, result } }); + + toolResults.push({ + type: 'tool_result', + tool_use_id: block.id, + content: JSON.stringify(result), + }); + } + + messages.push({ role: 'user', content: toolResults }); + continue; + } + + // Unexpected stop reason + this.onEvent({ type: 'error', data: `Unexpected stop reason: ${response.stop_reason}` }); + return; + } + + this.onEvent({ type: 'error', data: 'Agent reached maximum iterations without completing.' }); + } + + async _callAPI(apiKey, body) { + const res = await fetch(ANTHROPIC_URL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'x-api-key': apiKey, + 'anthropic-version': '2023-06-01', + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + const text = await res.text(); + throw new Error(`Anthropic API ${res.status}: ${text}`); + } + + return res.json(); + } +} diff --git a/agrifine-extension/src/ag-refine/index.js b/agrifine-extension/src/ag-refine/index.js new file mode 100644 index 0000000..d870629 --- /dev/null +++ b/agrifine-extension/src/ag-refine/index.js @@ -0,0 +1,234 @@ +import { AgrifineAgent } from './agent.js'; + +const TOOL_ICONS = { + get_reading_list: '📖', + get_field_profiles: '🌱', + get_ingested_files: '📄', + get_weather: '🌤️', + lookup_usda_soil: '🏛️', + calculate_gdd: '📊', +}; + +const SUGGESTED_PROMPTS = [ + 'What are my current field conditions and harvest windows?', + 'Which fields have the best soil for carbon sequestration?', + 'Summarise all my farm data and flag any issues', + 'What does the 7-day weather look like for my fields?', + 'What USDA programs might I qualify for based on my fields?', +]; + +export function AgRefineModule() { + let messages = []; + let isRunning = false; + + return { + id: 'ag-refine', + label: 'AgriAgent', + + async render(container) { + container.innerHTML = ` +
+ + +
+
+ 🤖 +

AgriAgent

+ AI Agent +
+

Multi-step reasoning over all your farm data

+
+ + +
+ + +
+

Try asking…

+
+ ${SUGGESTED_PROMPTS.map((p) => ` + `).join('')} +
+
+ + +
+
+ + +
+ +
+
+ `; + + this._bindEvents(container); + this._renderMessages(container); + }, + + _bindEvents(container) { + const input = container.querySelector('#agent-input'); + const sendBtn = container.querySelector('#agent-send'); + + const send = () => { + const text = input.value.trim(); + if (!text || isRunning) return; + input.value = ''; + this._runAgent(text, container); + }; + + sendBtn.addEventListener('click', send); + input.addEventListener('keydown', (e) => { + if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } + }); + + container.querySelectorAll('.suggest-btn').forEach((btn) => { + btn.addEventListener('click', () => { + input.value = btn.textContent.trim(); + send(); + }); + }); + + container.querySelector('#agent-clear').addEventListener('click', () => { + messages = []; + isRunning = false; + this._renderMessages(container); + }); + }, + + async _runAgent(userText, container) { + if (isRunning) return; + isRunning = true; + + // Hide suggestions + container.querySelector('#agent-suggestions')?.classList.add('hidden'); + + // Add user message + messages.push({ role: 'user', text: userText }); + this._renderMessages(container); + + // Thinking placeholder + const thinkingId = `thinking_${Date.now()}`; + messages.push({ role: 'thinking', id: thinkingId, steps: [] }); + this._renderMessages(container); + + const thinkingMsg = messages[messages.length - 1]; + + const agent = new AgrifineAgent({ + onEvent: ({ type, data }) => { + if (type === 'thinking') { + thinkingMsg.steps.push({ type: 'status', text: data }); + } else if (type === 'tool_call') { + thinkingMsg.steps.push({ + type: 'tool', + icon: TOOL_ICONS[data.name] ?? '🔧', + name: data.name.replace(/_/g, ' '), + input: JSON.stringify(data.input), + }); + } else if (type === 'tool_result') { + const last = thinkingMsg.steps[thinkingMsg.steps.length - 1]; + if (last?.type === 'tool') last.done = true; + } else if (type === 'answer') { + // Replace thinking bubble with final answer + const idx = messages.findIndex((m) => m.id === thinkingId); + if (idx >= 0) messages.splice(idx, 1); + messages.push({ role: 'assistant', text: data }); + isRunning = false; + } else if (type === 'error') { + const idx = messages.findIndex((m) => m.id === thinkingId); + if (idx >= 0) messages.splice(idx, 1); + messages.push({ role: 'error', text: data }); + isRunning = false; + } + this._renderMessages(container); + }, + }); + + await agent.run(userText); + }, + + _renderMessages(container) { + const chat = container.querySelector('#agent-chat'); + if (!chat) return; + + if (messages.length === 0) { + chat.innerHTML = ''; + container.querySelector('#agent-suggestions')?.classList.remove('hidden'); + return; + } + + chat.innerHTML = messages.map((msg) => { + if (msg.role === 'user') { + return ` +
+
+ ${escapeHtml(msg.text)} +
+
`; + } + + if (msg.role === 'thinking') { + const steps = msg.steps ?? []; + return ` +
+ ${steps.map((step) => { + if (step.type === 'status') { + return `
+ ${escapeHtml(step.text)} +
`; + } + if (step.type === 'tool') { + return `
+ ${step.icon} + ${step.name} + ${step.done ? '' : ''} +
`; + } + return ''; + }).join('')} + ${steps.length === 0 ? '
Starting…
' : ''} +
`; + } + + if (msg.role === 'assistant') { + return ` +
+
🤖
+
+ ${escapeHtml(msg.text)} +
+
`; + } + + if (msg.role === 'error') { + return ` +
+ ⚠️ ${escapeHtml(msg.text)} +
`; + } + + return ''; + }).join(''); + + // Scroll to bottom + chat.scrollTop = chat.scrollHeight; + }, + }; +} + +function escapeHtml(str) { + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} diff --git a/agrifine-extension/src/ag-refine/tools.js b/agrifine-extension/src/ag-refine/tools.js new file mode 100644 index 0000000..6d693cd --- /dev/null +++ b/agrifine-extension/src/ag-refine/tools.js @@ -0,0 +1,304 @@ +import { getReadingList, getIngestedFiles, getFieldProfiles } from '../utils/storage.js'; + +// ── Tool definitions sent to Claude ────────────────────────────────────────── + +export const TOOL_DEFINITIONS = [ + { + name: 'get_reading_list', + description: 'Retrieve saved web pages from the user\'s reading list. Can filter by tag.', + input_schema: { + type: 'object', + properties: { + tag: { + type: 'string', + description: 'Optional tag to filter by: agriculture, equipment, land, carbon, USDA, dairy, finance, weather', + }, + }, + required: [], + }, + }, + { + name: 'get_field_profiles', + description: 'Retrieve all farm field profiles including acreage, soil type, coordinates, crop history, and notes.', + input_schema: { + type: 'object', + properties: { + field_name: { + type: 'string', + description: 'Optional field name to filter by (partial match)', + }, + }, + required: [], + }, + }, + { + name: 'get_ingested_files', + description: 'Retrieve all uploaded and parsed farm data files (CSV, Excel, PDF). Returns structured JSON extracted from each file.', + input_schema: { + type: 'object', + properties: { + type: { + type: 'string', + enum: ['CSV', 'Excel', 'PDF'], + description: 'Optional file type filter', + }, + }, + required: [], + }, + }, + { + name: 'get_weather', + description: 'Fetch current conditions, 7-day forecast, and calculate Growing Degree Days (GDD) for a field location using Open-Meteo (free, no key required).', + input_schema: { + type: 'object', + properties: { + latitude: { + type: 'number', + description: 'Latitude of the field', + }, + longitude: { + type: 'number', + description: 'Longitude of the field', + }, + field_name: { + type: 'string', + description: 'Human-readable field name for context', + }, + }, + required: ['latitude', 'longitude'], + }, + }, + { + name: 'lookup_usda_soil', + description: 'Look up soil data from the USDA Web Soil Survey API by coordinates. Returns soil series, texture, organic matter, and drainage class.', + input_schema: { + type: 'object', + properties: { + latitude: { + type: 'number', + description: 'Latitude', + }, + longitude: { + type: 'number', + description: 'Longitude', + }, + }, + required: ['latitude', 'longitude'], + }, + }, + { + name: 'calculate_gdd', + description: 'Calculate Growing Degree Days from temperature data. Uses base temp of 50°F for forage crops.', + input_schema: { + type: 'object', + properties: { + daily_highs: { + type: 'array', + items: { type: 'number' }, + description: 'Array of daily high temperatures in Fahrenheit', + }, + daily_lows: { + type: 'array', + items: { type: 'number' }, + description: 'Array of daily low temperatures in Fahrenheit', + }, + base_temp: { + type: 'number', + description: 'Base temperature in °F (default 50 for forage crops)', + }, + }, + required: ['daily_highs', 'daily_lows'], + }, + }, +]; + +// ── Tool implementations ────────────────────────────────────────────────────── + +export async function executeTool(name, input) { + switch (name) { + case 'get_reading_list': + return toolGetReadingList(input); + case 'get_field_profiles': + return toolGetFieldProfiles(input); + case 'get_ingested_files': + return toolGetIngestedFiles(input); + case 'get_weather': + return toolGetWeather(input); + case 'lookup_usda_soil': + return toolLookupUSDAsoil(input); + case 'calculate_gdd': + return toolCalculateGDD(input); + default: + return { error: `Unknown tool: ${name}` }; + } +} + +async function toolGetReadingList({ tag } = {}) { + const list = await getReadingList(); + const filtered = tag ? list.filter((i) => i.tags?.includes(tag)) : list; + return { + count: filtered.length, + items: filtered.slice(0, 30).map((i) => ({ + title: i.title, + url: i.url, + summary: i.summary, + tags: i.tags, + savedAt: i.savedAt, + })), + }; +} + +async function toolGetFieldProfiles({ field_name } = {}) { + const profiles = await getFieldProfiles(); + const filtered = field_name + ? profiles.filter((p) => p.name.toLowerCase().includes(field_name.toLowerCase())) + : profiles; + return { + count: filtered.length, + profiles: filtered.map((p) => ({ + id: p.id, + name: p.name, + acres: p.acres, + soilType: p.soilType, + cluId: p.cluId, + coordinates: p.coordinates, + notes: p.notes, + cropHistory: p.cropHistory, + harvestRecords: p.harvestRecords, + createdAt: p.createdAt, + })), + }; +} + +async function toolGetIngestedFiles({ type } = {}) { + const files = await getIngestedFiles(); + const filtered = type ? files.filter((f) => f.type === type) : files; + return { + count: filtered.length, + files: filtered.map((f) => ({ + filename: f.filename, + type: f.type, + uploadedAt: f.uploadedAt, + structuredData: f.structuredData, + })), + }; +} + +async function toolGetWeather({ latitude, longitude, field_name = 'field' }) { + const url = new URL('https://api.open-meteo.com/v1/forecast'); + url.searchParams.set('latitude', latitude); + url.searchParams.set('longitude', longitude); + url.searchParams.set('current', 'temperature_2m,precipitation,wind_speed_10m,weather_code'); + url.searchParams.set('daily', 'temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max'); + url.searchParams.set('temperature_unit', 'fahrenheit'); + url.searchParams.set('wind_speed_unit', 'mph'); + url.searchParams.set('precipitation_unit', 'inch'); + url.searchParams.set('forecast_days', '7'); + url.searchParams.set('timezone', 'auto'); + + const res = await fetch(url.toString()); + if (!res.ok) throw new Error(`Open-Meteo error: ${res.status}`); + const data = await res.json(); + + const current = data.current; + const daily = data.daily; + + // GDD accumulation from forecast + const gddDays = daily.temperature_2m_max.map((hi, i) => { + const lo = daily.temperature_2m_min[i]; + return Math.max(0, ((hi + lo) / 2) - 50); + }); + const totalGDD = gddDays.reduce((a, b) => a + b, 0); + + // Rain alert: >0.5 inch in next 48h + const rainAlert = (daily.precipitation_sum[0] ?? 0) + (daily.precipitation_sum[1] ?? 0) > 0.5; + + // Harvest window + const avgRainProb = (daily.precipitation_probability_max.slice(0, 3).reduce((a, b) => a + b, 0) / 3); + const harvestWindow = avgRainProb < 20 ? 'GREEN' : avgRainProb < 50 ? 'YELLOW' : 'RED'; + + return { + field: field_name, + coordinates: { latitude, longitude }, + current: { + temperature_f: current.temperature_2m, + precipitation_in: current.precipitation, + wind_mph: current.wind_speed_10m, + }, + forecast_7day: daily.time.map((date, i) => ({ + date, + high_f: daily.temperature_2m_max[i], + low_f: daily.temperature_2m_min[i], + precip_in: daily.precipitation_sum[i], + rain_probability_pct: daily.precipitation_probability_max[i], + gdd: gddDays[i].toFixed(1), + })), + gdd_7day_total: totalGDD.toFixed(1), + rain_alert_48h: rainAlert, + harvest_window: harvestWindow, + }; +} + +async function toolLookupUSDAsoil({ latitude, longitude }) { + // USDA Web Soil Survey SDA REST API + const query = `SELECT mapunit.muname, component.compname, component.comppct_r, + component.taxorder, component.taxsubgrp, chorizon.texture, chorizon.om_r, + chorizon.drainagecl + FROM mapunit + INNER JOIN component ON mapunit.mukey = component.mukey + INNER JOIN chorizon ON component.cokey = chorizon.cokey + WHERE mu_lks.mukey IN ( + SELECT * FROM SDA_Get_Mukey_from_intersection_with_WktWgs84( + 'point(${longitude} ${latitude})') + ) + AND component.majcompflag = 'Yes' + ORDER BY component.comppct_r DESC`; + + try { + const res = await fetch('https://sdmdataaccess.sc.egov.usda.gov/TABULAR/post.rest', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: `request=query&query=${encodeURIComponent(query)}&format=JSON`, + }); + const data = await res.json(); + const rows = data.Table ?? []; + return { + coordinates: { latitude, longitude }, + soil_data: rows.slice(0, 5).map((r) => ({ + map_unit: r[0], + component: r[1], + percent: r[2], + tax_order: r[3], + subgroup: r[4], + texture: r[5], + organic_matter_pct: r[6], + drainage_class: r[7], + })), + }; + } catch (_) { + return { + coordinates: { latitude, longitude }, + note: 'USDA SDA API unavailable — soil data requires network access from background worker', + }; + } +} + +function toolCalculateGDD({ daily_highs, daily_lows, base_temp = 50 }) { + const gdd_per_day = daily_highs.map((hi, i) => { + const lo = daily_lows[i] ?? hi; + const avg = (hi + lo) / 2; + return Math.max(0, avg - base_temp); + }); + const total = gdd_per_day.reduce((a, b) => a + b, 0); + return { + base_temp_f: base_temp, + days: gdd_per_day.length, + gdd_per_day: gdd_per_day.map((g) => parseFloat(g.toFixed(1))), + total_gdd: parseFloat(total.toFixed(1)), + interpretation: + total < 200 ? 'Early growth stage' : + total < 500 ? 'Vegetative growth' : + total < 900 ? 'Approaching harvest window' : + 'Harvest recommended', + }; +} diff --git a/agrifine-extension/src/sidebar/index.js b/agrifine-extension/src/sidebar/index.js index 72d1209..2c88fa1 100644 --- a/agrifine-extension/src/sidebar/index.js +++ b/agrifine-extension/src/sidebar/index.js @@ -4,6 +4,7 @@ import { DataIngestModule } from '../modules/data-ingest/index.js'; import { FieldProfileModule } from '../modules/field-profile/index.js'; import { DashboardModule } from '../modules/dashboard/index.js'; import { CarbonEstimatorModule } from '../modules/carbon-estimator/index.js'; +import { AgRefineModule } from '../ag-refine/index.js'; import { sessionSet, sessionGet, KEYS } from '../utils/storage.js'; // ── Module registry ─────────────────────────────────────────────────────────── @@ -13,6 +14,7 @@ const MODULES = [ FieldProfileModule(), DashboardModule(), CarbonEstimatorModule(), + AgRefineModule(), ]; const moduleMap = Object.fromEntries(MODULES.map((m) => [m.id, m])); diff --git a/agrifine-extension/src/sidebar/sidebar.html b/agrifine-extension/src/sidebar/sidebar.html index db557ca..f9a0880 100644 --- a/agrifine-extension/src/sidebar/sidebar.html +++ b/agrifine-extension/src/sidebar/sidebar.html @@ -86,6 +86,15 @@ Carbon + + From 3e16c962c61524feefe8cd9f893d16bf33a301fc Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 04:05:08 +0000 Subject: [PATCH 04/12] feat: add run-agrifine-extension skill + Playwright driver Driver (.claude/skills/run-agrifine-extension/driver.mjs): - Launches Chrome with unpacked extension via Playwright persistent context - Stubs chrome.* APIs so sidebar renders headlessly without real extension context - REPL commands: ss, tab, click, type, eval, quit - Screenshots land in screenshots/ - Verified: all 6 tabs render correctly (Reading, Ingest, Fields, Dashboard, Carbon, Agent) SKILL.md documents agent path first, gotchas, and troubleshooting from actual execution in this container. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01KBD2dN2KEjzz3UQFa9hEpu --- .../skills/run-agrifine-extension/SKILL.md | 87 ++++++++++ .../skills/run-agrifine-extension/driver.mjs | 162 ++++++++++++++++++ agrifine-extension/package-lock.json | 48 ++++++ agrifine-extension/package.json | 1 + agrifine-extension/screenshots/ag-refine.png | Bin 0 -> 53214 bytes agrifine-extension/screenshots/dashboard.png | Bin 0 -> 35371 bytes .../screenshots/data-ingest.png | Bin 0 -> 33235 bytes .../screenshots/field-profile.png | Bin 0 -> 26746 bytes .../screenshots/reading-list.png | Bin 0 -> 33490 bytes .../screenshots/sidebar_initial.png | Bin 0 -> 33496 bytes 10 files changed, 298 insertions(+) create mode 100644 agrifine-extension/.claude/skills/run-agrifine-extension/SKILL.md create mode 100644 agrifine-extension/.claude/skills/run-agrifine-extension/driver.mjs create mode 100644 agrifine-extension/screenshots/ag-refine.png create mode 100644 agrifine-extension/screenshots/dashboard.png create mode 100644 agrifine-extension/screenshots/data-ingest.png create mode 100644 agrifine-extension/screenshots/field-profile.png create mode 100644 agrifine-extension/screenshots/reading-list.png create mode 100644 agrifine-extension/screenshots/sidebar_initial.png diff --git a/agrifine-extension/.claude/skills/run-agrifine-extension/SKILL.md b/agrifine-extension/.claude/skills/run-agrifine-extension/SKILL.md new file mode 100644 index 0000000..2df452b --- /dev/null +++ b/agrifine-extension/.claude/skills/run-agrifine-extension/SKILL.md @@ -0,0 +1,87 @@ +--- +name: run-agrifine-extension +description: Run, build, launch, screenshot, or drive the Agrifine browser extension UI. Use when asked to start, test, verify, or take a screenshot of the extension sidebar or any of its tabs (reading list, data ingest, field profiles, dashboard, AgriAgent). +--- + +# run-agrifine-extension + +Agrifine is a Manifest V3 Chrome extension with a persistent sidebar panel. The sidebar (`dist/sidebar.html`) is driven headlessly via Playwright using the pre-installed Chromium at `/opt/pw-browsers`. A `chrome.*` API stub lets the page render without a real extension context. + +All paths below are relative to `agrifine-extension/` (the unit root). + +## Prerequisites + +Node.js 18+ and Playwright are already in `node_modules` (added as devDependency). Set this env var for every command: + +```bash +export PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers +``` + +## Build + +```bash +npm run build +# → dist/ produced, webpack compiled successfully +``` + +## Run — agent path (driver) + +Driver: `.claude/skills/run-agrifine-extension/driver.mjs` +Screenshots land in: `screenshots/` + +**Single command:** +```bash +PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers node .claude/skills/run-agrifine-extension/driver.mjs "ss sidebar_initial" +# → screenshots/sidebar_initial.png +``` + +**Interactive REPL:** +```bash +PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers node .claude/skills/run-agrifine-extension/driver.mjs +# agrifine> ss reading-tab +# agrifine> tab agent +# agrifine> ss agent-tab +# agrifine> eval document.querySelector('#main-content').innerHTML.slice(0,200) +# agrifine> quit +``` + +**Available REPL commands:** + +| Command | Effect | +|---|---| +| `ss [name]` | Screenshot → `screenshots/.png` | +| `tab ` | Switch tab: `reading`, `ingest`, `fields`, `dashboard`, `carbon`, `agent` | +| `click ` | Click a CSS selector | +| `type ` | Fill an input | +| `eval ` | Evaluate JS in page context, print result | +| `quit` | Exit | + +## Verified flows (run in this container) + +```bash +# Initial sidebar — Reading List tab +PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers node .claude/skills/run-agrifine-extension/driver.mjs "ss sidebar_initial" + +# All 5 tabs +PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers node -e "..." # (see driver source) +``` + +Screenshots confirmed: green header, bottom tab bar with 6 tabs (Reading, Ingest, Fields, Dashboard, Carbon, Agent), AgriAgent chat UI with suggested prompts visible. + +## Gotchas + +- **`chrome.*` APIs are stubbed** — storage reads return null, `sendMessage` returns an error object. The sidebar renders and navigates correctly; AI calls fail gracefully with "No API key set." +- **Extension loaded from `dist/`** — always `npm run build` first. The driver checks for `dist/manifest.json` and exits with a clear error if missing. +- **`PLAYWRIGHT_BROWSERS_PATH` must be set** — without it, Playwright tries to download browsers and fails. Always export it before running the driver. +- **PersistentContext required** — Chrome extensions only load in `launchPersistentContext`, not `launch`. The profile dir is passed as `''` (temp, cleaned up on exit). +- **Tabs are data-attribute driven** — selectors are `[data-tab="reading-list"]` etc. The driver maps short names (`reading`, `agent`) to full attribute values. + +## Troubleshooting + +| Error | Fix | +|---|---| +| `Cannot find package 'playwright'` | `npm install` inside `agrifine-extension/` | +| `dist/ not found` | `npm run build` | +| `Error: dist/ not found` with correct path | Check `UNIT_ROOT` in driver — must resolve to `agrifine-extension/`, 3 levels up from skill dir | +| Page blank / `#main-content` timeout | Chrome stub missing — ensure `addInitScript` runs before `goto` | +| `ERR_FILE_NOT_FOUND` for sidebar.html | Build produced it at wrong path — check `webpack.config.js` CopyPlugin target | diff --git a/agrifine-extension/.claude/skills/run-agrifine-extension/driver.mjs b/agrifine-extension/.claude/skills/run-agrifine-extension/driver.mjs new file mode 100644 index 0000000..1c14cd1 --- /dev/null +++ b/agrifine-extension/.claude/skills/run-agrifine-extension/driver.mjs @@ -0,0 +1,162 @@ +#!/usr/bin/env node +/** + * Agrifine Extension driver + * Launches Chrome with the unpacked extension loaded, opens the sidebar + * page directly, and exposes a simple REPL for agent interaction. + * + * Usage: + * node driver.mjs [command] + * + * Commands (interactive REPL if none given): + * ss [file] Take screenshot → screenshots/.png + * click Click element + * tab Click tab by label (reading|ingest|fields|dashboard|carbon|agent) + * type Type into element + * eval Evaluate JS in page, print result + * quit Exit + */ + +import { chromium } from 'playwright'; +import { createInterface } from 'readline'; +import { mkdirSync, existsSync } from 'fs'; +import { resolve, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dir = dirname(fileURLToPath(import.meta.url)); +// Skill lives at .claude/skills/run-agrifine-extension/ +// Unit root (agrifine-extension/) is 3 levels up +const UNIT_ROOT = resolve(__dir, '..', '..', '..'); +const DIST = resolve(UNIT_ROOT, 'dist'); +const SCREENSHOTS = resolve(UNIT_ROOT, 'screenshots'); +const CHROMIUM = process.env.PLAYWRIGHT_BROWSERS_PATH + ? `${process.env.PLAYWRIGHT_BROWSERS_PATH}/chromium-1194/chrome-linux/chrome` + : '/opt/pw-browsers/chromium-1194/chrome-linux/chrome'; + +mkdirSync(SCREENSHOTS, { recursive: true }); + +async function main() { + if (!existsSync(DIST + '/manifest.json')) { + console.error('ERROR: dist/ not found. Run: npm run build'); + process.exit(1); + } + + console.log('Launching Chrome with Agrifine extension…'); + + // Chrome requires a persistent context to load extensions + const context = await chromium.launchPersistentContext('', { + executablePath: CHROMIUM, + headless: true, + args: [ + `--disable-extensions-except=${DIST}`, + `--load-extension=${DIST}`, + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage', + '--disable-gpu', + ], + }); + + // Open the sidebar HTML directly — works for visual/UI testing + // (chrome.* APIs are mocked via the stub below) + const page = await context.newPage(); + + // Stub chrome.* APIs so the page renders without a real extension context + await page.addInitScript(() => { + const store = {}; + window.chrome = { + storage: { + local: { + get: (k, cb) => cb({ [k]: null }), + set: (_o, cb) => cb && cb(), + }, + session: { + get: (k, cb) => cb({ [k]: null }), + set: (_o, cb) => cb && cb(), + }, + }, + runtime: { + sendMessage: (_msg, cb) => cb && cb({ error: 'No background in test mode' }), + connect: () => ({ onDisconnect: { addListener: () => {} } }), + lastError: null, + }, + tabs: { + query: (_q, cb) => cb([{ id: 1, url: 'https://example.com', title: 'Test Page' }]), + sendMessage: (_id, _msg, cb) => cb && cb({ text: 'test page content', title: 'Test' }), + }, + sidePanel: { setPanelBehavior: () => Promise.resolve() }, + }; + }); + + await page.goto(`file://${DIST}/sidebar.html`); + await page.waitForSelector('#main-content', { timeout: 5000 }); + console.log('Extension sidebar loaded.'); + + // Single command mode + const args = process.argv.slice(2); + if (args.length > 0) { + await runCommand(page, args.join(' ')); + await context.close(); + return; + } + + // Interactive REPL + console.log('REPL ready. Commands: ss [file] | click | tab | type | eval | quit'); + const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: 'agrifine> ' }); + rl.prompt(); + rl.on('line', async (line) => { + const cmd = line.trim(); + if (!cmd) { rl.prompt(); return; } + if (cmd === 'quit' || cmd === 'exit') { await context.close(); process.exit(0); } + await runCommand(page, cmd); + rl.prompt(); + }); + rl.on('close', async () => { await context.close(); }); +} + +async function runCommand(page, cmd) { + const [verb, ...rest] = cmd.split(/\s+/); + try { + if (verb === 'ss') { + const name = rest[0] || `screenshot_${Date.now()}`; + const file = `${SCREENSHOTS}/${name.endsWith('.png') ? name : name + '.png'}`; + await page.screenshot({ path: file, fullPage: false }); + console.log(`Screenshot: ${file}`); + + } else if (verb === 'tab') { + const label = rest[0]?.toLowerCase(); + const TAB_MAP = { + reading: '[data-tab="reading-list"]', + ingest: '[data-tab="data-ingest"]', + fields: '[data-tab="field-profile"]', + dashboard: '[data-tab="dashboard"]', + carbon: '[data-tab="carbon-estimator"]', + agent: '[data-tab="ag-refine"]', + }; + const sel = TAB_MAP[label] ?? `[data-tab="${label}"]`; + await page.click(sel); + await page.waitForTimeout(300); + console.log(`Clicked tab: ${label}`); + + } else if (verb === 'click') { + await page.click(rest.join(' ')); + await page.waitForTimeout(200); + console.log('Clicked.'); + + } else if (verb === 'type') { + const [sel, ...words] = rest; + await page.fill(sel, words.join(' ')); + console.log('Typed.'); + + } else if (verb === 'eval') { + const result = await page.evaluate(rest.join(' ')); + console.log(JSON.stringify(result, null, 2)); + + } else { + console.log(`Unknown command: ${verb}. Try: ss | tab | click | type | eval | quit`); + } + } catch (err) { + console.error(`Error: ${err.message}`); + } +} + +main().catch((err) => { console.error(err); process.exit(1); }); diff --git a/agrifine-extension/package-lock.json b/agrifine-extension/package-lock.json index 1bc27de..bc4eb68 100644 --- a/agrifine-extension/package-lock.json +++ b/agrifine-extension/package-lock.json @@ -20,6 +20,7 @@ "copy-webpack-plugin": "^12.0.2", "css-loader": "^7.1.2", "mini-css-extract-plugin": "^2.9.0", + "playwright": "^1.61.1", "postcss": "^8.4.38", "postcss-loader": "^8.1.1", "tailwindcss": "^3.4.3", @@ -4046,6 +4047,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/playwright": { + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz", + "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.61.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz", + "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/postcss": { "version": "8.5.15", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", diff --git a/agrifine-extension/package.json b/agrifine-extension/package.json index a33d9c5..2270b00 100644 --- a/agrifine-extension/package.json +++ b/agrifine-extension/package.json @@ -16,6 +16,7 @@ "copy-webpack-plugin": "^12.0.2", "css-loader": "^7.1.2", "mini-css-extract-plugin": "^2.9.0", + "playwright": "^1.61.1", "postcss": "^8.4.38", "postcss-loader": "^8.1.1", "tailwindcss": "^3.4.3", diff --git a/agrifine-extension/screenshots/ag-refine.png b/agrifine-extension/screenshots/ag-refine.png new file mode 100644 index 0000000000000000000000000000000000000000..1c79dde609e3c844c8c7331efb95483b8b153937 GIT binary patch literal 53214 zcmeFZXF!udur`XKqS8b_kSZb~U65XtDjliP1wnc*p+{7@6h%O4q)SIi0)zn4d+04B zbV5z&J;^6}&i($L`<46Wo?rXE$-c9*v%9l1&&+O=j+P4fZHC)KL`3AOFBNr(h_3&6 zygGFA>Yw5{tJ)PJqB}&YiZAs2GPaQ9L5YVj0>Ld^_|_wswrX}!*{#pXYNmX;R~$HX zQpY}$*}-)RTH-t#e}g15Famq$xI2S3lDj(b=d|$m5=@L5;Y`u;SBz*XZN(p7fS!MSyiHIuseDfAvNF+_MH#O?vbh=nO8DA`bcNkVwCM%`Q+9mS)%gVKGyf_ zxY=B(S#stOm5b#<+(rJ$CTE!S0v*4bUbm!U<`rgUMeEDDEgaWMi1UGB2$K$5&s5@_ zAqt~3`*XGK=!>ha49lO55X2Yl@e#s*%6Cel+m1txyR{RRCrMelQJZ1be!W$cSWWVy zM*O?&hAyD-@X%>QoVk^i>bGeV;qh5#3JWTAupA%eNeJ=-_ zsAWZTv-}*xELESIy9B)Li{~H!+gF|@5N!#}Ai^M3f&4BJfu-)5d(>2HM~W$%gpP6j zX<}DOS)cae+m!A`AVXnD&%~T=*#XwCNFGwpzkC<^g&gR7giY?`hBwM_W?DG(?yOJC znTxBkUp7c&q@w74;=-;hRwH_&dzm2Q+e=5_J=&)}MtU4ia%$Jjm|KNrN5tKm6rq%+ zrFcXXaih+a(gk<+ZEvdR_ux^vL(PR^7p3C)o8jR*YZju5>Aj~8|HSU~4YQ2V$iY5DLOQT?8&yf{rW7AxH=JOHjq_h?LvxaG z{f^4ULpF{Pgh#N*7?!3tXBmT(tXb0g9pe>-lbLsjg%XI&<_ey;zJkXIO-h-fDq`&& zNfTtr*484AywasEfWmo2O`1(b{3qR9w7~=3E z&-`-b61n>$sQ~E**nHsNgcEy`X9s367(7~-r=4Y5Yoj}IGO88m@)lW9mDR|OnJ8g+ z&%wD>OzBvAtULjaDo5&2d$eYcL>;}S7~T>f`^X$3-za;L?g)Jdm2B*!+ELn^7jo+{ zTAvH4?zI9OFHEa%ypoHJSr2fjfRwb#Y?gH5y-zgLH{&H51h_~ULDI+Tf`GXAv6|O$ z%;HBce6tU~fbd<~F!s{)cvuJ=1Yz=u7^ov0mkiEAq4RKTlqt*E`pzq^nVn<-I=EEU zsRbnPeM$q%nfo9ydlT|S|Aho%HPAx8%(0*xj-Y)1bQ1ZWL) zkx`YYXtMGl)Ap^7+shjrIy3iKV;DsqK9ZgqJ&sG%v;-Q1caxfd`ipli1vX#ZB)c9} zo1He#Omh5E-~wlR7MVQ~!w}=&XXif>Q)8-|4>Zawr6LyDQLW_GA}_8aS0k%J-JfWj zX8Pd+Asya*-*j4oz;?WS)%MNh$d{l~ALu+(6we4Jd+d5FASLpX5@D#=g?d)B$+9qk z1eKpk`Y$k*9hjtg_DwB>bu|q{Z!9axoz7`@g#()O9HC__OCG17V^Z}3A9FzD_ z4`wDHJF0%&n)xn9wRs{J+I+DCx4g$xnFW$y*1Qfp*=lnssHS#-gcu(!%n-Ad;un9glo47?jPefG|pUbds8GlawhdvJFJ#a$@tCC zEmq|H;GWQh%aPs*K9HZFj<>^arH3biLQd<|iUMqUiM3MBkw~mMp$>sS+t_dsU)^iw zeJW<0b&;YHa@x`ybLCVk{zb85S#d2-E(zi-35Y^GKaQftNSubY&|p{%ZJs@0{6+Ih z2($d-f={&}wniEh)y1~VB&H;)J*SK52990$1C7+0=^7`1p2B_#h?SXoi8)z%G0RlB ztn_SFuihX&&BOP5P04anE!=MMb-sRv&_ZpqrfS_w^19O#Lf~=*aK>&ksE|HuZwUkR z5e7Cn1}>m(iD`}iT=T4s?WWbCm@5?NZ2ZORZ7LJ^qqcX2y2tZ#`0cqazW}kFT6x!H?zy`#}vg6syjR|qs)7i%%i>OgY+BA_&0-swvq7-m10Dk#MN*v=8{E6?ycKU1h!7*&GH+&_d79+ zTaB90U4^E=5Jf_gx&LsPqw9THiF}@BFa}q(lV>XKC^zlm|K^h&O%1(Z(B8E}H0#VK zU9V9-yXfBoU2+$d;Agoe`5(4_vp&{XJM1pTAFZp{jbK++#CN7Uktj}LsZvYU>S#gK zt68-qWiA?phi=Tn1pTtuV&yD<(C3cU@wL`R!J z%a~LWEEwSZl922}kzhy;mfBiuE!;aA0Nif*Dpb-?RQ9US8~g{(FvphR(8|ORYX0h9il}eXAmSJot5^f!f8@sI$zWFw?ibnRjU- zN(+##k0rlFb`~!o@Umker$UWHly(9@-lDt1Uro`(UgPt6$RX9T>*Rsy&sm(q{ts2E zSgPAbAtf8QnaaS{(ql){yJK-sd6z;24pqwH`DH+9jdPCLe>L{qVzHfXxg_w*&aIxe zxqV=L=ms3+P%`%EdY_`X-Hl|Ya5EdCn!cH>yGG%osPklI-;!_6uXcOF6cxy;GW~t8e^-m4cGFZGh_f zaWkZ1&b&^WtQ$btvIv@Z0l8sHte~a7?xyi0SOxaZ+Hdquel@I3n_GSE?pT^j^vTZ` z&+P2qu5cN=^Xp3=hqxEa6K|8(gM?4Sqp_8nZN1@dSv z(epmV=ALI(&BfABp7B7VO3z4TCYhu4U)3B=*^zOn2i@+wkfqtbmS&4eW>uhCMp>bB zM{6_PcAo&ASJL_?6zP-GRGyn_em1lb%)8^z)v_6$!p4>5&D|gOK3#v%H@~l$NVl3RkMo$gCvzl#(sts{*SPQXHGg#Kl zT#8)D4GHMmk;6(>)t5RBGNb$}^&$K?$Q)ceq*UpdqpnR|9lmA^gKzsq(%J4m<2%Yn zn8S4U0QoO$K>06zKGa*p1U}+d9zXbvg8MQ2wV+wYPsirYl9h{YGKs&0HE-#lg^ki) zY~0H26gE!R7M)agiwL8B$tqEHDzJS_sE;}>v+2v$2C&kPRm=drz$Eyn8%9I&6=%F=KGyfT!EV?~_ zGv@n*^K3h*IoYSXC^X@mRt|W&DF;+7V;DQNiddWSs(Vg0W*Zq55)wj^CJYD{F@i)@ zjd~^lyHugGA@8b6-WHClBTevP z!t`OpT+Vhzd&%ME%v;N}+oG&>@?LtE9!(4R5AZLH9R9-6V>tY5;+@>^?pi!cM&g$h zELtFc&VaQnMfMgc8CO~PPbb$q#4B{Wz{k;jY#enfEao3|y)T}xm;i-rN+d46!p~t$ zG%wVK7uQ%SX>W1$;XU1oAx|*kmHWG_Seeeszn)0lul|P3rob*O%-Y%s=tCy3hrsF~ zVFnIu?chsewbvp%4{qq^PdTlPDN&HPSf3`GvrK+L+FmC~FQqV8J~73dukU;>7pj8o zP}*81hFmJ3`S5D|5~b|L;#)vqAiCytN{20JiwiRzG)5B9ji`wR$Hj%peDiz0te~--CF&ua$*YXN`}yKX-ii=lRy{`rLTa?7D0xx6u#Fv%KV{ z<+yFS1#yZkC*mEnnXmrm<<<@Rz#I24Q7H$cf2!QE+VcBPEP&|5V(;1;j~5tQ8sW>& z=am6gQAVhgu*(;sy5XKn4B?Nf{r>;GtNlO4TH!QEk)mD$y_hYh06^F7Op*f^IFA#1 zq-;DFDt4B*F9qaIT<1KTpZ)6)3!Gj>qmSD_TBPI?H-p45aYu$8CTh)DVw11-wjbtu zaAin^sR!_3cPME-+JxZ$O1J!N3SW&dWa>sz(oeN!XIJp;ATi(JiAP#K`E#3DV_HSE z6vK}%J2EfnJI&o9)}_dj=>a-;cvSE*6x+g|F+mYgm+c)HH$f2?VHu(J*}ma7m4va=3A6^!BM z<9`3qk^kiOjF_yYtgH~L@3;~yY4nMEV_d7>bG+0ame+63(m{Zc1=dwZhn|+NcXvYc!Vs7WN(lhiPGcyxD zn(8m!-Rc4)PjV?D?36eTJAW-Ka_O|OG>?qc(n;8qjiyvr7F!?20a zu8oqNC!^orS5Zm9!INR*y{x#oIXSD4>GOq?6eHMag_ys30Xc~%R)!zv_QUmc$?2#4 zZk531ELZvv@D1lvYh0fI&T8%!m8@s$R%s=&!da4c48Ui8xJp*^VY?=1SB`LcL|}SS zEW1Dx+O~*2n{FfUIF%Z%7jZYA4t)@@jM_oiX;BK`{M^<(RMys{umsB(J7l>yH~@1& z;5~N5m1xQ_HmgQrwk1HO2dENF4k;%Z2LN*N?37N*$r)l+{L|F(@EC5E8xoRYjmQqR z6phuyGNromo$ei`Kl7WTg`3&b9pR*6o)x6AC$TA$@!6 zQri8&fqitkX9kp{Mv$y0$f^q?xxkP>O$fqgvw5m!HTUh{^ICUN78GtyeGcEKRCF^w zCVty7R`TfG(pvj+dTkmi+#GVq@IG@+{{pA(zZXv}B;*Z-tHpt%W1P;amLu6WBJST> zzm;QSH?9h|D^K)Cpr(0+k_qR9Shos3rvPV-%Jbms1O3-UkpzZKCi?3Z^oZag36|w?b{I40W5N;iQ#xwmB0F^ z`2I^G*Qv^$@%eh>|YCT zAgo>4G%mOXDt|U-1wctH92Fh^Sx=u_=2joNwR(rtZo*Ba6;g;hn-lie@qFo)O)`~T zv1I29dwiz8*txx~4myf6pNXJf!5|tY+TCMhinLYdc3WP2?{SDe>U5|eoESKZiJEH_ z2Mk!sAqgl?ZF$)eUo0ymaHCEPet``(mF*{Ng7dR(WK7}kU6vBf=G;N8U-?XBFF=rc z{tN&9wPMI*!!39`VgEI%ENvB=FW!Bj6Ug?8?;%ZJY%QQIKn$sj@nnE^ys-=)-;$_H_t1A%{1%uhbKAab8Zw%- zv#$yOgy8qv6TW`^8UVK(V^`Kv-=8&S5_c7&Sg>UdE2CC-B2%V9`H*kUF-+%?vVrCQdAfiyyJ4E<|x~ym^J& zjZl#mnNOZs^wjov{YCt+NikMOIgT(1wQhDXb2+_*^|rKhIfLvbCc4(!nM`V!*LH}^ z$sUM5b#0}0z^ZBb)d4W&6EhQi!kN`=drDbK!7B2lW1I?aJLeW9^~Sc1?dts$l{F%1 ztf}wby~=kk>*OhE1~#O+Gv%{iDPN?^14DN?mYo;)&&9ae#+q{Do&`>HsT8NBo8*`B zP~Ie^Sl>{om#<692qtY|Mmha8vdYEg)+Jhm{9EiSlP5F8tpE+JIk64!W1o|ADP_(I ze=M9kKc`^#n=bVfginNN>LLuFQ+*1nKZXI0-r5b5K>w&waZ@3KCk;1{N8+6l4}xA- zR4WI%KE<~_Ypg$v5i87Z^gr5Pf`VE7the&25qjJ-=fG;ib#HP z6>9j3!uy>=DhL=zsq_Xh%pOQs5Z{fL8^kT8#tU<(G^x^$cyUeZ@yqHWW{c+PuD>bjml78*wTO1EdQX(9BPyoG%0)t+T%0eOqI3Po|28@;hcA#Z@S<;lQjQ-U zVDoxWGn7>r3}!)?PCQ*7tW2(gbsXl%HHy(6pQM}#$e!i+j>vq8Vpr%eiXE&HpfD{^ zR+7*TdUY^9ZTlhbM@a~lC*A!g=LI4$v0-(^(}dee>6@}yPCpNagWF4AaRFn>WI%U7 z9r=_+b#)_V0vb|nE$?hs2OZCi)~JHarTU`B3=aaw^o}g9?deRadcS-})ITNv+vu<^c%Q#GiN0#6IM9Fw^bL z(o^sAEARwsq=J(nZttj^+ja6;XrCPZXV8QI_9A6>K?$)r0K^@4QOuP(loiRcoh|i~ zcZO1Do%Zzt*VCXy`8#5iIQi(>b5Y={XX}=C?KC2B_M5vCFo6r3LB}%j-K2U167~fk zv)lb$drnq|aBPR=XZEjFt_dJfiXgamoC|0-w0nJ{nMr4-ZQYXobvO;8=}_*F+u5r= zKHS^ls0VGeF0_@2oPwrRE}WMut3&moOC8cC^KvjWOJN9iL*~;!gKkRDaAxLX6B+9< z%D2(@rs|MR>d~y9b9;kr75G8}nGH*oIC>LoCZERP#|YLF%TOu&PP-G~70-vaHNOC# zfi=fO(!AT?spjC5ElRm9pL_Q3SN}1ygs#oA7JTNHJW*0mXq%G4B%nf$rtPe(tW>!m zn6sQZ?M*31IZV(6wi1D5INhdy=dx&?OKZ91l_rM@TAoWm*4pPA)L&4t(uyTd+84;} zep-rmbE}|>u4YdbC~n%kvGjg8@oSA8wdv3f)HOZ?TjGe#?9^ke+aDIQq*ga_mUC~t zFqr?;Wm$*IT`}#G5$g*$`tcbG^p9HvxK+&I!|EGndGmX}P-F1JGK8=6Pxy_mG@WLF zWGhd*16N$iIEyJkcix(0!pIixMN_0|oIv53irhmdYaoyeKw_LS%kO|0TQUU!4M@8& z%6&gD!Q^?#>MFm>GUi<1*qFde(&p&^sj{j7oz6@vHb)gJiZ!?cT%M70$4d&Ig=@Pj*(*wH1*SGQT zqlk#G*rx3x?dV=fI{L#dLeqMjDLWlOEr=xUUSXA!BahucIj#0Z1#_2D%Spb|Tn3fI zkf|$t$=Tz{hX(NYPDhD=?62}xuFr77VcE1tu+pu?|8rk`a$kyS5 z)AUWkqsKT9opN|&AGab|!PU!%_G zU`2a;*yV~Ig)L;srqJbc`?5FwHa^4@H5S zLhv{*1(u@R05}R6rs>Kyo16=U+%p8-Gm1a=9{5d+z-Js!#u^1RV^)hVC@J)Xp_j6J zkFCHPz0cGPlWG#5$hq%-JT+{RilzoQO%KAGOO5Cs&v~Tt&+Bf2%28hP_Csq2%Xi?t zLWh-K#G-!4F7J#c3-~7WxiSVKD%CNI4P(dbVJXlRoBAT8yOBwT7FW3-Kz&+HR%Cqy z8*SKk=~}*L9BT=G-bbuID5+Osx_RptrgMhc*Z+CT`HN~cC7l|jkRue;|R95f5gWo0dnz5gtv{Q(yv zf}37tU!A^uKSon2ulIT|HJ~uJr8tj zSE5$+w&j05?9^c4r(iC3^oVLEz;q+$^Q0bg{50X|qohq^+_K)e6FkD)mMbjeah9jg zAxoR*YpRXd-oBy`Tg27&fd=hdSF}9OX|Q)QEO&ZUmt32LZs`djr*SV`&*jR;!(3|D z7}8gM?6`$COHjfQzrK~=FG#+kIw)%{5317TXoFdu$$`hQR6t05+?_q;bwBGrIM}kb zOnT@%7BXYgi>SX4L2tVB#TX>S8L_q-ID$G6a)bu zs}QM8IEp=%yj3b=X6)eT3_d5JxG%bKv@ra;YM&B4u?AjLgUI&3^2r%2Vi1+Y-*eea z$;3&Fxt}wOsgOxl;0m2?t5Yz$cz55Re0B{Qh$VrXf

e(i{wO7wV}x>zzm$U8@Z{ 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�UscC^<@=Bxr1w8aKD-yTf38$uvD4GOK0QEMRyC@V?#HGy5ODko2YvE1%3_< zN1CB^wYSR35fSDGRn`K5zm6OI5@fwj8#S!N=xA1W2jM-jCXzgR&WQoAPJX+O=XG@T z{35?AH|Br0?sQ%?njH;*^G)k=ZnhP|gxy|j_>a%zT`x(zC!VGT`7?12nbQ+lvzVtg zQ6js7*~woo%(At#V&ja~Hz`)JHQbAd-obTmXhIpn+GeK~?`DxXyOn;?EnmaY__ZC) ze7$&Jfgi`!Vonu*<~-AV_oR06-M!0eO-@RAPMO}oU0PzL;=f(* z^i!5sv-HomevA6jMzKxbrc|7#dpejOInveP)b_z_Tq>rw;l^39x0=yg&3K4qbmj7Q z@m&1?7s}7nznV%b?B)J=pDsMd5e!&BCE^62QT3& z+djWs*9o2Z#7y^HxTe?FpQQN1vvK)H`w*r)kdTrAxamjT;QpXvaZ-SgxATW#-KMf1 zswO4bKOW58OOYfC|eJ$#v)EaW@jFQJD5!Ri>|m@0NYiy5wyEi^n|w~NFy8y@(^ zl2`tQt?gSpwC-dq_2)U>_EOI03?z&uNJ{AWys^cH4jM3N(uUOnJT@IZHFTZ z2rTQW_Eb6Vobi2WNwr+Tc8VgdIlWxf&y!}$ihd!q4O&^-ml>RM9vmbOdVO|ZW$Ug8 zSxlzV=DT$&+j``(b>8tFt{v&LbDlY9J@}Yy54_qx% z%}8w6j*^o}WxQK3zQ$go@J)tE@Ab@BNAE>Ohnu#5Pvp<}wUbZv>ejhR&0Gha2Pfuk zG#lvr!#l9n5uuc(8lLm%q!Mm;|5cYi=cP0ROu^e>W>AA{O$`c)x@FmKUsC(3X)0Vy zgW^ zgL^Q+^Z2AJQ|*p~euo(BwuST73In72$H0kW*r(5fpKD}ZvFyAwF`EQ36rY?L3*2zA z6gd|Yn2glI*l3N4S_0g|4 zEwnztBq47U-uMNW+*Eq=XYkBqLNqaWnNRzq=wArhwlH`Voq%~JGOa1d|EhMu--J%5 zcSH*ZY80V(7SFU^FFCrXXK!CN|M`^2{UaOEacap!yK(J;RfG^W5;RG~MMBh~f-1r|5<}czwRQ`|)7k)|--gEU2?2 zV)qApY4%J%#4m6I!)CPa&v#KL{UwwFs&4ZsZnJU&7(yo1Yv)4qEqBeYR_4KSmp(yX zI7XDUE!_Qgy0&HI-UFMDxNo{EKHqtriP%B#Gp&EuFuiBIzVtUI;lFa-Qj;E$FQ5jv z+_Pp|@n^F#59wVTTHs8(7$*ub zRsB1*?@OE&{|9^T8P?Rcuxsmb*+505cLf3Iy*C8`=@L4jNDaM*7K#l}s?<<}^d6+w zfP!>L=)Fh{9jT#vCb-sKYwf+ydA~p3k8@q;pC$ojMrM*Z?r}fQ`0}~M4UDSQ+%;;r z^0_u0)#2mp@#PQTq{$Rx3XBsF$$fS{>cC-!Y!m#!sp!3aIx;5(`L4KMs(=bzJ7oO@ z|A*gq7#XjA4hAZM2D-CFsDL3lKUn~A=-GO9bY5v%$`SP|gT`*c@bgcvf zr~jZQ2gRQl>-t(P#lEc(-=5?K`Box6rj6K{+O=~p6Mhj#_vX}3y|gA)vf56IxLv&8 zm&v+WU3ffRN$XwLHqluV^uVAcDZ1*@Wzy_*;zYbVzh@Q+9c$+_lkfu>{Oqb-hTc+!pKWWCQ@lQl+CGu-6;ro%R|8JkAXbH1{xzyewgPgiI&tfpY8g$jV z`%00!58r%5%IR>L4zreSI8mW)1?#3uBGL1Ig4j+#(P1b5U@`9dWHB>y2*mzC(#BSk`BcrqpycrQH(J_*w|7mM3XcqwFtF&@ zuJM>tuimc;+Djwv4i$O&LrIgsfqPH(Qv}v>d6N4b#0wwuFPBdyx@*N}sAq(FT2H!8 z=G~?Yww?Vz413ojxnD|*X+?zQf{NGHw^0^R|Mi`E$Hm;?u}c&i$j@!KW$aB>oUi_!LN8g+%(;d?4^)V zhlaj~Eq^u2utJObU=3NI=82`ah4ox+;Q=RdLK<)!1?>#Gxn$Y$X9F!I>Ym+7DXfl&2+ph$B)=d5ot#lvH48{rSdRL2Zf%c5HQ}D=8`RicEz- zZaPhTxpzd_lkjW+l9sZ)0mq(cD>RbC~oG5e19MPV4ST;%6C@Osev&185A zqwsQTd$Rc5O!Ziy-1CM2;O*1Q__dD=#9x8S?+Tkicg%&}Yq{RXW^PkErNs(WPt!nT zCY=*3{MfEU&b%RZv{4jgsjJp}<+$U(*?PRBo$I5n>4Wc8YI!a6v9HjWRi$Hve$s+O zD!po4p?NLZPy$ege{}~6X0Kow^3er^k!Op9mpj}ADY7_IinKlG`xDR&aX}?1lY>Go zD?tltX|4|F686M$UEP*a(NY?nYIEgWl`(A-8+kN-t#Ze>*zE$LDhrg|L}aU>{2a4p$`(W>3d>+x3yP?nl8_H<4;8;EnDdpx>6A!iU7GgJa_f zNi7PMH8mZ^B6b>)J%j3mnEbTic!Go$iAsAfSLLsioVK2I~I7ha5o9pb*SX#r6c@Y&qtTEto42RLd{g_q5BHq(* z5(k3C-A;n>_Yx9N}K4(4cT88`vbzGrHffHNt9 zPM5G3Nu=x5j~&k`CRZzQ&j@ZZyc>!!lPtwf*r?*ov`cm{eM#)jgoGXnVM>Vlz=NC7O*5e&*|ov7yHzt7?xvY$IvI-*GuWM-^#Lc0BhK~LIl)v?n9KHs}8M1Mp<;-vSKUPlyL3S)hjCn9e;_;T~6o2W5x>$y0u!z z&;2~{P-lhA^gTB_RIe_-q;aLr6{f%VCavU4#-YpokfXb%vR*?vt7ocg)5sA}?N1l& zj^A=MDAN>`lSL&L$HyN~ySXG|@5swM%TV)sdTC?pu2_0i)cw!|E+5;LHyYA5n&!!h z_wGg6FOB7vm&|`sha;$F3m!*=aofDcI%cqUAuk6|O}bwADDJLAe>bt&k>*{yM^b9Q$^X<)0B|{_F+XBr(lxd-7x=ULiH8Mh; z&2U~>%ZxBD%djb3>x~s1e-S6Gyl7v}F?RkSrCcx_^k^m?pXu9RG*!WmDF#ZS7-2|; z%2<^I3wPsGe>t{9Zw+xjhv%CR%d=h=0x+c{XHi%rvSp_CUc|DhY6n*i2aiGnJb1nl zv1x3O>mf>?zJnvetY3;J_cC~gJxURmF=w$Xx$~XK1LmOg4tr@XQghMaXJR=?(L{-E z28XYU)XA64i^Wi61}l#2k+Md}Q(Z%SomDo+WvnIt(}Zs~R$n*j*`)IGDKp93m^q!L zq3GQkG)j$LNkdlHgB>eIk~_XHy~iKR8F=UB+oaV&3_=x`bE=gRdp0H0KHqiamPWoI0!VPKH|})S$A}7S z@Wp6)(Zi+Sv&zr@$#<-rKvzo!{^C*V&4ETM*E;a`mp&&bYxQGS#hWr}+dwNBm%Qy? z-0E8@H@Hq_(eqv^zdW;**q|mvp1`NxbZ3rrs^sx)UM5K#D5!W?H-gWUB!gDJ0ymgj zOBwSO_)b0>NP5nE`5N%!o=UmB%L^3>x%tP2#IAcKS7Vqy+Q8a^#En>>tpauRt-QaF z&HC89NV%C0y50f2wEHb2_Y(4!SLWaUc#)Z3Gsuy#|9dX_jHj=uoRlcBoa-TEA&kjr z`f-|x1zWs?=-`w(!FYzj`}b`xX|c$BRG8s{`b+fHk3C{<4FfUR*GT?7uFVb3IKD~)a8`kt{M2fDevud{3c3#eJ9n`rVQKk!FS}cXfQm6rq`yE7;(*rZ=O{Xh;UT- z^PUDaq z>nc*vaJpFd@N3tDn4D4_>c(TGjl^e@WSKNp)&Z(L zBR||7ddJh`lY)MNhIw+0kX>FW(#;PYn`D0YfwCXAVywOAwR|a&g1Rw^i&{&4*q@0A zPnEass+mLH=E-SBW$^q7!q3C)`&D)j;zQM){(#J@iy^f}x@mA<=EpF*JqIwS+XGb6 zZ?MgL%a$&MP+qQs^F{vQ;(wqhGBE~v%`%OO4pHZkROsnG1t=3IRw`ht?Oql6y*29Efny^c)j@; zol;(NL-Q4g#&Ow4o}U{|r$9?ubQ|AUbCZolv^M>H+}1UlsScmxB(-IPZn9XDYxXY+ zwJ~O3w;Zt}JJ>OJ&)G)VWv)3)+-z4V-KBq{+dug_I?j9eLk21pAUB4ucA#>VGSzD+Y&fX4Yyf~1kJ?+eG&QsQsGt7AKTMfR zucMNf&y&vl>C<|Kk`zLx&f{ADDUO(P%x3ytmXCTu!>Oe5&RQy%&naGQHcI+foC&R0 zQJ*vR@uSIFQ@G3>MXS{4)XX%e_YV!}4cLPaFdZbND9;$Eq<<&1vku$y8c!R0$)Q|A zM@?64baoqEuk~U=c)uQd{$UAceZyyMEI7Ek>++$=MJhdNPZlNH>nyezm4)uGO14n2~`Je z4`ZgnSGy8ZeB8q!c$W9>rW^!U%I(kG7PymOD3iaLeMUEX%r6JMVH@RM`{Rq>YDC-<5;n0RHtep#ACP03Q|s9(XZ z){Q_j6)+onu4`x_ap_^a`v%x;imivkWhzXNCdX>GPU{y`V&2OXE1y7=dJKw7;#3~g zd3yy^*0UTb8Lv6vqgH1?@gIelpyPyoUOa-2l=6G!ECV0IMy0|hBO?w?6gR-7emeo~ zBuiI2)k8t@TKYjvUP6$57g0OJ@K_FcXSV0!!_}<;GIf%=f#}o54w&_XG*4@oycYD% z>!FM+OiH=kch54K zk&jNlhOO4OdEDi-YLe5 zTdQPMDn$oKw}$^irfN3*WyWa-=(i2{c6^;`eQ;gsEo~g>27vQyP{ebN9z5?0=PFUP6}KyWB(piE?PQHGV4UnXm+qbq`$=dmcZa0XuQ3f>I&C`VP3K0`&9z*5V4rj*v^0YuULuk z1I*?6;?ZC@(#v_-DZeVDe$qmEDnO2QOtW`0b;+j(lz7~jcb(9%8q1_@aXhK>C!MMq z(kB+qr}0V6m^r}|X4(jf32(%}WIcXXuTP3aDeBWAzh8{YchQHBUSaxTisV#LDJ7;zNRs;e1l4xK2PFSC+^^LI)6scr66}>0v)UP-1&#plD6s5^jjd8D+ zc|fY~PL^Io5*IG>W{s+w8CD}Mdd3PL!cip&>eq$3hA9=WwzGehn@&6%c$3pHTv^bb z@4gc10$2U%R3ba}@@#A}QIMLI_rt^7o28^GKu6IEo3_QUWoTM%jqEoRAFnAUi^{1| z14SekG}Sqk*pOY{%lrp**?QXOm0{UkaxTfdduY+3*bm80)@H5Hu4`CD?JZmnvJLVu zZFy6RwXo#WRdVyni~c{mR5{l>-~7n}{_a&VXsY){rjRbdCB-;(7bahI)}2ktkq(!A z2x_$-J=eTCA*1dVo1Nq8rp`HYJd9!$T>Ml0DOrOAb|MAg8i{Nc*=~!$y|h24(@Dpd zJvBQ>)Hh1lZ7LK_$)mVsHe9d4B-TuQN{RK%b>Kt@-QrwNEuSK97j56;Awl-|9jL19G zJ!<%tD~ziOlDuj7nS+-*XPg99XDcGw{}*vlMMYE44n+U#s-;ZJ;`EyWAGr-IO4L7; zq_O%XDRh zKl>xa-qKd6C;CM z*sHfvAzo@pCBm2>*+hqtsc8uPO(tFP+i+?<10VWECG%x{<) zf$R|1G|?Io1!rZ)Z5ts_>o2!6h{v&KCI!&Bjx_5)qUXO*ONy_<@mt+{{5G-FVlJ#% zr)H@>yN!XAtg*`Ssq1)XYA@6D!4Y zMibj>V}nt*vrrBTRI4?aqoex9c<7@^!cE)ugo2%hZz>pL;6l7J0W^6Mia(`mV%t^7 z1$8qZFkl&;6g_QD3817o9BoPG^gEb(XW0urKXo#8`u-^%S zJLZS$ViPab_36$+Xb`Z3o1S!)A!e#JJ(-yJkpJN_A?)nxH(e*kZm;nwhH!b*?$`S3 zr5V#adSQyKk1e{rv7K>Wnx;tS{PWt! z9l(Eh@z+K7vdb=dIp6>$$dqc&A>k(<)v1bbsp!Q|1q{cHWC4 z+^>f^5|AH-AK9H;A&(H5`_UC25%ejC+@O67WXWh74OpXt_U8osj zFbbA z?NuVcM(5mBP}Y@`H4Ca;3jWmARVtSOmxHLZJs*i)r$x_Hy2Nuvn68a*Wpr8XQ zmMN=VbNv^o>$1j5ZFQ1pveaG%CUHKwO*Z~SQQkzUWFc05?zC{x^{h;{pIBt{RnQji zGkAiCyRXu)K>^Cm3MXAV&x3*{SU+#^*z{Cej)dYxwNKC`Wo>&0`|dYJd-yy*IgNrq za;`k1-76!-IDO#WQE#P`c5T0@>tYh9Ka!6spB|4l%|L4ed}GM(^55%oxMtig{{fwM z0$R?@KZ_S4%)NP| z&-E%-rq~mfJEAqt1+w`d*9yH{kY8GcwJk6ze zuqQFzOu^2Y6k!S%hoidhQ*{Mz8DC%x+@F+M*TCJjX%!|W{fT|5^4eZJ-|>3vaY?^} z`-~%>h{jP4`s#eD+Se5%h8^WDpO?cT7FdI+WIVQ%Ai;(;~-e z-c_0z`i{+p1f}O!-IoNz^0_lXFXj()b46WtSZ&s%Sha89;zvKPRcsK9skwEU`Y_u; zji&M+I=G{mIz~IODBByoWki5H+}kYpiHnh4C%NoPuSN}Yn6hYdB5O>ONobh+RjJ zSEa~lJ*1SqkwzO*g&`YQ7CHHZWcz)mM#4+XhRgr%Hf!c4A)%z<_QKO<{ z{9|OyF;x6`n!DdJggU?SgO!s7+w@q&;E0BM@G@_cJP8r01va)0&bp9w_-YH|k^*kA zz##~6-=%$Av?6 z@~p$OPS@dZl|O}%axILv_QLo+AI@|82V%bus?U(z8q<(lvGwLS>ezGCb!a7j2xVvz zs!B!OyJ`ZIG+Fr%GS5?>v`AC&UUXccitUpM9^|DH`F6J`LPG7icrJmKhL%Q!M++xW z5$EF#DjqwfIFp>o9#2RuM7=yyE<@SCqnU?62pGN|TJ1H;GOeP_wFuHb|HZ!6owD0!X$X=!Q5Ib6cA-L&$-tzlw}Do zOh0cpR~U8p{>w)(IN@#vS#kf{l)2&9Y9PeZ%WJ5_E;wtkl9}IWD?*w@X48P>ugSir z#cSW4`;$`*D)@aEok)Aby5-_MK z#&i|s6iJ)$npW*X8{*VA0J!ChRw_83QC~j`4a=ok$;=ad*iU^i+LQ^lZ(mxk$A)U zlixn4qb`b1fyXD=yXT#1T&N0x9gTV8>=%!IW%F&oP*REH*X(f`vuP2(VL2}N>%RPr z6g#F6p5&C2lnc>CzKV@&z{sa;{oTbed}oR5bBObM8OQbl5G_)!cx$0*_gE`+H))aE z+Bv7umwm<5F8mkALt#;U;HdW9AW#@e*!2#M3IG)n_EAbSL+t~#Z)Sc`{6&aWnItY$`teoi$bkh{N=G{^7=M>)_COGV> zjBc#FeE^=CGEzZ}JWLWFaRDa9zhYJAFZ6p>l2^%cZa|8uwD_xGjjMSj(LVi zE}%oz>TuW-&d+W%Xi%FsjI4otW1T$ngzZK6s_MDf={KQ&-r@U|le&T^?$#)F@=>2n z#Fr4-b<8@`yA`uE^olmS#SAUa^SeQdMHK}ezVC5QN6MqR?Wo*MpmrMd6@Bh!a$VA1 zf}zfh6EtW1DRR^P?*iI`I1yKRC~NGa=zDv=GajMYr}l2;ka=q$H^<^ z3voJ-o1zfsOfq?pbSGbvJktI~wHCptNcQD(O~uPexY`ywDnG6i zSl&n;>ij38_DJ(;{N?N}CW;*R0#ufdaDg z%w&JG%xEwH4Kk{=yTe=pky4e zTB*h8SG+)ruE>Jxk&XR8*=B%d*}E{`(wK>XxFyfuzgYnC%dqR#V6=i$L-OS z-ywyDpWXJ}^{6@<8F+TN7%d?tWIFR)@k@p_5^?%^J2j+k#FZW;vk7|@PKq?+9=i(! z`{Hpi6DY3ne&o5R0+4q#-@>isL3d9|q0c_fK) za|~iQCPpeHZ*X_$o*ys%6R?9`FH{2h!T;!{bgx1OHkR4KFfwg|>vqAsuIwCx~e4zA?XDSn}S zcodLSmt~(HZ7x|~$mTi58tkRgAYQCpF#UO+V56Y2)K^SF|HPYFR@rdtYew%Dz0m}2 zJ8)CEXK-&oN>wz0Rq3m418g>#U6&ktJ1UkVvLo(rl?E&!SH9`*PFe^xuRDxmdhQq5 zkov`IxqldSxzGF%NOXyImVzq9N{!#r&s4Mb`TvOrKj{~m(!o_MSs*IZ~jrdQNSdgd55$`Pm(#;wpbxT`ae7joUDG} z-&9f#5=sbGaW!+TXFC}$fPQ}4bw znr&ImRyw{9xNHR!(W0G;MYP}$o~CPnn)=FQu!h$pfG%8Pt1vGD$Zj=iycmB0;UGM+ zif3`j&HQS{VSigb`i&OnZLNRl8ob**RH)Jc+l^eV9D%T|1Y*d5Tv&YkeWn%GOui8q z!E=Uwa`LgM>-TFZ@D)1BmO2 zX%*%9tmk-J6|f@z%yp&ig0hQ9(Ls^PF=GW+5uK_ca-|Tfe0MFVs2s8d)0v+hxriaB zp}rS?wwrP5?TQknwt%EIyDR?|cbEt-a@=^VPUxrEVwd*OR1|PJd1143`Xw_Zeeidy`}76Z@oWnHhkE#uv#qg*LrA>PrK2~<7YfDS1{uYgY;c7W#ZK9| z1%1aT!&JrUw(m-Tonv%T>b3PftYvxzFJf>ma_Q2U;V+V{ls>npO^=w^ap@|j6#0E8 zfDFSk2S$l={|OIjTV#yhfe6RQm1CU!K|!x(K^|+a3Fiylw63RbAL;-w!T)`n3jmN5h{& zGp)~hNB<@WRW?Dzz1^&YlHJt}1}dF_V0QgrD?riu|JiNr=)c@QiK1cM=xK?HDL0Z@vab+Ey+XNb{qSy~2Mm%x7!NybI3 zC#~{?U*3%GD?*&lne6qo9S2PR7C-8E0lLNYF9$^5)+F`6$B($5F)t)MFy@s9n%aCF zD|9Hpbqgk$JQ~czQ1KYha&mdrXr4ykwcKa#80}}e7IyZq{12Q|hJu7SY?_PhIx7~; z;NMX38KMwQ?E3B-i{Epl_h$MH6Dl9<-5;C_XpA&TO-UJph8H)+9VJE%@cP+yY%c30 z5z7eYTc?qlooeS1eMl6*jK7!|ytQ5hR%2OtBe)0hUtVErtKUAS|bFlv*M z@Db5HHF6gXIMmq+c)5UmkQh>~tX1Exa>7QGd?9xJF%lMnUtj(?-Q}} z&iWetX#J?c9l|G`8%%Ug78=7`2Ih_(JGwi!i5q+@w4H*N=#{-!Tsos{^94@b@|#B+ zhV~~KH^oGE8B~nIiCW$<2aMfj4HijhV!JxlM?Z-PF6)lyjg3r3uuhmyxmfz;R)W?) zN0aCkAnu(#4Dbkb^-m%HZT)`OWpw0uKgfg!(rj4{861vBY;mt>^~AY|`x`|}b7%mW zbdSui0%c0ERX=_|L4Y;C$XiB{MoOjVhjSLqw!VwW$Fa$R_+|R;n`KvH*@a8B7oQhJ z(a(v%N%Ov8A!wLgXQY#;3f|sQyt>a{}S*>_jlBd}L}vUBN*UhrFZ+Uhv8PW2Z* z4w2U-RGjj7xp1wJae%CVHxJE7;y)Ef)36#Uby`=3*pBOSsoj(f1~M|g(ZVV2zj&+) z#IrKKesBR*if?5zxkxvbQTV)bdk^w8Ch)L$z2QReUg8CrIzrDLqg%IvNP%H>3?(K- zQ=@%bwylQD!HbX1>n&Y;6Ep-W5#nWA!6joP4hQSJd8E@xcWDRUr#F}%p9XHb07QXLI{ga@n;0(sUnQGFjlA@b@Z1(C*jFDD z0aDW!+T|s(9Cd17@2?JDB;Th?YnBdwW?!<$ldUCV&Oy)j)RNCDZowD7=Q{;=`7lA0 z|Aj5EkK3u$%@Q5k5B+st-Z5nSX1Wp``!Sd4~^AhotvMzgGicmn4JQ&kyBQXAv;g znuhD^c3Ezn-8=?WY%gxLUAp3!T$`CYDM0r!=i-3BTMLi5(G3`-$6WnzwnKW#H0YZ+ zUiil@eVV|-bWCdtrzTmBiU50Kve$4yLRjo&+^-+ai|Qygs_tH=roO;-4NihUdC$d> z0uBetuZl?JA~-ekgcIgX$8eqr_>R!k^95ag_ zF7};zW%E2J6C^}@`Yifl><<2=$=sS3{sIqfDm!9w_~{m|`CVj&%g$qI-3Y78S@LDi zxuf1L59P6(#{{RrRkRO&h8(Bm{&d247E%@d$pYR_>#seo*|nM3!TB~Hr~ZpG4Tr~$ zO^|Ad$NlIKmmIC%Je3qb>X`~Mbf{kP1=UpFAvj+flUVqxNJn2CD`)^)?u)@q44tlz z6G#}Ek(|ziQi)$Bh991~)1I{N_mxgJgTo-Iex~h1jGL4;%SQyh!h3?akc05+*$v05 zNoheOR_f(`u;)SIMILAJ2id8EX6qeR&bZ90=nX(l{&;SC)<`X(q}_FKyh znT>C{GiP=xf37q&s3^h?Zu-1>+4%Vev{UU#KsAknCqRL}wTY#tOcxaIN zum{gaDXAo*Y9Jw(;NC@LkKX9OdZ7V46`xpJ#86?>qmz}jkQp#Vo(F3TXsok-PLVgs ztAf+$OEC56LUK9Srjt;s{uuV)Ve_z?+b7*td2O7I&m&-1rr2Ai8Jyxf@`QeVK~-Nb z3VxC~srRGUx0gKZQf6%%NCF)HFkU>)`~q6yK3WmMV>-2%W*0F@$puzzllv>HwS?-W zee_i_=ZPu!V9e1Q^8bBeie*$ch1(MK_{lr$Zmaew3;lxEFDmQPDKt z;GX16E(5|slogLeTrER>h);`8_brH|!Ky&N+I%l7A&Smpx2qi=q56K`wiO8YtX5ud z7Rn9fAl{fnh(y({@8E0r-$F;sHpr3_RQYw>W^SeIyYP4@?nJl=s$l$o@_Rsy4U!;w zJ23}s6_xhabl}7R#qch@`Zm~igMvQ8At5=&p_qA+k@UT^+wifVaI<>l8sX~}Y=xQm z5~ruGuHvx0r>VKW{7O0@cQ!@)>)ZN_rDTY-sTUPJcNsypoVIs?IYvW7R};wyVOyxD94# z&YYY?nOQ=%V4e8TdY#xoaM=cFa%WQQI=nNCTA+Q8d>I2ZypmPYJ$k&oKM+T?QWbJD zoLwn2{Nw(VMxF0)!rp>;jQzs_E7rx+6+;Z>NwZC*c~K!(`QuD`Z56U9y))YRtzg)~(!Rm- zki4K_n*2L`5RN)nLdoNC7*0Jh`dbAk?3@xn--fQc`UC zMbyrYWMM8J$H>6}rK%09_WG2A^M}|u%976Jg7{7E!|gyL4iBeA|8iyR1q2H>>uNH4 zzq-;PCuYix%d;}@E0%6Q55-{pl|BmPsr{ZUhCNZ7DwJrj*9FC#7 z+aqJ4>V&L2M(cIgsO4& zqR_#L4a4mz`$IeJN~Jz{ELGiSaK@vbjal9iB_79sSp|(La%gL}5$Q)SR{0bB9NuRl zf$%B9pAz6m2mXh8sNa{fm7?JbTKukvPj4de3c1D4Y=dG~EyPdI`Ld_qYPIDdhfAF{ z+93n17{29;{-?golE2kIi4TiYX>1PXl}h~s=2cA~buPsQw#fPGS$C`yEcSUB_sF!i z-m&7=R&c=Ys>m6!+>MUhmO((Ak1$q2;^LV@@t1L1~dCBAeK!YVj_zD|P(EC#w1%@R=ZtflHC_bH@5(xi$5BD0q<5P!a-jVV4K~&Y^@e)MF zKb_+^a?--#@I-zdy_^>D*htHP7DyO1p=Dvg@){j{&;%Eaj(*sp_K@_>6iuYS+3S$! z$xa@NUC(7+41^#H8O}v2_Q_bA+{vHSWW18lIyGxQsiCBihmg+i;)s&7;@I^9O*0j* zw*JVfQPpg+HykwwuaJSC=QEx`fWX**i1r@Sf`xQroZ*$2{Nhg;N{M{9H=8TIi=EWX)NFASUzRf*o%AuHAXG&;A(l-kMl1V;41|n76U1A`u$oL_ zAd8LjSNxa&Wc3ouA3#H}Ao)K!oyPslNriI|NX9{H>h#N`JLeQ6w zNN7yLs|U)%_0ijxm>cD9-w5i~i~CsW+!|HnK%~aa8>^I(>}GgPqLy@dNn^#KlF{yK zFZ9N&?eW6V7xZHL;L{cR@#UH5tMAVos|wiZ_{srXUZ_Q?0qtEl_7lJ1U`xY_nX~eCw zR^=LeSJ&jWW~R>=`^Kv`7W4pV?~aaCmf1=*Hzn{bs{M_a%AD+8yrpAdC%bi-CC@FE zWt+-}y7hJtHPg^tx_P?kLdtD7tan-x%6qCa;I6XbxrYorO~raei#?E{?&a!TW zQYW<si2Ae8v?5hc)dFS^*$=Dv}>YWixXkYsuL3K4BA zh5}_s0RO}@L7A?r@BH}*w1+%ChNAB{5(LZGF^P~$$GMZMmTQTtL30lv4rQ(eSI|Rf zn=igE7s4iDGp?>$v@G+Z#c9P7C#y3U{{pLhs$8QCPKpDmM?b7MyTKpFPC)=Utp?X; z-Wagdv+nA{B2rZJLy0H-RI8&EIkE=AYPF-_U_*U%klpiy>B@U;c!i8zT+UN91-tJz zXvc$VD@IqVH@5UNpFK10QX_vub^;XfykebGkhnhLLg_e%rZ<1hJr!@N*$c9IyxC?P z=oT_Vca0qL@;poRw z=ae5wT^w_VfF^%ZgDQ9wu zK83@f)aR8+x|VzB0H~vpe}3SHFtHdNP1lmCoZ-iMVOXEO0mh>iV`lcFFBy3+$XX_&mg&YeG3K*6x<=p@U4`tB=OztZY!pWCU=0D-wda_J%;Ud}^ z*0=8MD{Ma02`92^E5y-wI1EeEy3H|LX%)gy-zZXqL}uymJEU6~$=Dah@e;%c=9nM1 zRX(%G2+&W%CGD5sf;;r;1Vf98?n98TFM6e1L;24GZ++udedXGE4-G1TEM|W23wbQV zgTD~0sS}?jP!E@BAKzC99)d?3^rYa;wK=INi=yB)rDTJ4{zwWnHkp?B3Tg4YeOp9qaZ-va%E%HPG6xZp?9IbR-%QX7BuUh0hfZ4DJ znW}aey;}N2?v|gWaU(0H!1HB1u28^YBXRiy!r=LIUg7m2hfW{VS%!?jBW3}g!?(KR z4;$537p6+g5z3y={IiwfPdZK>rI#@KsmDA=jM?ocpTp{)W|`~C^qBZ@`Fj!^ya!)+ z8^ES&E4=+i-Vz*Zb!sD0F$X7Io<(-LJoc^fz=lCCE5WKTN?Rq}AE15*BOOoGP}uWD zyASOwiQ8{@?`B|hr{-omV{AnuZWOtYWT;x5$4%wq}N=@?6)?kFjtYn zvi0y{v*lyfJNLio{|yCytUvQg3+d8FWO~?*r#XRDM53ib#=gmAv6De7rZ_eaKY3Ma zB}0kFhqN-4mELFHxcJ1l$jcRBjD*4`kz^d+aaiu>V2TvqgA=RQ$N38fE3NKj;-^1O zG-9fd)&G+GWQL1U(LNg5+pD8jTZjoDp*1J**$+2QNlP>l*M)AMR9;Fk;WVrfspa=M z-2Q#>6TsBI?AiY+k!tZ@Tcj_)jrf|jzfy<6iJG)D8x<{AA}bo_eSX)N-0EIsujz{G zVU6%DdMvkorp%wv_2|lSrNdwDASZC9*QbzKdO$}zfdo1c?nFlTLvIKWN!n>`aVHaOSwtK7K;QHVM0<=d1tB0Aa|d8D zUvNaypDq}mAmZ{nb(Sx{U%7NCrDqfNYC&pfsCW2!@5L>Sqkx3>_xPXCuVmS9+j(PE zgRkm<=*NG@!41BW>eaa0BN_d3LpAk_pO|b zx-~xTKRi7AaNeO5`|kgi%BsJGDbJtD!SB^;W#`TUFo8ct7p135U;O)rPwQRF^MC#S zvl+)Vnpe~+*yaAPem9JyTW$Y>+eLrWmr!|*s9cSXr!376Vw`_G$dpRGJ1y!<4N&2q zD=Ue%75%oDWl^6723wB}k9rsYdbD6WxC^XTH4PaA2CFBjEI za65a1(0zyTe6OUv{J&az%dohbHcXHZf`s7i!Gk*l5AG1$HMl#$A-KC+a0t*4+%-5f z(zrV`8XOvEmc04iZ)UHZ{V}s!zs^;Cy6Qed;L{p-$gGR< zy^rtPZpBiN`ypqY!5?G+Xpw}3#tpg7e9OO307|d!W~{Mx4wRr zO}ZHSpZYv1iCz$#(Vyq;+g$7TX+KCPTDPxPX42~E%kcc8Bi~5sB*WPddSjHfO!EFY zSKto+&+C(hDpbke@|%0Ew|ToYgRhU`pb+CVC+{u|%+om*;gKh~z}?X2r_IP#X_g%5 z-gcMYopL{&QwXo3&v{yxkIs@$-?N7^xn|$I_oe%z)9T*(bMg1B`aexOKDAN2T5u}( z&2q$DJTp?4;QAA1s}n}0eIfpO`|oyzTUIv zH*-*hv+Cny|1*pm@J?@FYp!>Miy!&@eogx0`Y2CrOoI9LKpqJs(H=ofPR_QhZ@fo)OX793Fm;ac>oe-+9{8-t6w#;>-XhvlZS^}Fo=kgxyP8<}04+wOk&5NkL8La#xK zG>giPZ~i+`^aa5D$ibHTGMR45+N}Or3Y^(t=`dYvVP36X18J?38l8A6ipPRzF({0! z>BO5;DL_Z*`!n2TZdN0Qh2PV_=b1RANwmj`XNC*8&iUd}44!CIDUFPg@=etKNQ>Cg zWq%lv?FcW!oH+73Hz_%w-^UHF4=m)-(Lp@tJ=i}mliL$h8=+bmJl=F#C! zs0IS=kLeoeiFE?1o3=u#2F^RpW{cCsY(DJdt@{lzkCn%}_ajEkEfkl?YNKQwEZG{K z(zSCtUm2XTOMns3Sf&PYnOj`OaBRj_+wb1 z68*sGp)N~k!?oc@_jYmG@!`>2oKuH1D}aEpr~San4uMPEz8QVX6JK4-fTo>l9TO)9 zKbHs{Ze)>D-CmI_!V%#^bteY4W_EmPHZe8M+hAihq{R#jMLRiKJ7H=K-yk4Gq<%U9 z5zW@9i3)CsbW55?Edbapm!8ETx2s*0osa@3IDMzWQYC#twnn1y1H3lykA~hhozPqGttQ-n0!@V4|ecLZ~9C?M9Vtw$$eU`1h$>Tkf_XT%*f)m zX;8ecY*{2M|4fy)Yvn{@TgZi&e7T-kIO zNU4zCB*5>f;p_|){HgNrox@tObKmT6x>Bngv|`tZd`9q(kBcLJ`WEg6`HSVdHokw{ zOr3tNfWa`S_3<%?YN)vvF=oZHy?tn*Ktr}K)b8pAk`@4Df62HRS!iDNgZ_vQemjv@5M>ot*){Q7M{c3(iB9FGUoSx<^)$&= zvtFi!>tMa($B%qv8&2jg)0;^ry1{IIrwDF-xfDa3L8b3B38b@)$;TRdz-raicUGxh~+tq;-j4avyY?k~n(QdSy7{(m)@sw5&%36)vaGTWl!(4}KQMt|#g1zUB>BL= zFJ7A#ml5cTVR8Ylz9dVxwfJrv-X`1V8%C~TROkADDwUPm8m_d3!}E8$kH2cS(C12y z&YCdtZ)qe`p?*;g7)l@T5*ihAJX6)&NksZV-gBNEZEQ%~0tVC{r=0<*C$6F968fDM ziCt2|!dS$SQ^e-Jc?xBUDi!Uk^I`A2>SDqrahDO=V#LHxnJ`nKigl{raW5=&Ef9}p zrntWJueobQ^%yx_Y+DgElpF5|#>W;P zN4nMc<|t-K^tH59)uXv7Wm)oe5QvO1tz_KHX!qlm)O8}4pRq(})O5V}OY>&eUx{x; zMU@~xfrKfCTiHvt5)#D^GwQh{*I)IrXep*ACuvps2PdgG7Yex+o9n9_sm2{mGd=Ht zpohWXZoN*mPp#gP&NFwx%ERD`?On6dV(oGnWtCis^_3YbWTkXBvoG(*hnFOlD~BE-+Wl%#7)Y`4sO}`nv|r7kf_i(5$JHswDWxj z7(?L8LpeQD#7KB4b=WAHDx9uP*3wucTtY?Drb*ot7jXbBU%HT}`nPYyR@OVxAiNOB zoN>{V%NIgab@e=~F`2h+Zn+hJ6TH%u!Yg7*r8HYjb^Vw4d7}7iTzNLrZP^JsUaNQO zPO!01xj~^L>|&rUdjIWOz{ypF2DCk!mp-tx?>Z#0ZoHtVIAetFUhYLN00SeBQ0Qx9 zXainLP2~GxGymPM+nAh(J{Y4c*jPs8`Y_#F^OvdI0=lzU2{R18f?W(>DW`TzXTlc4wDQ^t&->bt`2QgjoNT zuaA)kkI@kf3c8Kqnr@vxcBETY`*)EgD6Aqc4sn-_%nmQc4zbJ-nm{Fdf$Y@kX8aZ; z2G~O0o~XP|CADQhiMvSbn2{BuYd2$@fie9CaWx%v?~T4XZd3+Lq~ehxY<6tVeX39w6r7nL%5LN@Ue;hG#{}G5!DuX>1an@OcQ{+RK0gI!3RsJ zEH}w03K5%gq|oMHieE9+%}-ZM9gvK7G9RgdSQbDWyqp^$cq?FJrPc&TF=B=6_)x7{ z8jkPR^qPyiA}TZg)m{H8y-R;=vbLDAYmj*v?!JT&ILVWA6gTDJoVC!brHk|F=8fjm=S@T2F_`-T&9olV$ z`_cmngmf7_Gvgm&?Plf+*JCThVfjdi(0OrK?fYiS+JdCNkTny^Ud?lSyR*&G_U7YJ ztbmApllOGW58!<1gd$a7cw>9cV@;%fE8hdRH+xJ++v5-vRl-js^bqoJycWNF^ErBp z)m!p?(pB;Ou!(>I-ko4)A zu)v-@WE2z~(08+%wtUC|fglS#_ak?dPb?Hzryy2vxA5Caq06H;AAfvJb$L>P!d!y< zZ(6(+Yx^yz*(`q+Y8U4!IIV!}=lxKeVHI-`+2L~=I@Z7jYdvvA+06|L3Tj+lQeJUu zj-(DMH?e?gbCQ^ctyQg0>$6|eZ9abgl&XGxR}W*v(3ngNF2*0=FwOn$T%=ybhb%j| zUiZiDDXhm4!4FS*Wcq&NANe?`HLaDY+Qd$byc#D%z=~*lb8RTILtr%3QRzj z%8FN_Px(y)1g8t*uWKsIMoIg+Yw!x3oAgW6;_`p7Rf4v_vUTCkk6*yGBpzv_+`rImAKlpz44B3Jml!Xc$yme#%mV}a~H znk|^$)Zb4!Sb(0j!!s?H)A?OIe*cdbzA_5MH9|U7p73~_KzWAh&u*m@{aLqDFU2(S&@f5MKz1n9;zUIEdiI&{>fm;HEXaBLNI zWM~iM_*_n+_1Fc`{~fZ_i)g3<8R?Upp>xnjJ=8SC$u!r!+vzSog_!PtK|9Ln^FnS% z?m>c>`2U?5lJz=&!SSw`Fn~T^Ra4Oa=+~ls&oIx*?temJy7f}?f5R5sc;uDoUjglP zY)0<25ajVb(H-?G!jUd~x5G zo8->ObR10KyA-SYN23b2a2)bK0h?b697U9ybT=BQgH`aSHSS3Tn!1nd`gHLiq@}e7 zD=AMihn#&Wk0~RLsf>I9r%(!BO2!E2SPJbFZ^E}4iII9tyXzv|SoGk3nttPx+i#5( zCHglx01O;yg;_WYJ`YT3$iM?ufbfyf^U$F1U3>Ln+Sh7P3(~`~@4}sFoM;ot{W){9 zn8H*tCXd?V)ok6I2cTx9zf1D{dxaI)?80oZN7kL%H23-F48Lj#%|eC;P+jIoROZ=) zwci_~{D3p(mVY~?N?TS4+WabaS@1NH2eR=fQOXLfI*FWnc#9KBx~D0}4iX_B z9`)||U|G{f6%@m(Iwy@t|E48)QO;==+I4Zl0A=SKdHtvdX)#az*`8#ak*DHx^Wx8* zAtLs-I}_NQi6F48^~n~(Wr6zNoDeWDr;>I#tK3;RjZcsaKdECICSSk~PMxpU;6$WW z&-2Q|6T-}`-h3P2C9}i9l`lKVNiz$0;9jj83q51`W_V6`M6J;+h(Kas;+)uoi(nX6Vwre%Fv=L8cIfo2nwg%r!!}c&2IZZ z5wj9cgx38J1{fF*^sB#t@?Zi2{$oB31M}+Dzk3cA_HSP3mn94L?{R~O`0p-7NB_7} z(p=ebf|m)YWX3FW{Lj>#zJoTwv{gQ}-sA>~WPwP28Q+Ua1XD2X&|F@U4D(KcCO5;w zRfoS`;e;`uGc*fuqsRUIXLru837F&BgEnTXusdf7pR)J~Cmncrh&*oC`(QW$jSon8 zn16vckKf}3*u7ru(8v{_R~+8=GH{Vl$(5EB81L1rG$T8(Ib%-`%@(O-mB-1)W+P7P zD>^$lCBm<1;S~_k5^q)!U6$3y)qf}!0>nGLThx~?vks-Wi-K26tEz4*t(!3MNO+(7 zk%l{)yM8IUqe=%9usRMG_CbBqSd`gm(OY-fEqJ0e^cXcQ3Q1Xl&a|?yw7Af)DDu{B z((1(Wur^fEW~b66+V|4Fhh(hP&Rr`0BfSdW%zQBq+Jas%-1)9DQUa_Am$f$pGRBQy z9Gv)By@>OdoxROb6Q7KnuP?Ikj?>gzn_Fttp=d3FyzL7Q;h-slm+P;W;#hHy6L2yY zC_-Bif6=^MyhT;I>YlZS9V#ZCLH zPD{2Tn^Q8=Q@&yPv7NE8+;Wb=eBAOw&9>aMY1_mz4X)`yqAA1qD?OxkQr>7h%%XdX zPV@1z#o?-9=PNXJQepP2R5~AU>-Y+-q)8b!CLe9s+rHsYFcWyMx9j3NdpCY^dC4U^ zV{F`8XfAWdiHWwrD-ztSZ%;#I8_NE1$b8NnyzJJ4B%7eaL;@*5t{?SkLG9)(yY&{9 zVElX32I!7dmq<5_?xLD#0pS?h7@r36jkML8rMtHyOr76MtXa4>f2`z`r$OHQDbOiT zjt3&Pa(P(mM!}T`uO{U^a(;J+5Uxc)O1|a9OPo5f@1m~(`W{0@h(p@Df4(al!Z|d} zb8rP9#b!(xv2@>MeMDc9w{76%6-fB7V0^xoG-Ac3o$ZqlE;X>$#L(n;f0-ku$g?WK z%o02?>AU^57~=x{RorG2)yU^ukV!+_OU$yPC8d9E7hqtT(hZrqMTiySmtXQ@51@@P zhpmF~XY?y)W5!H86?vS}-C6-cQT=;Y@P@I!F1ti>?bwg;PllOGqZ}m!fMrbldLr-o z?)ID(jF{Q@^q41d;heN-4x(`M?I)b`lPy@&Z54Cd9J;C15WjL}$8|W2l`;JmP2LP5 zX+53r&I!h$SHqyk*d}Cmb0dH-HEymD5g*f-u24D(KKykZ_yh1&`feEFH!p|+w8+oqfFY4c;rio>XapP^q*@pBv^4eDf z(R@+z{y8eNL&a(4Jh1*vi*Ut`HR~Smibt3|82UQr%PG<7jQSb&P%;wxR;~8C)zut* zc&F^KxmlY;2+9lf`X_ z>M2G|P0pFs`eInLh-L&^aJdqOwXb^Xzj$AH^U(2Z{{BVoBZRes&zf<38bKt?8~uq? zRNe~|0BXXhm>u4f3vMSb^qbrSo7-|`Mtq{#QLINX4(~QTokGD3lpd0=aVX>s8+)DG zIZRASG&W6h_I?82Xz4Q(dhl;;z_K}~PEMyiD7Vojtlvppc<*TSKP0lb_|fMbre;yJ z;?B`hYduOw?mRKK79(2ecmpMGVqcn7K@eYk&OSe}Ju1&ft?!>Df)Pz4H-LMgG^vd} z(?-K^ZxkMRi8XL>B;=9RBOShvokUDf?f6 z+dzkDew{HM#8gG{FU<|`pM-tq7*@_}=AqE;r(ILx>pM?YOrg z!K{#vC~0!tE~+#KSJ62Qygcfy^W(hF%gTkq^9X1_U_2fWE)Qb;<|A^jjQkW!Dr7+`kM0KVHpb$V3pr zvd+48gf=~2bkcA`LLBV(&b7|kQ_g&UpO;E0o(g|G?)kP0XSAeO>EN}$y4nE|S~~Pz zua)@8rp%mH(a=!==maMzDP;o$x}5qbWsscUHgK)2j*7r(8nAmzy5feU0(zo`d!`lx zW$JK7hr~h}b2BSKmOm%4Hm1GLA`sI+8CPxV3EQQXT=fAHO5t((iAfSLCBQ}CgcZd1 zJ?}nI6e$`7mfMvJ*6o?>TkweCxDTs-io6j!Vz(b#1_HF+x3n4rPKmtn5heNru$B;Z zt#_Rp3m#YUlc2)H3@CT0EXu}hthWEU;|#g}dXX{fWqUc?Lgx+qkCrDKWYRI@VC+-Y3|>F^D$TuU8anER zO>b_Zz+y0=<)Su_#*+oNy<^Yy(aVNwvr?eY==Ff^*)(p#!3Q(3FLL)8hmZkt z$ZA|)PdHUN;drPbW^^emtV@A>8F~AbvmkF6d8^F z_O6}@@T25rBO$3?cCT}n*TtNcp;r`vY3>H~q=%9kPsri>eoyq3_R9d**SifBVWzM@ zj%0|4n9ja#ky7+=-vD8`hi%tI{;@_K_qccKUlO&GKkXpg6asHVm>6|K ze0Mb@;}yu<>`(V9{jGh|=yMA1+R@J=uQkk}-%N`vS2L3SAP|||()D5ov?m{ zXDC!kN$3XsRXRnR``J7Zg!FlYe(6VQlj~++AGQD22M5>Amz{CFIF9*q$ddi}{G^MY zIM$#e-*ST1RRNY&@G2DAL4L$DyV}Yk}LcCsv_Ney5uN<@bUV=}b!Zh1*Wcs|;Y$K%d z(Wia+0tAZUk7S<*O z>J$E7RKq`SWN9mV#&QQuMwD^`UOc-g8A?lwXAEp@?M|ZeFvMW&GkYeL+JA1vIXv4z z+j%edfF)IASA)CGU3X`~&yQQw`)~1>oCQeFzzRnO{+Bt(c|7=#=!?%Uvre%p2oaM~ za`z&0-RVOkJw@)r`z=)!iO}1_>G&~QbG(Hf0-3y$gV|7gkz5?xj;6p7w2Qz;il^Li z&!e1MpA*|oe1XJ3?KzG|=OJ@S7*&z|j^X%mbADY_Isb3aO}3?JIRSm>H_YuX6Z3P= z%W_?W`1sj5iTK#q$;sdIUo|()zcj4cZ}Jm*G4G&LsR8RaDj_8?&9VG5QC04AJo7GN zpOcDASi5J}+37WRz%m&uYxha)QO5y$+L_Jl^qdUnOd6kN?Hw@&DJ~WXSbJ$nq`hwn zsap;4hPy!!nxc-xVd8&Nu@3rmgxoy?X{b<2&9OQu(#-;zB)-k#>JAt0xI zfnk+TdGC;xTK)7SjC8N`ye{62cIQvmeWHj}T0+}{Ra|ny)fERzzSkkNpTf z=>ioiIr!OXP6=hG$(OQlHKe5E;Y3ONJp2I5ic_E_yG8P~~$6tX9JwyWzxM`LwFEo6q2?8Fl#9iNfImWvlx2Ub%^oTUbJ#CAi;F&2aoPPfY3ua5kr^)v>&McG99=Crs1~GemT4-odpE$qsD_eB~;XM<&02 zOQZnj``cLd{OfU2oM8QF0_+lyd%9!MSAxy^cq%1MFmmG+h{9vIxAvmW;bh^u!ymd- z4PEb=_5kfEcw812Z%T+ywHDZO=Kq^5=j+ya z*k>wZ>w8FYtbpFqF3~RkrW~p)x%_J{nj(U`6OT3i`$Yns9n0Y&@NI5oOBQ#fNJNm; z#R>KECx0K%YwpqLysEDhUv_Qc9vOV^dr$LlH2hq_hPPqA;otyRFJG`_Qka7A)+=*V z-$&{9?jRbsp7mnK?fZ^Np;|uwP|1@l8KN*WG6n`=RSvPB(i+%q{cm&awoiL|Bxk37 z9`kF{6ZBcS%iytANC^;N&*$_Ls**0?x(x~Ya{h>xZf*Qxux^M-%twxjF&z;UCQIW> zm!{;`haW)niQ~5_(fss?Wo96FH2c_7Ngz~5xLE@F@QeS-qwKR+!LaJ%j_AZTyrHo6 zU5A-2qF(9u1TR&X=DNqb-SsKL12Vs7ZCFRSg_Bsp2UK+p{YfH-&pfIQtd-EPbY6#- z1oNry8&Du_{rcls9?P8mh09Zh%=tQGfCiS;&N72>=@JR053PDc3KF8*XT%14><{|F z{Nq97XEFgIXMNlHM#j2j~V znD`Pp!|ewjOJ*oMAd`SRk(O=?QIGcJB^FS4#iz@wFt3eml)kb+jRkZ1?$t7^tcKiO%=Z;MtnMk;!I2`8YRXPdzxw)#u-6;6B z)hi7Tj_NL5{XIBRW&3+L0`2crq+vSYR;#K3e9o)_*P3S*CGs-w&)M7k@A&;wp$F9& z=c-NPZ6fbI0?l^_Yz$Z8MO$sqPS%=y5fX%TS-;RTkM$lz?@qzJ(BExA27B4If<*Bu z8W^5Pq>P4}atmiu_YOcu{@(VJw}I81oiB|)JUi-d(1am z=`rb?-sPk(NhKFOUfgz@s=;-oi-i#PTlpv|)}>!5Kf$2Ylnjr) z)dD>g^l2|y1wCj9xQrqn?Rhgtqi*jb7%)^;a-0`(Tr}MQ!;*{LZ?nP#brBV`I_<|P zI}6Ofd>U$MdgWYf)7rdf_Fvz#MUy(Xr|q8@^&OZ?h!SSpw6iKendX z&{fX^*yu;mHeNGe?)_Ci^ow&Mx%ec#lz18oZ~KHiUD$9qS}*ftm5)-n+V>m4YBrY< zvKZ^ts^hBBgL~GWhC9Eu)EB}(%7Rb4RhFzyM5>25PIg<1%G#@^T(n&^rZsP<3+V(3 z2#G5I3-Rf>-1&i5l)p0cn{;9k!9V+C~sO6 zkZ;kkWhbGI5tVoE7rCJJ&;uwCJs&9DA38=2qhh*UY`EG{*KI%gWE^2~P%{_sfGBFYV? zElN=rdl7EqZ7P)8cdl;2K3!x5&G9$~sha@}CFSkRyZ?UC(?ZhZR?ibxos!O3~w(=_MsW;609Unkc)@L1` zs~2m)_t!T|Xm8OTfML06E7L`WwR>$u*h_^H{BNU@S!}gFH07>p--$Gt_aPH;re^k% z@Hd_Fcrnj?(eH`4gbB#~?WBY>|{{ zm5sVRUa1OSOT>|BPcu)too4*4rmng8z``j7Sig9*Rq3+f@3yKG#4}vG?n6qxsb<*ADBx;QKS^;kBy#O{-o^HwR(SNP$6vmvN#B zZbo_oeblQ%uS?pBaOP$sZjJ$)e;~(lS#j~8_(SmpRjh10&acBil)*b;ns^h zxMxk9%bz?tyTF!|n+RKLu@xU!!l6rW?q9*VU)%yj!q=@XsLhQPRRi3hO zsoPBPB!56sM$Iqt1C3M?dlCOT6 zb(snQd0rQMn{se{{h@wXuIZJi2pr}=f9j5Tsh)v(427Wm zx>$^;{g1OzN0G9I{#IwwN`7i}0b~He*R}xs+#13dbJad*-s31VK|Lj3a|Jr%qVt8y z8TuRinV8O4VEsNADT)lZpxXX$o7XP!3rU-ZduKud9@P}praA=|O-GTqqv3@PY8qIA zuc?t+x@A>=ddc)$ocgvI`g>+^i6`xnOo|BXwU<@&1B#zdw0F5U}2 zV7tA8GWClM=V(w^P)nm_ZeEtm02ychg);wauLTC zBVrO^>B6L3vv_5@KWLsbf=C~-gPgb48m|Qb<}GR7op;tYm*Qdt5Dnl-i(k}#!)q#v zITUdyC(CXA;p0VgE}*rz!bP+XaKc}~fSjDHR6@vm!mx zbZbdhT4k!R`GI)Q&DZNl@&%qoqdcTFx^32RU2R9*2q~Es=CMs|VP~8N;I6~(*8!-3 z!4q%AVNGUH!*Ifs*DWk&FhvY!0XEeeg)y1|o6Iz^@^OyXc|Xn+MhRDum!{mT4V~(? z5}4MdBjed1)ALPSF&%H(W-al76Szr>z#%HezG;Wh@!U|Xh$d6(sxj$tuI`Ux`u-`$#${FU!4OG@ri!F%ofW&+G+YKh6KrrxKhocj0xsW} z$gLN9t$tr!(KtKVrbREO6o(Bx=X9Qw{L-dv(>u@C{3@D{lCtvY_bCUTLrY;`<4aU4 zb&tZ4Qox~BRrTO|!4QLKoen#vNXwLBy;dVI}nTP&)g4{xH`DVgLA4d!fb;J}&Fm*P1&0Y5ug z$#u6MNLG2vyR6olHIJTJ(wo=|p1a98A|kTLj6X0>Pi>i2STR9eyR!l$z(*;K9t<9u zcZ#aqb|H-o{wq~=n51AHn;1CBo+b$%BI;Lo&31!hxY{M%{Vy1ogcpv7_ z#nt`w47Otu)MmixvC8*FdCEq3<)j1IwP&C>fl+Rt{hMJ!0~<2y$|@Dz8{NE^l?Ipf zqpsiYPK|yUb4=rwBBu{U_tycjJ1&y?a$&K^k%=5WeI(*$kZpQ;Zl5_tyjgkU6>|HC z+u=CMXJfqSkaxTK#%nt$mq>}ir~3}#CWW@R)rC_{dapyHzEh3;*j(0N=ewlopKw2L zi&p(yo}-{%J(A>#-~vWcOHO+#-1x!MdE1le;*N<`pcu1wA!jE4dm#(2n7S(Z?uypM zeS>+j5Uyp_9@da_A_?D}Z%**R2-Cjhm7mzpKVmx~c539AFGO)#P}rY_SU~Pq{>T84QF_gI?WCN-0PV;eqD^ zb&YPOdspYfHw#leX;;b95}X5E#H4?FQ52KuZ|Xd2xrfgx8+zU>P`5hh7Lb^H^N*_u z3=Ax+&VOv!{(rj>g$lpGeSUt@(s+J(fd3;7zlNd8BvpbY-hjZ7ucm3}=pLW)ho!K*c_MY;ac@p|bMUIGong9m}he-b8htD`TxHli~ z4nDklGrVO`xPyc97)SoYI}PvDtrvZyyXS-XSZR<_^<%9a4Z;LM zi`7x1!aA34FHWn^YA6xcSGIQR!4ugQb1A^X#pPZeUrj8I>d?24^a$)ec10EsGFdfy zG1_WpZ}@N5-k>BA>#HWEr{R@|8|JqwD8^uHfS^{p{ZnKTs!ae4Zl?O ziQtlRf3hkBS$&F$fqH}_(B8q#f?Q>b7&!%58DMC zj#X*?Y~m0c+MGSru+2QL{QOisr`;xtik6^8m-jHO^>W$!;9p~arOzAYcj}DJcD0to zv!tIPs~Q&|VIu6lWTxt_o zfWcft*lN3DmwnXnhGEdM#W5C=xXQBz2hL87&3tK!x@w*DV&4?V0rxHM;gK3{!?2z6 z=1{0-)#1j8Aq9gu)Es=M?iKt1Y|~{0-s^?Ypi+VkT_x{Sw?a8~kTdC{sD*8C5mRLk z^fBIzzCX9zEdnj{EY^zp9gI&AS*RRqlLZd>#b_pEA3$yDWdyfBs}EEaJgL1ZbL;y6 zNf8q|8O;gn0q{;$Z^uQdg{LXRDOd|%o#C8;H&Q3}vn4?e}M{MW!^{amt9|z&LWF_?xIj$@b4RwnDkdQ$AxQ>Rg)q549 zmWUrM%_`QWYEI_ei<+Tx^l;z1+T1AM?JV5*bC4>Y+siM8-N7SR?T;My($D{qKkIk- z<*Hv30T`QWMQI(cAB;I^;wrH_`J8txt?hu_juqeUP-TF_CL3Y=@06w&RlmUf;2qG~ruG%wfI7>c-$AKvQqx$dz;vkpy;P(8vc z?DV-fAf7hmxumeA4ajZ{Z!z$!hOZ6c;m{d$=y6TiobPFyPnR6}3sb{9m8>PB^jrJ! zxuarb&0Q0zKMD#OXVVP}Y6ne6AJ=mGm(oIkt?a4ECQABA(UpGtO(HE4G*uG%5bR8y zXg>x zV%@csj`pFXx;9l32!*qnH87%!)USA089S5@nN6T|8P?Zu=_qXH^A{EqLHCdO&n^E} z6}S~KG`c51BKVlP=+y1qY`9pwpKJkvq^ED{Ks|Q1rK}+%;c3}nRB7w$4&vrHN^pt( z8k$IP$ahh5_HSdOaKvuy#17VL6tMEyY2(LWw=dRRdBnk`601^rxt-hrNOP->iEkh1 zhtN~{ZgJ^rmpUjr7_29W`gB2;Q~^l}QotQAm29KtIe-S-!%Q*cwQMtA$6fa8=B>{V|rWc#7UgP-rEUuJ!gh%-bFfS|Rq2 zX?CnDD;>lt^ou^v)f@@Jr1l0PV4>K%4Gmrf7rJrpOV0+2kz76gGwy3AP8Z3}hFt4{ zA3eA{!t~=ZJ)kxQ1W+!f7K3dyt-4WGw%yFv7i&v(Pfb7pN;fWMj+f<2S+3`DGc`vt~#Ot;RRRxckOelcbi6W!)zbvf;X$H>i&bJW|?>AZ`iq<%;Nm9%uULH^1 z4k50&BK*-Yjtjxm0 z$zI=I{3?=5b*LX}zlGo{=`=L5pd>g4x)hB1#{CWtgQN^SeiNLo#e@7 z(bvC!dn{u&{EW{?CjI*Vlc;{QWhD+!?s0JOBDU}?7Mq_PdF5s z6CMVQD&^f%MF%o$_qY%TrG>cy@qgEnGbs|cNSO62JvYld(%(W#Y7~vuKBM}5uB)L#i1d69&A5~Hqwy~hBT@+zh|&rfrYK3Z)#HhxO0p`sgQ=-Da^6u+ zzZv8(SDmxkL_uv~r>g38^-uQPxp~zZLyyQRb|PPky$6c_B8-n89TWp~uG0h^O$|{3 zbJv{%)Tk7{J6L$kT3x-PPxTh6>#+U~L}yn(_QUl-aY) zbRC>7sU97sU+xmArb{XurCx5Zk~;~Uim9a96bz?4;?0nV{kn2qUGDw`GvxqYSlp`( zNiXYkpp0?Ax`qZX&Pf>pEgzm#!Yh7)Z?EUaL2hmA3X0Wjw-MvUSH^qT6546zB!6;jFE4LqrMss10TXd#)9*;n(E>nl8Q>Ww!cbq0#W)O7aGNR=In! zoGdu^Zcor_sF=>;mdk^%U?T{=l`tMbj5{g}RXc^3cNB=rr6x0I;W>RdvR53{WzHe+bW#z% zE`-jSO4L}ed0Zxbk}~z_&!6rcV~8)x`%`CUiS;NMjbS+J9$~jDs67@5TgnRVQT6KS zSSxU3|4Ym@l{n4d7;aQ{-h_M~runH;wXgB4e@nw-JY~wuRmk{;f1D@ewP+_fFR0G_ z$ia0_jV(fhRR!2kUl;3o*%Zp2ZgHe-z4|b{{q=q0IwP%(!N?(R)ZKt`A>nov$RcCG z&-ww>d55h;U;0;-uCI;dsRgw4SG%b<{v1guQGYozv(3^_$m?%=Y%rHbmKx0_ z1eD*Y>?EwZx*q64ct3aVvi5oZ&eGqza(t{{0L+rD`u?{?pBRZ%p8x(^J!hLS9=;tt z(Iu{bfz9Jr@qSVQhbRbmzj<(EYIWwc0Scz4;POA}!4|07y}x%6)X2$H7j!5;i*M4_zSIvG>4Npdx_wi_z2A%CRJa_%2K??QlHW%Y?rfnktSN@Z%8*~ztZ!&fZ zdK#U_;SeGcLducd7&MlNm`8@HhbDi@L2JP;xcw&4X|YbUT{m>B%)g0wZLtVc_-=(P zRO2MSx%gb^Oh=4s&H4M@Zs@sFR&1kB=j(0=w${*MM2M-z=McS7}Gwc+gqp=wP*$YqK2)Q0-Q7N+mb zylFN{KSbwGx;1PyU-#8*d+7gw`0kBKiBB36{fp6X?nj_Rnr=zq0Q$MAQgHvB2WPea zz2xryGk<*SSy(s5eQtgKE>C6VpIp1?x8W$@U&0L7=;zq) z4&i%pI~PY=^#3rge(n9o_rI}#|Cb~@TpXv412{Wpv?lEHQxw$I%WB!42eai%P#Pd1 zdPLx^y){!ZfCTzAqW*rLD7EpKH=>e7*ypftg)D}jrNP{eT};Pd%KYT$Tfs}BQkPO2 zk*B9L}bOINGTU&d1W>%a7yO8e%CL{d@eb--Yg4r1}AFXZ`){n-l z?r!GK0+*fLqDIDPXq#yvd`x`p&uNg0X|)MeR#LK7eu(GoDunb z^au9Q5b1-JCim(1-1x5*tM>WjK6oivT2QTrU@I@HndXBst+{86)ii8k(~JK1isSQ% zquwYju%+p(x}CUBQj_fXJ4st~vL0e|(J0>s%yUD7tLLZWu;Y1TUxZScF*><}9CBa>ynf?@mUzT&R~L&)6Zw5dmX zo1F>>!sUWG*e{)pZ#hv+o}Q%-5qkbwr9jI!nI>w|bi`NRR`06i&Bha}A2FKeqHGF; zCvc$XCJC~Q`)?#wVp$b5V~F*>x_R}$wo?(>9cnvz1-nmMNnBUmrWTW++W%0~;+`bz z_hZ?QqE4EufPD*AOn;RXfNsoHWVTfCgj*lF^_L_RI6eCw^< z;$_>{F`=VHI!e8%&GdV9La~!TI+ZA@FBYwilDCr0-(_oR*v7*+cw1cnckQvpBMX>M zeZ#YpgKS##aiKmN&0M{ak$OGzVdlffo>h zR_OQsMrQ7JO2-Wb9$KCIym>+z30fZvV#o@})ott)!>&&42sBGbJYhw)Mn3W~ia;p) zbM@C2(t@5-UsdLe`7rK+aa&w-<#n^nlA-+Vau_*lSXQ2H_;>)Di&DHUljP40vvOV{ z(=fmIc+c@S6uahkoK(G>i&$SC>rFmPCb^a7G1vM_9Z4_M*MzmSJJ*FP)^@g(A%C(y zM=$wK+3L|Wn7*4xd*ZLaGcr_tHr8=1x7o((BeFVTTeN^$Hg~X+F_Sra*UY*8WSFcT zFJ+r?;}^&HMw{#z5ac-bHfhwX2<`l!pnkQ@TzOzYs}x6nd`o46+oOGHTu!aTaXjv(y(@SR(5JYFE(rI{sZIyT*&fCMR89?fXZsOXX&`J4POZ6K08nr2;2ouN8|#N#s01X^|K?=-u8 z(ViBpdp^-Hsq6L|{M`;fH0*aP$J@WwGkC)D){Z+5F&go9Q4l0eiC9|0wP$H!QnIT8 zk9y$&b7Ysi{M!Jl4UcMR_~hO? zPt34%!WUQg_z?t7Qye}RLOq4v@x1VLAo7sVRg-PD;G6=ti8|w3JE{7gY0!{o(3|*f zN#RW_I@&pHQ=Bgq<@?{wKdmoZjvST^*&Ynh?|$mqyhc)-?JSKP{gAaa9p<%ZJCd`^ zq%Am(s!e7~iOEtIXtn-l3XGdxCJ z%RHA-)YyW@xy8Z)HC*8ms>M$3O3-sldM|YU;vQEO%Mte=%_m!O(%i#GKPkM%$wFqm zb8G{l<1BvfH5Pto>MHK0>}^oN)v9qQpMGgqfaR1b!qiwgI{yVbUwVd1S3RMfbTQ_S z5`v@FBT^!_uP_)XqX6Gs=kEdwbA65eHV6C*erf(V#NPLm;qeu*_Zw6g|H;N><{5&v z2C09REmY#7=|2U%pEFW01l2D~wOFj`lS!RKOb-O%o3#9m;JAW3M}kvqr`*a%GkX%@~ogeZ|+ABBor|0f?a`brEgr<$i4sziPL12xBuz7n8P*5Seg~Xb}%FQ zE+}EQ4|ECon!q+kChORCXJYs8B2}{3_qIlZqn()@q!ZPOJ~PNpg)7`nzyT!j z+s4h2QEiTSp$Tp#;3YiAxex~v{in)OtYaI|E#{6}U0<$M{e-qcgMjfBrR?7&%#(l7 z>wGtpr6|uN(Q!V@JbCf`wbE2Z;->4jZ@JcJjcXwK^+@W^yH}-=U!2MJ`L}&m;v7~g`Dn=3ClDLKRSKwnmyb+? zS``byUW#IprEuQ*6?XwAU$dF>&39bKJ5Jm_OL5A0Q+PIC=JXI2R~Ov%)vFuYo^&=6 z=R53ZL4oQ4FO$0lD=9``^xMNYm)AtMeEn_d1RtJjV|tT)LY=tz7YX)0`XmzprSL_`(8K4MB6(cJ_U5+nI)1yd&tblu6+&54{w$%qb zy2nC(!^u3`X;VNYt3KHi)OM;GsL&Qabz~MRBmh%6uS6yyMR!_qbi}y7xR-)U&+v!L~FxNmRWe zRh4kYS>R{=wqbY{TGFV!Q zU9?X!rf_moDb0HQk1%ravDxRAwr4R9;?)ax$r&bmvinvE$5Ud;8G%3ai4+r7SO9M~ zCU(m-p2o!sdZ0iH$$x^nMh-hViK7$5k>>_=ih*H8gDeq>k8RNnWUGc!T#JAyVPhvY zAFm}FA`!SC7$b}8*Vi7L5&&a+gm0GH_g9`MxMRLf0i#i+H`Bmtpn+_={FLWbQsiVk zU7J&)>DRc_PVMp=+yW=G1p8ID>0S-3zBj@shjmg*GwEm_#vfnQmaP{59h*`y>VLQD ztp}{L?Wx?ALM^Uq%63@f6yR-KZQ0Hq?Gz^)`>zci1ic=n@ z+GG3IXRs? zayJ9zC!L&%Djx3hJ&7J3c05Q$;i4SL?xvf`MRq{LlYSLfBI)v8i~b2s7TXSQe|Rct zN3D!ozQ+Ao%+Z z*WAL2UptFI4X34e`B3(zyKlZc+m5)Yve^llbL#yvdBTwcRAi%VXx&id7R=6k|52qU zokcKvaee<=s(7~u^~!cJw*xO!C6&L~A@4P8*6^u?ULx%a$F>%S;Iwa{e5+g$YIVu^ zCr@`#PZQzpslFveu>M4$IWcoeYlrvWbai#+tZB^namk!j?Lb-MZ$xDLyLZHvX;nq; z&)cv~mJ|v86yM0T>nodA`RqjaAyraZxg}GTJCr;M`hnhv{$j{$u1I*C0$&Q06DPWK zXk`G&fXCBMgR@5pL>yF|h2rULNKGwYZT|CG)h(>NWNT}_VGK?V_CGcKybgxj&l_Ow zVN6_0nV~1Mc~cileNhe-_^doW>T!|kvy{atygL~PRi)WFZ08(I+*fS`=Ip{9KwdIF zHo+hC@j=>uV*#P~%sIaWSeX8DnBL#^Z(ei96-!`FtYFI#6m{u6a=5@t1TKd zO>FS)NZQbTHJ;+;*2$bwp%?MO2QXXlR0bH)?os~(${)o}mGHP|ToxLh@|euAYNDaJ zsx5-Ar%<5Jpn2%7AkQmyvyS702s|>!zkiKHfi0&l&)h6mBGg31L}vm401f~|k_VV7 z^4{)^)e1AZp_16;MZJUokwkYaK3_-s2kVzlI+PQs+%g&((~968vwynyn9aW*4%2+@ zTvL7{%x-6&t}f>WM^@d>WLD}^5y)dy>WVpxIbLY3hkTamvc^-+%q=4;L)xa=A6Wr{HW^iR2v%t7qW@FRx{_) zgUOxQwp(!?mGj>o3a1oszVA&mzhbpoCYI=o>2$5q7MdEB=d%irAoGf@z~>vOXn9Cv z7j^{W*L~lgx^L-{lcUm~Vk~;>#W`O*1vgWVsWjfN*nhxPKzx&ju&2HRS=cJ*qx+>L zjik}>EpIX1pRjYz4ezp!gxLtDXr^W&E~v+^vU0Pp+K!~Gyz>{I-@U|!2$Ncjk*ntU0M)e}oS)^z;Sd|@%`%M{&Xx#+y5 z&UV%+LFD9cxUar)nn6q=9qgHDjRk>pxaad|)-h6rjL9jnQ|ryWB@#^qo}CL{Tv&N0 zJ73#6-nm$h#t`$i4W6*<>-kOh+Ud$7JEXmY%^%qX;#9%pYQflV)_qM1>Kj>)y3b7v zTy=7PM9@C0;DsA9>I4#roc;YNq6rqKNR&8ThZX+mw6*&g5!B`y{h#NFpI6c9B+U9*@jGw<6=J&5@beow?HvaCR zU1$TxihwLFw+nI_kqvP2mMtfkL8WnBj-?ZN_Lzu?DB}y0dZc^}R`oraUElv;sY5Wz znH5lvvsI3yEw4>O!ks8V;w6p!$(G@9GTG#XqXOgndMM7m8&55>no3UCAw!t4_iV*s zTYT7DmD-BRe&H_N3Q$nvHFJNWAWQe}aYAHf->yK~(@z$GR;-$_I`5~|)JKxiCv>c| zb5x{&V?39!c!36uO3bN(S+j$KL(s==Hp7`TxjDA|g7I5^R+8S*Ds*PT>SsFZVAC?^ zedB>3CKgCHaQe4Cme%dpv(FugY;5fMX}n=NO+pZ`<>}nVCj_5=}}fO$rCGCvr!xyr5<>ZiwM)%dySb$gqOY778w(SZe+A(H6Q)*n)>_ zSlu*$#qmKZo!~%;?>QTh?#8$7?oHE_K8ufvLUbhbKh(DGbB$07d`&i{oWDL)xtC5{ zFhcYFNk2r%Y>>Sn%_D6`qfeLXDTlhOjfI?VE#T|&b#hkctj*yA{uXOtm~59jb6{a( zOgur8JQK=iZKmP+dtPF^w($u|L&LS$>8GNpLkl$ql zNcZiFDY`)6-WZ0Es4DR5Tv+T;2$EvCkLNW;H_)u6PDtGO_wt(CuD@fYv-U#H-zG{l z?RyI_UzGBKL$w;Q=-}5j{vkr*r>-- ze9#T^bPzQaTUyo+=8>gYw|6MV3woLc4%Miy)2c>hK?jv}?z~uLJAAY0%rh7?o*btKw z-IG|+uPU08a*jUgst8?TPWBV1!_e86gxd8wRcSG>aqiyutZg|YY|i5^HQ@B2n_k(l zR((}w|K?7q;Le=BlUV6VwVoHa#7EI1%1D^o%3<`=@_CT_Gt$ZfQ1D8TDaQ#gt#2#` znD0Pu^1X;#R=uGGz3xIZ>7<|Xla!Hv9615c+fd6V?cF#3F;Vy`umQYw-9hivG^tTq zp6Ql7bSS-{R!psc}FsBy+c;^KAXH5ZNCaog{SzaC0^PUB0lC9urV>+=o}$FltG` zw-?J*9N993=JeYmo-vf_$3auRiCVr36pl4*!Z2{?5 zZHc^Q9kJ+pGP~qyx_I$2Q4roKmy-3Fp1a0l_DL_inmH_7bX^u!UmC%bipJ1HldISAwGLVZoG-n*iEIuN#b zJpTk=L0wBW8vWgXYVw@QH!PJux|)RBm3Bh6;>@V7?d+B6U*4xx;7ix0u@T2(rWpU5 z+KqD#p{il5XGAv!vRxSi120eLS5>_*YtFB(GK$HW6Ej^LYQ%-jCD>pj(!=L3GU4#m3nm1y8Y*M^%RD1ca(A0EBW}RD;#q>sAoTfjUm0~DSQ8V=ih^n4UAuKvE%b{KtPM^$qJH!YOywUzQPt&Dkw{HF>Dm~BJB66d4&mRedv z$nQCI=^XXdPX+ZvRck<0j9#ZEkj~+qnm2r%jWiRCP>73t%>Hj3F2#sG2gfKO(aATx zN5GbE9TIcwmtn2`x~Vt?F?QE)*1pQfs|O!?yt^aZHoI{o>{nLuCPFU<`KJv+aJDj~ zOM6SD*jExUw}PoQpx=igVA@&go0%0YJ~o~@;M%pksALR2Xx1lsxJt}DS5tX@@d+qRq%6Ka#j zPIex8Y2Yg7Up6b7!Vxw~AEvX{3!kmxXSsSU4&gWb69}-nUhuDi`t$zXH@8pTK6&_` zZ{(lt z7VFaSbfLxj23{TKzCQ8|kOJOoXnBpF5X?SCkfXqLt?@cgDwxo1pW^s)?WT6m*i2JF znMd@wCf#wz4Sx9XosM=B7oY^@aP5!>&m9@r-aaN|%zl)RqVcO{=$U^SR${?VH@WU^ zV^i1MLkriWHwt&JZ$5spAkb9`P!l$y^ibo@DFDL(Geq@l`Yd@yV?z!cH`&4mfHe-d zadF0I*Z;+!5J51hPvRB}?nz;Ht>=ebS21yiPEqC6j}7nG0Z%YoR#y66_O7vd1=K?{ z+*g@~3ffn;HMKO}nw2V_5&3H~IyXBjU-KL1vZrAHTd)aIZDI+3qFKF&ap|E?cI|xA zxm$KroiwNqS?3rir6;a?Z>VP+1l#fTs(O_zmvrsxzv%k#EGQ?R5{< zjg;Ti_DGDl!CQacz|>7fa|ilsHN}U1v#H<#P>R1B#swAW(ZM8x52=_~{)6f0FOPCd z;@He_AA`jg)P2>qK)*UJ5KaB3%aODD^G^0>2EVzVhiiCGuTh8}E{xWHe8*$b0>c1+ zhd~)uJG;koh?SuXLpZ-zQtz*X)khM$rQ1<{hfew^JeWt1`9eqa-^kVCj9D-%#hBVz zuQb9tx0e+l$Q3r`$`b*;#|@1*?Q)cqTR~$Fx7Ub0@w3pbvn+BAU2FEYn`$0$D%liL zx2Y(af6*_JzL<<{z>JfuE7I#=54CIMrq%UQufIm-+fJ1}k{-6<_K`3|a64BPl#ALL zoldGND>C@4qpTMe!`|5H*BKaA?e<GSATX z`AueB(rYF41g@v1+>-`xLCOr``ze{MQs@1tIx9aJ4fbq(ww~=m8Lp9SgUNeH$J2J$ z53B0|p#eN=j^Yji!A5)yCTEKydsu8IH^a%^AE zrFx%F5VmyIp=(6CA!qyO7H#@^mNioYi*t^DIxi!|n^(}6hC(k=vt*K2xrJWiP6|L2 zl?+EfN8&1S=z}BLjeIG-8=(Boq=lBq(*jvZ7`B%?xm907rnitgYQEqwDRwBPIE@hi z=CX$a?r{D2`r~`3k>oa&aABqpX?Xc4K4|L7 z_pTh5*@$7L2-T;^I3W?MXYhb5czqY_7!JOy=uhx=8(#4wo6Vpmyh$-FZV-1GniF4N zkjeWA-A-N=-Ldp2E%KlvWDF?%_S7$A3R&9x?N@l<`%pnQbE!u7d26=7hjFlz~$jd9( z%Yzgv1J_v;$v|-fms@i!X{G{Q@RcD%{fc6QM+JPU7F4Rfb9%0fYpTXG(K`;pO{%1; zE1=EIs{&)<3oFO3F_?a4BcLlTslZx3NE99ljYgjh+1i-hACy2lxF%1@4kQW}CeL^#(FRM=@yT=*M+#F2v zGxNGO!{`}CKBpWtU3r<~_SnsuFy=_}(Yw2Z7G0H|~i_o^@ z?CK&T&=S0Fz>g|x$Ssup+fejUTHU3>&sagsc4S&g=Q;ka64RL?TH+|2Ba+VowoW1N+`F~`~VZNb$)iuD#~ zH?$v*PO_6_|oJa=8lugVshdLSTv&d&p*B(Ga9c-u{dOm;jT1fQ0 zlQ`&Vz0C0(lfY-j48lZVFGm#p8F;Sy6_J1KNgj_|u=nL~)UcB*qb zh^)HBhDJPz_d5wuExsNpkD9A_#mei^uD!$k#sYi|9JqNX^-Tpq3H!RpJGB|fN-=%5 z#{fRf(r5Ilug~~wA3DCKp3Ql7esX=<7I>oMTI7Gey;z(f=c&V*ZaE>*4x`_Yfqw53LK`g9tN{W5uYd92Pkdt%NJH5kNmt(bV#fhT0OT#kPE znGM66dwM;d6&=No+3i;+Dp(;Gm$8X%X}K(1H&OLk-5<%GNGR5Btg4af{ABQ(C~Tk% z+L8o6ip0X&cp=f zaZ65}Xb5dee3f5iUcvC@ktf5npHkg??m(|fWQ20M$KmjP8r=A-j5b4|uqD{=O)jU=uSrNJBcB!Yyc>f%5-{#t@;6!7 z&hMt16Hoz@uxZX;AtN(uKjG3(x1Mc7n-puSt$i5rWQ|OWRsIt9PkBu;TTyLccH1b2nKpK$ zOz?#OyBbd$wV)+ugQtSl=WHIE%QAhI&Pr`TBF~)idFpD9+KJ^tUBXqG+JZJSLuss5 zdSk8Z#BK1(TK7|Q>~YJIB~+Q;9Sa>?CG)jI^23XiQX%?!pV#U3WBWC&>F?~8f?${E ztjsb|#q}vGTjW0XH|i{&iYHGOu>o^4Ac8Pylka0eo7z7nvUPGatH1Y)<4yPsuBx{s zS7a~^CY!>4m>BhIW`vDB^82N2T|to0&I-n*lyuDfeA5Qe(e~BlDM4wUX$&xVs^}Px zq3)uHY$P;sZ4bY+b*X1hqvFar=)uAZ$~0@ z`FKH2yG3rfwu%_f_PzljR$OiEn6b~8j+4ftj!>UhZM7AI@x{qkyW`hqQ&s*9TNb_p z<4(y>*#QL5w0m2BrhSL)^vv3tkR*;TT<(QN)v}K_UUh#v$j?o`#@JelUN%SYPW)AY zDh?)-Rj@GCW(bzPIcNFKRzV#+fMQaa_C~dZz_$Yi+;b)Cf#z@zS5Qbv;i&V zmwOg_;&|E8&>6BJNomGm|3sGU=Jg^s<3EKNLp?#H>k}8SDiXH%*^@(9c89Hf3go^?WoxiU#L8iTK1kG;T4a5cQ(5_M9rLeLI^DLXo0~iR4Qm-pAoG{Rk1;T?U@@$W# zs>Bk&7`ZtGcAhH8@*+eK~+cUZAqHyj(IFSFITvm|;QSX_0c@D9qWrRwhUEN))v zHIH%7s}o`z_a;$Ak}~-&%i5nBe=A#lq;_(4n5LJ&!drT8j(rZCZ6GAZDdxF6e$^+C0}=U@7Y&qPlq~II`D^CJ%NO&~ zqY)V>mTzyxO2(=zQr>G2Jk?Vdpxuh9tIR$F2w5H1UMax+Dk$IxsC8wj&3L4!OGjgE zi$Qw^>euHODt0F}F=pc9$^@8^w%A8@Kd|D$6pT`^lA!>A9UxLJC3AZcvQMOA!={sr zg70i|!ZUJ3Q`qdLLc*^Iin!jd+uBQM=Q&hpD}Gny@XxW#$^C(!-Ei5;i+-$_(Z})k zh;Dihvzp#EnRF#!AhWr(5voa}MOpc+pKd$9sBr7RXUdK}&`!f7Jc7n-^!3xlyFEm* zHCagCe&B&&>I33-ZtI)E;;XP6HLJ;;Kr4fb+QJQ76zZ5E_JpC?xpKVH6Q2>)_HJ!X z)C^NbF0YLBT`Uy}yAXRNmO|`z)Y5Z-YG|GITpUU>(-$0nAXdV_epaGHW%SdM-?D#z zloWyG%tSS?-=|YpVNGPa za7iKHUWSe&<5O+87@q?q!!H{L5Z5Pi*fsJLaT8=}Xr4oc=koOVB$H~xRZ0j_1oSH@ z)N(tCTrb$NcWXaVo8e-Y8S%mj12QuD$@VSCjalR!sn|u>oL2o+FT@{XAERjZU9mUW ze)oGitnYRR$=F*)x?TCh z&coDc>IshMZsLH)uTO{53~us)U)%`VT7n}`Py4~a_c}4731%`fr)U#{ly{e`L8!QA z1+Vv+EFW;wNwsmSA-8g32#n4bgvOse%58h)7GCV16t{Xd&Ma|IWyCXkeuDx2=l=p` zud2wjztYgJKBkcS=fV{hy#+ z>pwV%Kg|kH`z!ieYV1U7D=Kq89+JE}_eghe2QcsmKR(^|!kXgA!bG80&G|kPphrr3Kzk#DFBhznIzpYl`d{O;aKWUD3et269**ZBL`@h=z z>Yz5iuTSbNlv0X&DJ?F=9ok~Wi@Uo7cM@nzf#RjOmtsXi@ZiBI?h>5f8iHHGrv2@^ zv$MOiJNxd=J3BjH{$cX)aC4t~&%Mt*=X^e&!%t}A3MoU69>?SLO{l|}NZ8C~E##@lPsJ>e^7Op*++moiQx?~Cb+_2}mYQzy;iHC^oUPi@+b|wv~?-lOr ztEttkD1U6OF;6oifs?w}vBFnbm<>WxP(DGnC$2u`bcV|sCv4WX`e;Q7Ena`8c^%QF zEH~pQ5lnB^UqvBYc={A!Ql3O2CFz&=Zxf+xwtcC01W;;!v)Re&nu8pD?^e$1?b*CY1#3JW6r{w*^4hq$ zbx^P^Sb!I+8>+exgv6J*u8*YHjc&|0D=LC5^6&+cenbuZ&gAutRD;7d;&rHtu-Jc* zAjQmNZg*K(!y8Z`*7PPFJ@ZxgJT%9lLY5(`RVnvYl%g+xq9^!Cp^Vl_ttE|*gLWMo z{xGsW7SD9zwz%c#vmNn6y=J;)$W;~J-m>vru4z+g@1Sr`>iT7*JmDYi4Z!W!7vX&O z@P7=fBor}qE^!>p^gtI7br2Jk(fT5Tc#?!|FcqslQIMwW35thbRP0W@rji6wG?-LU zmufWQb)31vc{r4!g)AQ3X&&qq0krPsDS8g3{shU;?LSK#$gt$GDzII25VFoN-Hy>} zKHauXl3-!8|9!k;Cs|?Uo+oJ4dvfm);lkt|9Wnp*C@!gr{P0Q5RO0?zV_$>mY3_73 zWAQ}8i!b*TL)qGYoq2qXdg=!T3m}ESrci-d5?7+CL(@ZcL;n`1)Yp57jzPtjE%{Bs zNMUOT^Vdh#H6J&oV=eUJZ00Jaf5cv3Ic);*{|(lW`*B4-*vdh&=rr}H)FdT$t7J~y z=KvswRF2^NIix$pG>=js&1l&48f)e^@Mq*q6O~AQ2^we+0Bln0W*EtxmdqpNGm`@~ z6yp0w4C`U5P4CP)8!h*Gcxwbno#u23sCk`bybOO-+sf%hNqwaQHr?OFKbh!$k+fby52AdUaoJ1BkVRrERYf&d+&aX=1|i@G4|=VAEBvLE6H+ zzFY1*Mg3&#;)4DNYpzNrA4?~3_DGl2s*<9Hu0tx|*4t9SjrC|{0lR8Ssl(bvJC^WM z%7`5wLJiUc0UL9-Dp^LI)0(MqeSUd&>lj6TJFV8(?kFNWaP|l>cN`gUKeeRS_3E|o z%HvN?5uk(OH!KJyC35FU`xEZEd&2SxSg76r7qilq{CyqwyiOYGPOC!46AE=K8|!Vs z@QyvRud_wA7n~f z4_?@x%;yh$S0$u;H2pbj{S6jzi;lich|b^^R$+JyXEU~=)p@Ow zo+=<>HTNai#ov~<_XUqzca$QZEkEMmu`4dZFmPfc93s1^{UEw;0tyIdGSl-QYnh!+;w zbF%4MKS^MUDUH~cd^-&{G%APutZtg+{U-M!!yIQHDbF@0oqC-8oYLjY^{=y6YUPGk&re0ie*a&N(+ zizPSh54~vT%alpeBpvKZ3j^QX(kU2Qs{t5QTJOl`*bzIqVv4Y9N@HLXhTikchwN^#7#6fPbrf#;oqEGvX@4I)r;cXnG zh4g>38hspDsQOxtnQBni$#qW{XnycSr7=)UO6l|4Up4ih>;gK-#xkBz!>)wEM&bsW z3a!0MUB~?ZvF|!_C5Vym-=Ey-1z72|=LI_Wi>wr)>`i%l+dAcLK}B^}lJ5DX7Da?R zP=QsPoo|Yl5t&3l`YJbb&+t#sooa<(b^#vXl3lI>=|LFDX^WnhBB%6P--*8$Jg~ZuA|HW184v(NyIypxzM{IHm7zoyms?&vPUA52 z`c-IK?z?Y=aisIFIkeo@r=^s%^Od93v~*Kv#|0n~^qjq`qnZK+B?~GsJdE4tJ$)5% z`Y+?|?VOtDyepS5WW@L^>DmAOuQs!{?uJ z2gt&obNTD{EzHhPi*q9{_3j55Q`yc`<_}Yldm!E}2lZS0p8pH2)Y|`!W%n5p6+TsT zF?N2F&r4xBxSmftw1s{5v8(7Qx%nwXszJUz0Ac};OK5c~T#H=Rr@O4|>5^HM;H&c& zwT=U)9~l*>Sb_EfcGy*EXXhEL75j~ljJxBmr9yjd-54Y5jv#>D?s1n`O4kn^KhYg5 zBs*HN!!qcVVG0=hvy>^>hkvG)JQ!TsJd*#F_iT|zp^)GHwwK}%s-_-5>i?!NMyN8d zf}L+2MZ0)QHB^^T+#SDnoKQrj#Y}vJcWwf{h5Ji+8}H#41+YBVbQ;HLrRU2;mYgac zXVoc`%3kLFAfYk2*iywzV{dXv)tB0(yv{qEY3{i?q;!5~e;5%i2@Sfprk$PVnonA? zx7WM!wNWPXvETRdGHx}o=yS#G5HVUwPxqdYBtpaWej_~vbdvT9pJXySM2_4SF_`Tj zCfO{Ug%$jQ3rg3kby(YU_@_b1XbUSv#5oOCVj1LS<{1oShsqJ7huQ^WPQsd+UhGeK zm!)-VqF6-LMvOI_wYn_RCTvo^C=v16?MFJo-`t;Mj83yXoY^q<0*Nlgs?>>$z4zN)JrOnSzXf{>WYQ67&FKG0Jz%+&4 z;ax>VllfR_&VWFcbm{uD0~VqH+=>*tY7yb;Ut$O2k=zY86VbP^XSo967xB!B`$Mu|kc=ix%MmsS533(%~< z1c}QD>5yZmq1N1}s`!nAQXzN7T0&l@c0;kCPa8meCYOY$>*ZaGv=?TFB|Dz4{8__| zXLpE*S%V~AaI)!@#|;sAs5cSX=jdicQ1e#80Z`f;ui?N7?m$cBj)U6HOKtu^WW$=p`4D=mXR2X1CwF)Q~FRXjGY5s#aTukkQ8 zy~2!EJDi>@-e*Bxe&%i^0&_i|v(sP%Cl@U08I~{a1ueJ)8$BbM9&)Y7{m{_$M>1GPjp3RX$bFZ z+<7oZLs~rl+T|(z(zczmx9o!3{o9r)U!Aydo?pjQ6&AiHko+Rm zfa9-sgp>7@J5g44C-@Jn?+G43M6@6+!1iAVyV_Oz?U>G&ljl^5b}$!(eb{=zk0p7Y3%q9%sy9l^FTLwtrJpzYOUq4I5c;>XkrG)$NH>2m zT4#5IP~9tW*fE>odmPe}lM}eet^{;(=hW5t<)7ZSbUu#@#lj)-WX--#X2}h05OFg9 z3u5MyM~wRWDl49Iib?uQq$E{BtBI?g~F>I>WVG&)H8V@hY$b5e!ft-}>us`r4fxgZNW#VO34J;;-p8MiaL>R!H*;XFIm7(aau^iu);UwG7DX! zm(gDwenK`sa|{w6G|UIcSjN9y%yQ)CzKAf##)(S#ut?q(+ecGfGCl0dR-QeTl^!;l zI3SvYP=ds2eVV3adyx4c|AijoNs3k5$Kt%)Yf~$^7}fMtVR7|MaZEV0vaqD8uo^zO zLZlh1#uC@Hk!NdZzIK8B&Io-;YSOpsnN8k zj6%J*!yJFAVufCP{k`Ro)nmIcjmXxQbepBc!iMlkb63B+zS2t9{2JYPGCj8wdk5(F zMei*yHBb@Yetu!rHYyV);(Ecxs`vytJJ*Dp(VC8h`_ts$4L~ZbRAm5Cp*kOSG!DB| zdwD{lpZRbohd$91tf~VoAAapvmDdlFitsBnLSRHOVCX7uFn!Ctb8li% z)!;o{jxE@E`(V2?rN*Pk)ikee#;a6xnz_`{?8ZP&mHnfb@4~Jr*(MPl-#9Ldu%Y@G zed#xs40;Y{pp&0;*|JT)lUg*)+F9A?Mw^JqskbLBjjsI@F;2_o3+!Gf8^z8lEVnnU zp*{ayjC(5{^ZQfjC_0TmBvRNHtM;>8$g)`He52jHdQU^SfRWlnuIE!5kN0kFkNX(E zk=5E2D?mb7db1jPeg)8Kd~+VYN6n$d|H@y%^Rh=zjeD%L?;B!IiD42D$%KByrOQBdT zgCX=dbvn7^9-er?@i~4ir5Ev@ePY3eYGy_W5p{-g;zCOc?m>;VKo=vEih|C}w!On? zVsQ@cp*gX!;#!Tea>e*De9ZiX9}Rw9=$RvG$dFG$8?I5=&`aq%uuGN0U>RVLHjym` zhLtNNrIQy51|j6R^EEyKqB-|ZfgXE^?@21N(-v<5rM4`g|ue?H{q2o$SebXp&% zWE0#ijqEoNDVB_%p%Q=;3-8TW&};v0F8%6|ube@X<0d#o$0}UL_S$Oc{5MPGk>1(9 z_#7a$f^VpVC_QoT37v@=4o*%Cj1%XhT5jZkVno2rd-!tc`SsVB2mbz)(Wk!=Ja~tQ z7oD4N;t~*mjhaO<$B;+wR;#g`RE|dCYo~Bs{)9*M*A9N{4Fq)$j5X6VDh9Gci>iRZ zvlWnYqub$b&6x)C%0XJc%?qKHIktFElljv@a8N;FP@1 zkKqql_z^agGC6w^;2HEvTtHJ=JdFIULuylg`n9|sVFf0(QevNxnl@GDL@G z$=lQK4)^EkiaaK_{-1>`v1sSty=PFEi5>ve(dE-YSv%wSdRvRxF_)xJy&7yX$aAuWn8AN>d|9T7$f7XeK+%^!)~SW3a_*NxPQ*c z!A#j;2zBB+y4#q|Ia#hoi7Mn#vmpKxJ^#DosFNeyN2#FNlYEgG2d=kI>-`(wb?A=0 z>9$Q7ji=5QT5|CT*0@tPyM-U~o9~H7RHB{5fWFKMO2^2k+KNBHGeh9)4b&EpYf=Jv zqCP==n#^M){e_25w{)zBgi}iTS2#PK#GdE*ZM5@|R}D31p|fqZFev-1hX@o<4lYpU zSSk~~z1@-g*3T<~DDvyb<0`Gfan@ijXNc}?5}i+woNcsDkqRZh*yJ98?F;p1tFx!O z3&Z3zR90V=zbf)&!6OVv(nxaV7G}mXs0(-Oe!2f58nx(LgA&x$3=w|p4CdRBEuV6A z39g;rGk}g~h-q$|-WyEM=!&<0=*V?p3ead2ZX+g3i?`Kur{}=#zzlzuchZZ~)X0vm z?-dn;@&$L358`hBQeu?A&s^}gXHN(Y_>v{^!=y#4;b`ft^L4ziUjBQq%GQ(9-!vYW zcDkcu-*hqLaNyNZWiene@i4Qt-!6htT6&v!A;0a6;KA)66$Qq0j>_Py!xl2Xr={=7 zrvfMUw=B9fl>F9I)HZ@2ni?s^pZPHoRnQHqMP145rn(T4XKz78yjjl-VS za_lv425;d!ACSsp+=S!(n+JAUW;JlC%qL?W&pm@GdbrbBfCD;^?99n5dD$gw_HTWY|5@ zM@*$-ug10*?m{OJwEMf3hri!j{itl;raY#>wNOx4IG*!mv*!A(dCCVp^BE$Sp@>bT zU3My!1WqHOm6XD^hf<^^eTiI*8Q+qAvK%R?>c6@x!{lKialk>OPY( zmmbNP!~tdB^1k5jTXHC2FWf@i7em-u4RkY9DcOt$dkY$LvXhhUD|1y1ufgY&kjOt1JTSrlAFe8`3QrI}@J^a<0zPPf&V=+ocs!57;`b{iqWY zd&6t?D}#lCw^GZ?-(7vm(84E85`607U86-SG-FQi(AeSRQx2kKsliB`BO@S1U(|NW z-pK9e$b|9OE`NTv%W~&)j z5z6-TARKQ7=K8?5xFD~pqN0?|=ivF$wyo!R$Nh+Ixz9->GflqUv%vr<9Gv^Z_b72( z2$_}je9Q4?XT|RfS=Apm!aub?=sShXP6b+IUdvzT5!&1p(X+h#LJ@r!x?;_uW@$~l#B5S7PmEhiS z9808lX2XulCHetmD%DgVXqcz5^J2yAv)1^*!hXIuQYRQu*p~d-%KE2M8D@e9G3ce=Ohr$o6f1zr@-0@WJgr zt$ke1zWvzH>`8)FKy6)FMUghJF(F+c?+5+;pl^ zlb1*HZ1?Cg=PTDc#u^I1*8}0scsMR={%h6M26$(W-B*1p3qbpcB)3C8IrlTT z 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 G=l=xyn64@S literal 0 HcmV?d00001 diff --git a/agrifine-extension/screenshots/data-ingest.png b/agrifine-extension/screenshots/data-ingest.png new file mode 100644 index 0000000000000000000000000000000000000000..742649a352422867f6c59d49526b01324ad0c164 GIT binary patch literal 33235 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 L@ssMu4j=y)A(KA> literal 0 HcmV?d00001 diff --git a/agrifine-extension/screenshots/reading-list.png b/agrifine-extension/screenshots/reading-list.png new file mode 100644 index 0000000000000000000000000000000000000000..da446221e9badd533da54aef5ad9ef36be2ecaf8 GIT binary patch literal 33490 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 literal 0 HcmV?d00001 diff --git a/agrifine-extension/screenshots/sidebar_initial.png b/agrifine-extension/screenshots/sidebar_initial.png new file mode 100644 index 0000000000000000000000000000000000000000..d2bd0204868be74c2f45ca540a9ae568957f8a5a GIT binary patch literal 33496 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 F{x3CD4dMU* literal 0 HcmV?d00001 From b7b832764dbc14ed540de4c9d8ae0ff1219963cb Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 04:16:30 +0000 Subject: [PATCH 05/12] fix: add anthropic-dangerous-direct-browser-access header for CORS --- agrifine-extension/src/utils/api.js | 1 + 1 file changed, 1 insertion(+) diff --git a/agrifine-extension/src/utils/api.js b/agrifine-extension/src/utils/api.js index dc09b16..639abdd 100644 --- a/agrifine-extension/src/utils/api.js +++ b/agrifine-extension/src/utils/api.js @@ -47,6 +47,7 @@ export async function fetchAnthropic({ system, userMessage, maxTokens = 1024 }) 'Content-Type': 'application/json', 'x-api-key': apiKey, 'anthropic-version': '2023-06-01', + 'anthropic-dangerous-direct-browser-access': 'true', }, body: JSON.stringify(body), }); From 3185b04ed695a5629e9cdf1426d170554c7a9261 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 04:35:32 +0000 Subject: [PATCH 06/12] fix: patch all 10 code-review findings in agrifine-extension - agent.js: add anthropic-dangerous-direct-browser-access header to _callAPI (root cause of 401 CORS errors in AgriAgent tab) - agent.js: handle stop_reason=max_tokens alongside end_turn - ag-refine/index.js: reset isRunning in a try/catch around agent.run() - tools.js: check res.ok before parsing JSON in toolLookupUSDAsoil - tools.js: guard p.name?.toLowerCase() against null field names - field-profile/index.js: guard both lat and lon before toFixed() - reading-list/index.js: escapeHtml + safeHref to prevent XSS from page titles/urls - dashboard/index.js: escapeHtml AI answer and all dynamic list content - data-ingest/index.js: add .xlsx/.xls extension fallbacks for missing MIME type - storage.js: check chrome.runtime.lastError in all four storage helpers Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01KBD2dN2KEjzz3UQFa9hEpu --- agrifine-extension/src/ag-refine/agent.js | 4 +-- agrifine-extension/src/ag-refine/index.js | 10 ++++++- agrifine-extension/src/ag-refine/tools.js | 3 +- .../src/modules/dashboard/index.js | 16 +++++++---- .../src/modules/data-ingest/index.js | 5 +++- .../src/modules/field-profile/index.js | 2 +- .../src/modules/reading-list/index.js | 23 +++++++++++---- agrifine-extension/src/utils/storage.js | 28 +++++++++++++------ 8 files changed, 67 insertions(+), 24 deletions(-) diff --git a/agrifine-extension/src/ag-refine/agent.js b/agrifine-extension/src/ag-refine/agent.js index 75af4ba..fc2f0a0 100644 --- a/agrifine-extension/src/ag-refine/agent.js +++ b/agrifine-extension/src/ag-refine/agent.js @@ -61,8 +61,7 @@ export class AgrifineAgent { // Append assistant turn messages.push({ role: 'assistant', content: response.content }); - if (response.stop_reason === 'end_turn') { - // Extract final text + if (response.stop_reason === 'end_turn' || response.stop_reason === 'max_tokens') { const text = response.content .filter((b) => b.type === 'text') .map((b) => b.text) @@ -113,6 +112,7 @@ export class AgrifineAgent { 'Content-Type': 'application/json', 'x-api-key': apiKey, 'anthropic-version': '2023-06-01', + 'anthropic-dangerous-direct-browser-access': 'true', }, body: JSON.stringify(body), }); diff --git a/agrifine-extension/src/ag-refine/index.js b/agrifine-extension/src/ag-refine/index.js index d870629..a509734 100644 --- a/agrifine-extension/src/ag-refine/index.js +++ b/agrifine-extension/src/ag-refine/index.js @@ -153,7 +153,15 @@ export function AgRefineModule() { }, }); - await agent.run(userText); + try { + await agent.run(userText); + } catch (err) { + const idx = messages.findIndex((m) => m.id === thinkingId); + if (idx >= 0) messages.splice(idx, 1); + messages.push({ role: 'error', text: err.message }); + isRunning = false; + this._renderMessages(container); + } }, _renderMessages(container) { diff --git a/agrifine-extension/src/ag-refine/tools.js b/agrifine-extension/src/ag-refine/tools.js index 6d693cd..f47cf3a 100644 --- a/agrifine-extension/src/ag-refine/tools.js +++ b/agrifine-extension/src/ag-refine/tools.js @@ -151,7 +151,7 @@ async function toolGetReadingList({ tag } = {}) { async function toolGetFieldProfiles({ field_name } = {}) { const profiles = await getFieldProfiles(); const filtered = field_name - ? profiles.filter((p) => p.name.toLowerCase().includes(field_name.toLowerCase())) + ? profiles.filter((p) => p.name?.toLowerCase().includes(field_name.toLowerCase())) : profiles; return { count: filtered.length, @@ -260,6 +260,7 @@ async function toolLookupUSDAsoil({ latitude, longitude }) { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `request=query&query=${encodeURIComponent(query)}&format=JSON`, }); + if (!res.ok) throw new Error(`USDA SDA API ${res.status}`); const data = await res.json(); const rows = data.Table ?? []; return { diff --git a/agrifine-extension/src/modules/dashboard/index.js b/agrifine-extension/src/modules/dashboard/index.js index 390d7db..bff6de4 100644 --- a/agrifine-extension/src/modules/dashboard/index.js +++ b/agrifine-extension/src/modules/dashboard/index.js @@ -3,6 +3,12 @@ import { } from '../../utils/storage.js'; import { callAnthropic } from '../../utils/api.js'; +function escapeHtml(str) { + return String(str ?? '') + .replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +} + const CATEGORIES = ['all', 'land', 'equipment', 'harvest', 'finance', 'carbon', 'weather']; function tagCategory(item) { @@ -118,7 +124,7 @@ export function DashboardModule() { maxTokens: 512, }); - answerEl.innerHTML = `

Answer

${answer}`; + answerEl.innerHTML = `

Answer

${escapeHtml(answer)}`; } catch (err) { answerEl.textContent = `Error: ${err.message}`; } finally { @@ -167,11 +173,11 @@ export function DashboardModule() {
${sourceIcon}
-

${title}

- ${sub ? `

${sub}

` : ''} +

${escapeHtml(title)}

+ ${sub ? `

${escapeHtml(sub)}

` : ''}
- ${item._category} - ${(item.tags ?? []).filter((t) => t !== item._category).slice(0, 2).map((t) => `${t}`).join('')} + ${escapeHtml(item._category)} + ${(item.tags ?? []).filter((t) => t !== item._category).slice(0, 2).map((t) => `${escapeHtml(t)}`).join('')} ${date ? `${new Date(date).toLocaleDateString()}` : ''}
diff --git a/agrifine-extension/src/modules/data-ingest/index.js b/agrifine-extension/src/modules/data-ingest/index.js index dce5edb..79e4117 100644 --- a/agrifine-extension/src/modules/data-ingest/index.js +++ b/agrifine-extension/src/modules/data-ingest/index.js @@ -69,7 +69,10 @@ export function DataIngestModule() { async _processFile(file, container) { const status = container.querySelector('#ingest-status'); - const typeName = SUPPORTED_TYPES[file.type] ?? (file.name.endsWith('.csv') ? 'CSV' : null); + const typeName = SUPPORTED_TYPES[file.type] + ?? (file.name.endsWith('.csv') ? 'CSV' + : (file.name.endsWith('.xlsx') || file.name.endsWith('.xls')) ? 'Excel' + : null); if (!typeName) { status.textContent = 'Unsupported file type.'; diff --git a/agrifine-extension/src/modules/field-profile/index.js b/agrifine-extension/src/modules/field-profile/index.js index 646f650..958b394 100644 --- a/agrifine-extension/src/modules/field-profile/index.js +++ b/agrifine-extension/src/modules/field-profile/index.js @@ -148,7 +148,7 @@ export function FieldProfileModule() {
- ${p.coordinates?.lat ? `

📍 ${p.coordinates.lat.toFixed(4)}, ${p.coordinates.lon.toFixed(4)}

` : ''} + ${p.coordinates?.lat != null && p.coordinates?.lon != null ? `

📍 ${p.coordinates.lat.toFixed(4)}, ${p.coordinates.lon.toFixed(4)}

` : ''} ${p.notes ? `

📝 ${p.notes}

` : ''}

Weather data: Phase 6

Carbon potential: Phase 7

diff --git a/agrifine-extension/src/modules/reading-list/index.js b/agrifine-extension/src/modules/reading-list/index.js index 8c3db7c..47af440 100644 --- a/agrifine-extension/src/modules/reading-list/index.js +++ b/agrifine-extension/src/modules/reading-list/index.js @@ -1,6 +1,19 @@ import { getReadingList, saveReadingItem, deleteReadingItem } from '../../utils/storage.js'; import { callAnthropic, AGRICULTURE_TAGS } from '../../utils/api.js'; +function escapeHtml(str) { + return String(str ?? '') + .replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +} + +function safeHref(url) { + try { + const u = new URL(url); + return (u.protocol === 'https:' || u.protocol === 'http:') ? escapeHtml(url) : '#'; + } catch (_) { return '#'; } +} + export function ReadingListModule() { let currentTag = 'all'; @@ -126,18 +139,18 @@ export function ReadingListModule() { } listEl.innerHTML = filtered.map((item) => ` -
+
- ${item.summary ? `

${item.summary}

` : ''} + ${item.summary ? `

${escapeHtml(item.summary)}

` : ''}
- ${(item.tags ?? []).map((t) => `${t}`).join('')} + ${(item.tags ?? []).map((t) => `${escapeHtml(t)}`).join('')}

${new Date(item.savedAt).toLocaleDateString()}

diff --git a/agrifine-extension/src/utils/storage.js b/agrifine-extension/src/utils/storage.js index f5f6b95..680a433 100644 --- a/agrifine-extension/src/utils/storage.js +++ b/agrifine-extension/src/utils/storage.js @@ -22,26 +22,38 @@ export const KEYS = { // ── Generic helpers ────────────────────────────────────────────────────────── export async function localGet(key) { - return new Promise((resolve) => { - chrome.storage.local.get(key, (result) => resolve(result[key] ?? null)); + return new Promise((resolve, reject) => { + chrome.storage.local.get(key, (result) => { + if (chrome.runtime.lastError) { reject(new Error(chrome.runtime.lastError.message)); return; } + resolve(result[key] ?? null); + }); }); } export async function localSet(key, value) { - return new Promise((resolve) => { - chrome.storage.local.set({ [key]: value }, resolve); + return new Promise((resolve, reject) => { + chrome.storage.local.set({ [key]: value }, () => { + if (chrome.runtime.lastError) { reject(new Error(chrome.runtime.lastError.message)); return; } + resolve(); + }); }); } export async function sessionGet(key) { - return new Promise((resolve) => { - chrome.storage.session.get(key, (result) => resolve(result[key] ?? null)); + return new Promise((resolve, reject) => { + chrome.storage.session.get(key, (result) => { + if (chrome.runtime.lastError) { reject(new Error(chrome.runtime.lastError.message)); return; } + resolve(result[key] ?? null); + }); }); } export async function sessionSet(key, value) { - return new Promise((resolve) => { - chrome.storage.session.set({ [key]: value }, resolve); + return new Promise((resolve, reject) => { + chrome.storage.session.set({ [key]: value }, () => { + if (chrome.runtime.lastError) { reject(new Error(chrome.runtime.lastError.message)); return; } + resolve(); + }); }); } From 734664256342464c201ecf067c5151b221e24064 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 06:08:04 +0000 Subject: [PATCH 07/12] feat: add 5 new AgriAgent tools for web browsing and data export MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit screenshot_active_tab — captures current browser tab as JPEG; agent.js formats the result as an Anthropic vision image block so Claude can actually see the page (not just its text) get_page_content — reads text of the active tab via content script, or falls back to the reading-list cache when a URL is supplied export_farm_data — generates a CSV or JSON file and triggers a browser download for reading_list, field_profiles, ingested_files, or all data open_tab — opens any https:// URL in a new browser tab and waits for it to finish loading; returns tab_id for chained tool calls read_tab_content — extracts and parses page text from any tab by tab_id (or active tab) using chrome.scripting.executeScript; more reliable than the content-script sendMessage path Background worker gains CAPTURE_SCREENSHOT, GET_ACTIVE_TAB_CONTENT, OPEN_TAB, and READ_TAB_CONTENT message handlers; agent.js detects _type:'image' results and formats them as vision content blocks. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01KBD2dN2KEjzz3UQFa9hEpu --- agrifine-extension/src/ag-refine/agent.js | 28 ++- agrifine-extension/src/ag-refine/index.js | 22 +- agrifine-extension/src/ag-refine/tools.js | 236 +++++++++++++++++++++ agrifine-extension/src/background/index.js | 94 +++++++- 4 files changed, 366 insertions(+), 14 deletions(-) diff --git a/agrifine-extension/src/ag-refine/agent.js b/agrifine-extension/src/ag-refine/agent.js index fc2f0a0..6451229 100644 --- a/agrifine-extension/src/ag-refine/agent.js +++ b/agrifine-extension/src/ag-refine/agent.js @@ -86,11 +86,29 @@ export class AgrifineAgent { this.onEvent({ type: 'tool_result', data: { name: block.name, result } }); - toolResults.push({ - type: 'tool_result', - tool_use_id: block.id, - content: JSON.stringify(result), - }); + // Screenshot tool returns an image — pass it as a vision content block + if (result && result._type === 'image') { + toolResults.push({ + type: 'tool_result', + tool_use_id: block.id, + content: [ + { + type: 'image', + source: { type: 'base64', media_type: result.media_type, data: result.data }, + }, + { + type: 'text', + text: `Screenshot of "${result.title}" (${result.url})`, + }, + ], + }); + } else { + toolResults.push({ + type: 'tool_result', + tool_use_id: block.id, + content: JSON.stringify(result), + }); + } } messages.push({ role: 'user', content: toolResults }); diff --git a/agrifine-extension/src/ag-refine/index.js b/agrifine-extension/src/ag-refine/index.js index a509734..4d55ea3 100644 --- a/agrifine-extension/src/ag-refine/index.js +++ b/agrifine-extension/src/ag-refine/index.js @@ -1,20 +1,26 @@ import { AgrifineAgent } from './agent.js'; const TOOL_ICONS = { - get_reading_list: '📖', - get_field_profiles: '🌱', - get_ingested_files: '📄', - get_weather: '🌤️', - lookup_usda_soil: '🏛️', - calculate_gdd: '📊', + get_reading_list: '📖', + get_field_profiles: '🌱', + get_ingested_files: '📄', + get_weather: '🌤️', + lookup_usda_soil: '🏛️', + calculate_gdd: '📊', + screenshot_active_tab: '📸', + get_page_content: '🔍', + export_farm_data: '⬇️', + open_tab: '🌐', + read_tab_content: '📋', }; const SUGGESTED_PROMPTS = [ 'What are my current field conditions and harvest windows?', 'Which fields have the best soil for carbon sequestration?', 'Summarise all my farm data and flag any issues', - 'What does the 7-day weather look like for my fields?', - 'What USDA programs might I qualify for based on my fields?', + 'Screenshot this page and tell me what agricultural data you see', + 'Read this page and save any farm data you find', + 'Export my reading list and field profiles to CSV', ]; export function AgRefineModule() { diff --git a/agrifine-extension/src/ag-refine/tools.js b/agrifine-extension/src/ag-refine/tools.js index f47cf3a..b24cf6b 100644 --- a/agrifine-extension/src/ag-refine/tools.js +++ b/agrifine-extension/src/ag-refine/tools.js @@ -1,5 +1,11 @@ import { getReadingList, getIngestedFiles, getFieldProfiles } from '../utils/storage.js'; +function csvEscape(val) { + const s = String(val ?? ''); + return (s.includes(',') || s.includes('"') || s.includes('\n')) + ? `"${s.replace(/"/g, '""')}"` : s; +} + // ── Tool definitions sent to Claude ────────────────────────────────────────── export const TOOL_DEFINITIONS = [ @@ -86,6 +92,86 @@ export const TOOL_DEFINITIONS = [ required: ['latitude', 'longitude'], }, }, + { + name: 'screenshot_active_tab', + description: 'Take a screenshot of the currently active browser tab. Returns an image Claude can visually inspect — use this to see what the user is currently viewing, check a web page layout, verify data on screen, or analyse any visible content.', + input_schema: { + type: 'object', + properties: { + description: { + type: 'string', + description: 'Optional note about why the screenshot is being taken (for context)', + }, + }, + required: [], + }, + }, + { + name: 'get_page_content', + description: 'Fetch the full text content of the currently active browser tab, or look up a saved reading-list URL. Use this to read articles, extract data from web pages, or analyse the text of any page the user has open.', + input_schema: { + type: 'object', + properties: { + url: { + type: 'string', + description: 'Optional URL to look up in the saved reading list. If omitted, reads the active tab.', + }, + }, + required: [], + }, + }, + { + name: 'export_farm_data', + description: 'Generate and download a CSV or JSON export of farm data. Triggers a file download in the user\'s browser. Use when the user asks to export, download, or save their farm data.', + input_schema: { + type: 'object', + properties: { + data_type: { + type: 'string', + enum: ['reading_list', 'field_profiles', 'ingested_files', 'all'], + description: 'Which data set to export', + }, + format: { + type: 'string', + enum: ['csv', 'json'], + description: 'File format (csv or json). "all" data_type always uses json.', + }, + }, + required: ['data_type'], + }, + }, + { + name: 'open_tab', + description: 'Open a URL in a new browser tab and wait for it to load. Use this to navigate to a relevant website — USDA, weather services, commodity markets, farm news, etc. After opening, call read_tab_content or screenshot_active_tab to extract information.', + input_schema: { + type: 'object', + properties: { + url: { + type: 'string', + description: 'The full URL to open (must start with https:// or http://)', + }, + reason: { + type: 'string', + description: 'Why you are opening this URL — shown to the user', + }, + }, + required: ['url'], + }, + }, + { + name: 'read_tab_content', + description: 'Extract and parse the text content of a browser tab. Call after open_tab to read the page that was just loaded, or omit tab_id to read the currently active tab.', + input_schema: { + type: 'object', + properties: { + tab_id: { + type: 'number', + description: 'Tab ID returned by open_tab. Omit to read the currently active tab.', + }, + }, + required: [], + }, + }, { name: 'calculate_gdd', description: 'Calculate Growing Degree Days from temperature data. Uses base temp of 50°F for forage crops.', @@ -128,6 +214,16 @@ export async function executeTool(name, input) { return toolLookupUSDAsoil(input); case 'calculate_gdd': return toolCalculateGDD(input); + case 'screenshot_active_tab': + return toolScreenshotActiveTab(input); + case 'get_page_content': + return toolGetPageContent(input); + case 'export_farm_data': + return toolExportFarmData(input); + case 'open_tab': + return toolOpenTab(input); + case 'read_tab_content': + return toolReadTabContent(input); default: return { error: `Unknown tool: ${name}` }; } @@ -284,6 +380,146 @@ async function toolLookupUSDAsoil({ latitude, longitude }) { } } +function toolScreenshotActiveTab() { + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage({ type: 'CAPTURE_SCREENSHOT' }, (response) => { + if (chrome.runtime.lastError) { + reject(new Error(chrome.runtime.lastError.message)); + return; + } + if (response?.error) { + reject(new Error(response.error)); + return; + } + // Strip data URL prefix — agent.js will format this as an image content block + const base64 = response.dataUrl.replace(/^data:image\/\w+;base64,/, ''); + resolve({ + _type: 'image', + media_type: 'image/jpeg', + data: base64, + url: response.url, + title: response.title, + }); + }); + }); +} + +async function toolGetPageContent({ url } = {}) { + // Check reading list cache first if a URL was given + if (url) { + const list = await getReadingList(); + const saved = list.find((i) => i.url === url || i.url.startsWith(url)); + if (saved) { + return { + url: saved.url, + title: saved.title, + summary: saved.summary, + tags: saved.tags, + source: 'reading_list_cache', + }; + } + } + + // Fall back to reading the active tab via content script + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage({ type: 'GET_ACTIVE_TAB_CONTENT' }, (response) => { + if (chrome.runtime.lastError) { + reject(new Error(chrome.runtime.lastError.message)); + return; + } + if (response?.error) { + reject(new Error(response.error)); + return; + } + resolve(response); + }); + }); +} + +async function toolExportFarmData({ data_type, format = 'csv' }) { + let records; + let filename; + let content; + const date = new Date().toISOString().slice(0, 10); + + if (data_type === 'all') { + const [rl, files, profiles] = await Promise.all([getReadingList(), getIngestedFiles(), getFieldProfiles()]); + filename = `agrifine_export_${date}.json`; + content = JSON.stringify({ reading_list: rl, ingested_files: files, field_profiles: profiles }, null, 2); + records = rl.length + files.length + profiles.length; + } else if (data_type === 'reading_list') { + const list = await getReadingList(); + records = list.length; + filename = `agrifine_reading_list_${date}.${format}`; + if (format === 'json') { + content = JSON.stringify(list, null, 2); + } else { + const hdrs = ['title', 'url', 'summary', 'tags', 'savedAt']; + const rows = list.map((i) => [i.title, i.url, i.summary ?? '', (i.tags ?? []).join('; '), i.savedAt].map(csvEscape)); + content = [hdrs.join(','), ...rows.map((r) => r.join(','))].join('\n'); + } + } else if (data_type === 'field_profiles') { + const profiles = await getFieldProfiles(); + records = profiles.length; + filename = `agrifine_field_profiles_${date}.${format}`; + if (format === 'json') { + content = JSON.stringify(profiles, null, 2); + } else { + const hdrs = ['name', 'acres', 'soil_type', 'latitude', 'longitude', 'clu_id', 'notes', 'created_at']; + const rows = profiles.map((p) => [ + p.name, p.acres ?? '', p.soilType ?? '', + p.coordinates?.lat ?? '', p.coordinates?.lon ?? '', + p.cluId ?? '', p.notes ?? '', p.createdAt, + ].map(csvEscape)); + content = [hdrs.join(','), ...rows.map((r) => r.join(','))].join('\n'); + } + } else if (data_type === 'ingested_files') { + const files = await getIngestedFiles(); + records = files.length; + filename = `agrifine_ingested_files_${date}.json`; + content = JSON.stringify(files, null, 2); + } else { + return { error: `Unknown data_type: ${data_type}` }; + } + + // Trigger download inside the sidebar page + const mimeType = filename.endsWith('.json') ? 'application/json' : 'text/csv'; + const blob = new Blob([content], { type: mimeType }); + const objectUrl = URL.createObjectURL(blob); + const anchor = document.createElement('a'); + anchor.href = objectUrl; + anchor.download = filename; + document.body.appendChild(anchor); + anchor.click(); + document.body.removeChild(anchor); + setTimeout(() => URL.revokeObjectURL(objectUrl), 2000); + + return { exported: true, filename, record_count: records, format: filename.split('.').pop(), data_type }; +} + +function toolOpenTab({ url, reason }) { + if (!url.startsWith('http://') && !url.startsWith('https://')) { + return Promise.resolve({ error: 'URL must start with http:// or https://' }); + } + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage({ type: 'OPEN_TAB', payload: { url } }, (response) => { + if (chrome.runtime.lastError) { reject(new Error(chrome.runtime.lastError.message)); return; } + if (response?.error) { reject(new Error(response.error)); return; } + resolve({ ...response, reason: reason ?? null }); + }); + }); +} + +function toolReadTabContent({ tab_id } = {}) { + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage({ type: 'READ_TAB_CONTENT', payload: { tab_id: tab_id ?? null } }, (response) => { + if (chrome.runtime.lastError) { reject(new Error(chrome.runtime.lastError.message)); return; } + if (response?.error) { reject(new Error(response.error)); return; } + resolve(response); + }); + }); +} + function toolCalculateGDD({ daily_highs, daily_lows, base_temp = 50 }) { const gdd_per_day = daily_highs.map((hi, i) => { const lo = daily_lows[i] ?? hi; diff --git a/agrifine-extension/src/background/index.js b/agrifine-extension/src/background/index.js index 76e83d2..60f0b0d 100644 --- a/agrifine-extension/src/background/index.js +++ b/agrifine-extension/src/background/index.js @@ -20,10 +20,33 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { return true; case 'GET_PAGE_CONTENT': - // Content script relays page text; background stores it temporarily sendResponse({ ok: true }); return false; + case 'CAPTURE_SCREENSHOT': + captureActiveTabScreenshot() + .then(sendResponse) + .catch((err) => sendResponse({ error: err.message })); + return true; + + case 'GET_ACTIVE_TAB_CONTENT': + getActiveTabContent() + .then(sendResponse) + .catch((err) => sendResponse({ error: err.message })); + return true; + + case 'OPEN_TAB': + openUrlInTab(message.payload.url) + .then(sendResponse) + .catch((err) => sendResponse({ error: err.message })); + return true; + + case 'READ_TAB_CONTENT': + readTabContent(message.payload?.tab_id) + .then(sendResponse) + .catch((err) => sendResponse({ error: err.message })); + return true; + default: return false; } @@ -34,6 +57,75 @@ async function handleAnthropicRequest({ system, userMessage, maxTokens }) { return { text }; } +async function captureActiveTabScreenshot() { + const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); + if (!tab) throw new Error('No active tab found'); + const dataUrl = await chrome.tabs.captureVisibleTab(tab.windowId, { format: 'jpeg', quality: 80 }); + return { dataUrl, url: tab.url, title: tab.title }; +} + +async function getActiveTabContent() { + const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); + if (!tab) throw new Error('No active tab found'); + try { + const resp = await chrome.tabs.sendMessage(tab.id, { type: 'GET_PAGE_INFO' }); + return { url: tab.url, title: tab.title, text: resp?.text ?? '', source: 'active_tab' }; + } catch (_) { + return { + url: tab.url, + title: tab.title, + text: '', + source: 'active_tab', + note: 'Content script unavailable on this page (chrome://, extensions, etc.)', + }; + } +} + +function waitForTabLoad(tabId, timeoutMs = 20000) { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + chrome.tabs.onUpdated.removeListener(listener); + chrome.tabs.get(tabId).then(resolve).catch(() => reject(new Error('Tab load timed out'))); + }, timeoutMs); + function listener(id, info, tab) { + if (id !== tabId || info.status !== 'complete') return; + chrome.tabs.onUpdated.removeListener(listener); + clearTimeout(timer); + resolve(tab); + } + chrome.tabs.onUpdated.addListener(listener); + }); +} + +async function openUrlInTab(url) { + const tab = await chrome.tabs.create({ url, active: true }); + const loaded = await waitForTabLoad(tab.id); + return { tab_id: loaded.id, url: loaded.url, title: loaded.title, status: 'ready' }; +} + +async function readTabContent(tabId) { + const targetId = tabId + ?? (await chrome.tabs.query({ active: true, currentWindow: true }))[0]?.id; + if (!targetId) throw new Error('No tab found'); + + const [result] = await chrome.scripting.executeScript({ + target: { tabId: targetId }, + func: () => { + const selectors = ['article', 'main', '[role="main"]', '.content', '#content']; + for (const sel of selectors) { + const el = document.querySelector(sel); + if (el) { + const clone = el.cloneNode(true); + clone.querySelectorAll('script,style,nav,header,footer,aside').forEach((n) => n.remove()); + return { url: location.href, title: document.title, text: clone.innerText.trim().slice(0, 8000) }; + } + } + return { url: location.href, title: document.title, text: document.body?.innerText?.slice(0, 8000) ?? '' }; + }, + }); + return result.result; +} + // Keep service worker alive during active side-panel sessions chrome.runtime.onConnect.addListener((port) => { if (port.name === 'keepalive') { From 05a3a3bbd0d51e9fd28d72ca828e5875f15b84ce Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 06:12:05 +0000 Subject: [PATCH 08/12] feat: persistent farm memory and enriched context bundle for AgriAgent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Farm memory (agrifine_farm_memory in chrome.storage.local): - New FarmMemory schema: aiGeneratedSummary, farm_name, total_acres, primary_crops, soil_overview, key_insights, action_items, risk_flags, opportunities, lastUpdated - getFarmMemory() / saveFarmMemory() in storage.js buildContextBundle() now loads all four data sources in parallel: 1. Farm memory snapshot (AI synthesis from prior sessions) — at top 2. Field profiles with crop history, harvest records, and coordinates 3. Ingested data files with structured-data previews 4. Reading list articles with summaries and tags Two new AgriAgent tools: - get_farm_memory: retrieve the stored knowledge snapshot - update_farm_memory: agent saves a comprehensive farm synthesis so future sessions start with full context (the key to persistent memory) System prompt rewrite in agent.js: - Agent now understands its role as the farm's persistent advisor - Memory protocol: reference farm memory first, update it when new insights are discovered - Explicit reasoning steps: Ground → Gaps → Connect → Cite → Remember - Full tool selection guide with when-to-use guidance for all 11 tools Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01KBD2dN2KEjzz3UQFa9hEpu --- agrifine-extension/src/ag-refine/agent.js | 46 ++++++-- agrifine-extension/src/ag-refine/index.js | 7 +- agrifine-extension/src/ag-refine/tools.js | 59 ++++++++++- agrifine-extension/src/utils/storage.js | 123 +++++++++++++++++++--- 4 files changed, 204 insertions(+), 31 deletions(-) diff --git a/agrifine-extension/src/ag-refine/agent.js b/agrifine-extension/src/ag-refine/agent.js index 6451229..e3aa914 100644 --- a/agrifine-extension/src/ag-refine/agent.js +++ b/agrifine-extension/src/ag-refine/agent.js @@ -26,16 +26,42 @@ export class AgrifineAgent { const contextBundle = await buildContextBundle(); - const systemPrompt = [ - 'You are AgriAgent, an expert AI assistant for farm operations management.', - 'You have access to the user\'s farm data through tools — always use them before answering.', - 'When answering questions about fields, weather, yields, or finances: first query the relevant data, then synthesize a clear answer.', - 'Be specific: cite field names, dates, acreage, and numbers from the actual data.', - 'For weather queries on a field, always look up the field profile first to get coordinates.', - '', - 'FARM CONTEXT (reading list summaries + field profiles):', - contextBundle, - ].join('\n'); + const systemPrompt = `You are AgriAgent, the dedicated AI advisor for this farm operation. You maintain a persistent "farm memory" — a synthesized knowledge base you build and update over time as you learn more about the operation. + +IDENTITY AND ROLE +- You are this farm's trusted advisor with deep, specific knowledge of its fields, crops, soils, finances, and operations. +- You think both tactically (today's weather, this week's harvest window) and strategically (long-term soil health, carbon sequestration, USDA program eligibility). +- Your answers are always grounded in the farm's actual data — never guess or use generic advice when specific data is available. + +MEMORY PROTOCOL +- The FARM CONTEXT section below is pre-loaded with all available data from every source, including your previously stored farm memory. +- The farm memory (if present) is the most important section — it is your synthesized understanding of this operation built from prior analysis. Reference it first. +- When you discover something significant (a pattern, risk, or opportunity not already captured), call update_farm_memory to preserve it for future sessions. +- If farm memory is absent or stale (>14 days old), proactively synthesize one after reviewing the available field and file data. + +REASONING APPROACH — follow this order: +1. GROUND: What does the farm memory and pre-loaded context already tell me? +2. GAPS: What additional data do I need? Use the right tool — don't query what's already in context. +3. CONNECT: Link data across sources (e.g. soil type + weather + crop history → harvest recommendation). +4. CITE: Always name fields, dates, acreages, and numbers from the actual data. +5. REMEMBER: Did this conversation reveal anything new? If so, update_farm_memory. + +TOOL SELECTION GUIDE +- get_field_profiles — field locations, soil type, acreage, crop history, harvest records +- get_weather(lat, lon) — live 7-day forecast + GDD; always get field coordinates first +- lookup_usda_soil(lat, lon) — USDA soil classification and organic matter data +- get_ingested_files — uploaded CSVs, Excel files, PDFs with extracted structured data +- get_reading_list — saved articles, research, USDA notices +- calculate_gdd(highs, lows) — growing degree day accumulation from temperature data +- screenshot_active_tab — capture the current browser page as an image you can see +- get_page_content — read text from the active tab or a saved reading-list URL +- open_tab(url) + read_tab_content(tab_id) — navigate to a URL and parse its content +- export_farm_data — generate and download CSV/JSON of farm data +- get_farm_memory — retrieve the stored farm knowledge snapshot +- update_farm_memory — save new insights about this farm for future sessions + +FARM CONTEXT (all data sources pre-loaded — memory, field profiles, ingested files, reading list): +${contextBundle}`; const messages = [{ role: 'user', content: userMessage }]; diff --git a/agrifine-extension/src/ag-refine/index.js b/agrifine-extension/src/ag-refine/index.js index 4d55ea3..15f405b 100644 --- a/agrifine-extension/src/ag-refine/index.js +++ b/agrifine-extension/src/ag-refine/index.js @@ -12,14 +12,15 @@ const TOOL_ICONS = { export_farm_data: '⬇️', open_tab: '🌐', read_tab_content: '📋', + get_farm_memory: '🧠', + update_farm_memory: '💾', }; const SUGGESTED_PROMPTS = [ + 'Review all my farm data and build a farm memory summary', 'What are my current field conditions and harvest windows?', - 'Which fields have the best soil for carbon sequestration?', - 'Summarise all my farm data and flag any issues', + 'What risks or opportunities do you see across my operation?', 'Screenshot this page and tell me what agricultural data you see', - 'Read this page and save any farm data you find', 'Export my reading list and field profiles to CSV', ]; diff --git a/agrifine-extension/src/ag-refine/tools.js b/agrifine-extension/src/ag-refine/tools.js index b24cf6b..0fe1fde 100644 --- a/agrifine-extension/src/ag-refine/tools.js +++ b/agrifine-extension/src/ag-refine/tools.js @@ -1,4 +1,4 @@ -import { getReadingList, getIngestedFiles, getFieldProfiles } from '../utils/storage.js'; +import { getReadingList, getIngestedFiles, getFieldProfiles, getFarmMemory, saveFarmMemory } from '../utils/storage.js'; function csvEscape(val) { const s = String(val ?? ''); @@ -140,6 +140,33 @@ export const TOOL_DEFINITIONS = [ required: ['data_type'], }, }, + { + name: 'get_farm_memory', + description: 'Retrieve the stored farm memory — the AI-synthesized knowledge base for this operation. Returns the most recent summary, key insights, action items, risk flags, and opportunities identified in prior sessions. Call this if the system context did not already include farm memory.', + input_schema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'update_farm_memory', + description: 'Save an updated farm memory snapshot. Call this after synthesizing new insights so future sessions benefit from what you learned. Write a comprehensive aiGeneratedSummary covering the whole farm operation — fields, soils, crops, patterns, and strategic outlook.', + input_schema: { + type: 'object', + properties: { + aiGeneratedSummary: { + type: 'string', + description: 'A rich narrative synthesis of the farm operation. Cover: total acreage, each field\'s status, soil conditions, crop history patterns, financial health (if data available), key risks, and strategic opportunities. Write as a briefing you\'d give a new advisor.', + }, + farm_name: { type: 'string', description: 'Farm or operation name if known' }, + total_acres: { type: 'number', description: 'Total acreage across all fields' }, + primary_crops: { type: 'array', items: { type: 'string' }, description: 'Primary crops grown' }, + soil_overview: { type: 'string', description: 'Summary of soil conditions across the operation' }, + key_insights: { type: 'array', items: { type: 'string' }, description: 'Most important observations — patterns, correlations, or findings about this farm' }, + action_items: { type: 'array', items: { type: 'string' }, description: 'Recommended next steps for the operator' }, + risk_flags: { type: 'array', items: { type: 'string' }, description: 'Risks, concerns, or issues to monitor' }, + opportunities: { type: 'array', items: { type: 'string' }, description: 'Opportunities identified — programs, practices, markets' }, + }, + required: ['aiGeneratedSummary'], + }, + }, { name: 'open_tab', description: 'Open a URL in a new browser tab and wait for it to load. Use this to navigate to a relevant website — USDA, weather services, commodity markets, farm news, etc. After opening, call read_tab_content or screenshot_active_tab to extract information.', @@ -220,6 +247,10 @@ export async function executeTool(name, input) { return toolGetPageContent(input); case 'export_farm_data': return toolExportFarmData(input); + case 'get_farm_memory': + return toolGetFarmMemory(); + case 'update_farm_memory': + return toolUpdateFarmMemory(input); case 'open_tab': return toolOpenTab(input); case 'read_tab_content': @@ -497,6 +528,32 @@ async function toolExportFarmData({ data_type, format = 'csv' }) { return { exported: true, filename, record_count: records, format: filename.split('.').pop(), data_type }; } +async function toolGetFarmMemory() { + const memory = await getFarmMemory(); + if (!memory) { + return { + has_memory: false, + message: 'No farm memory stored yet. Review the field profiles and ingested files, then call update_farm_memory to create a persistent knowledge base for this farm.', + }; + } + return { has_memory: true, ...memory }; +} + +async function toolUpdateFarmMemory(input) { + await saveFarmMemory({ + aiGeneratedSummary: input.aiGeneratedSummary, + farm_name: input.farm_name ?? null, + total_acres: input.total_acres ?? null, + primary_crops: input.primary_crops ?? [], + soil_overview: input.soil_overview ?? null, + key_insights: input.key_insights ?? [], + action_items: input.action_items ?? [], + risk_flags: input.risk_flags ?? [], + opportunities: input.opportunities ?? [], + }); + return { saved: true, message: 'Farm memory updated. Future sessions will begin with this knowledge.' }; +} + function toolOpenTab({ url, reason }) { if (!url.startsWith('http://') && !url.startsWith('https://')) { return Promise.resolve({ error: 'URL must start with http:// or https://' }); diff --git a/agrifine-extension/src/utils/storage.js b/agrifine-extension/src/utils/storage.js index 680a433..abfe4b1 100644 --- a/agrifine-extension/src/utils/storage.js +++ b/agrifine-extension/src/utils/storage.js @@ -6,17 +6,33 @@ * agrifine_ingested_files — Array * agrifine_field_profiles — Array * agrifine_settings — Settings + * agrifine_farm_memory — FarmMemory (AI-synthesized knowledge base) * * chrome.storage.session keys: * agrifine_api_key — string (never persisted to local) + * + * FarmMemory shape: + * { + * lastUpdated: ISO string, + * aiGeneratedSummary: string, // Claude's narrative synthesis of the whole farm + * farm_name: string | null, + * total_acres: number | null, + * primary_crops: string[], + * soil_overview: string | null, + * key_insights: string[], // important observations + * action_items: string[], // recommended next steps + * risk_flags: string[], // risks or concerns to watch + * opportunities: string[], // identified opportunities + * } */ export const KEYS = { - READING_LIST: 'agrifine_reading_list', - INGESTED_FILES: 'agrifine_ingested_files', - FIELD_PROFILES: 'agrifine_field_profiles', - SETTINGS: 'agrifine_settings', - API_KEY: 'agrifine_api_key', // session only + READING_LIST: 'agrifine_reading_list', + INGESTED_FILES: 'agrifine_ingested_files', + FIELD_PROFILES: 'agrifine_field_profiles', + SETTINGS: 'agrifine_settings', + FARM_MEMORY: 'agrifine_farm_memory', + API_KEY: 'agrifine_api_key', // session only }; // ── Generic helpers ────────────────────────────────────────────────────────── @@ -113,6 +129,16 @@ export async function deleteFieldProfile(id) { await localSet(KEYS.FIELD_PROFILES, profiles.filter((p) => p.id !== id)); } +// ── Farm Memory ────────────────────────────────────────────────────────────── + +export async function getFarmMemory() { + return (await localGet(KEYS.FARM_MEMORY)) ?? null; +} + +export async function saveFarmMemory(memory) { + await localSet(KEYS.FARM_MEMORY, { ...memory, lastUpdated: new Date().toISOString() }); +} + // ── Settings ───────────────────────────────────────────────────────────────── export async function getSettings() { @@ -127,22 +153,85 @@ export async function saveSettings(patch) { // ── Context bundle (used as AI system context) ─────────────────────────────── export async function buildContextBundle() { - const list = await getReadingList(); - const profiles = await getFieldProfiles(); + const [list, profiles, files, memory] = await Promise.all([ + getReadingList(), + getFieldProfiles(), + getIngestedFiles(), + getFarmMemory(), + ]); - const readingCtx = list.slice(0, 20).map((item) => - `[${item.tags?.join(', ') ?? 'general'}] ${item.title}: ${item.summary ?? ''}` - ).join('\n'); + // ── 1. Farm memory (AI-synthesized knowledge — most important, goes first) ── + let memorySection; + if (memory) { + const lines = [ + `FARM MEMORY (last updated ${memory.lastUpdated?.slice(0, 10) ?? 'unknown'}):`, + memory.aiGeneratedSummary ?? '', + ]; + if (memory.primary_crops?.length) lines.push(`Primary crops: ${memory.primary_crops.join(', ')}`); + if (memory.total_acres != null) lines.push(`Total acreage: ${memory.total_acres} ac`); + if (memory.key_insights?.length) { + lines.push('Key insights:'); + memory.key_insights.forEach((s) => lines.push(` • ${s}`)); + } + if (memory.action_items?.length) { + lines.push('Action items:'); + memory.action_items.forEach((s) => lines.push(` • ${s}`)); + } + if (memory.risk_flags?.length) { + lines.push('Risk flags:'); + memory.risk_flags.forEach((s) => lines.push(` ⚠ ${s}`)); + } + memorySection = lines.filter(Boolean).join('\n'); + } else { + memorySection = 'FARM MEMORY: (none yet — after reviewing field data, call update_farm_memory to build a persistent knowledge base)'; + } - const fieldCtx = profiles.map((p) => - `Field "${p.name}" (${p.acres ?? '?'} ac, ${p.soilType ?? 'unknown soil'}): ${p.notes ?? ''}` - ).join('\n'); + // ── 2. Field profiles with crop history and harvest records ────────────────── + const fieldLines = profiles.length === 0 ? ['(none)'] : profiles.map((p) => { + const coords = p.coordinates?.lat != null && p.coordinates?.lon != null + ? `${p.coordinates.lat.toFixed(4)}, ${p.coordinates.lon.toFixed(4)}` + : null; + const history = (p.cropHistory ?? []).slice(0, 4).map((h) => `${h.year}: ${h.crop}`).join(', '); + const harvests = (p.harvestRecords ?? []).slice(0, 3) + .map((h) => `${h.date?.slice(0, 10) ?? '?'}: ${h.yield} ${h.unit ?? ''}`.trim()).join('; '); + const parts = [ + `Field "${p.name}" | ${p.acres ?? '?'} ac | ${p.soilType ?? 'unknown soil'}`, + coords ? ` Coords: ${coords}` : null, + p.cluId ? ` CLU: ${p.cluId}` : null, + history ? ` Crop history: ${history}` : null, + harvests ? ` Harvests: ${harvests}` : null, + p.notes ? ` Notes: ${p.notes}` : null, + ]; + return parts.filter(Boolean).join('\n'); + }); + + // ── 3. Ingested data files ─────────────────────────────────────────────────── + const fileLines = files.length === 0 ? ['(none)'] : files.slice(0, 10).map((f) => { + const preview = f.structuredData + ? Object.entries(f.structuredData) + .filter(([k]) => k !== 'raw_preview' && k !== 'parse_error') + .slice(0, 5) + .map(([k, v]) => `${k}: ${JSON.stringify(v).slice(0, 120)}`) + .join(' | ') + : f.preview?.slice(0, 200) ?? '(no structured data)'; + return `[${f.type}] ${f.filename} (${f.uploadedAt?.slice(0, 10) ?? '?'}): ${preview}`; + }); + + // ── 4. Reading list (recent saved articles) ────────────────────────────────── + const readingLines = list.length === 0 ? ['(none)'] : list.slice(0, 15).map((item) => + `[${item.tags?.join(', ') ?? 'general'}] "${item.title}": ${item.summary ?? '(no summary)'}` + ); return [ - 'USER READING LIST CONTEXT:', - readingCtx || '(none)', + memorySection, '', - 'FIELD PROFILES:', - fieldCtx || '(none)', + '── FIELD PROFILES ──', + fieldLines.join('\n\n'), + '', + '── INGESTED DATA FILES ──', + fileLines.join('\n'), + '', + '── READING LIST (recent articles) ──', + readingLines.join('\n'), ].join('\n'); } From 564ec1145e25599375c666642e330fc71e175707 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 27 Jun 2026 06:28:50 +0000 Subject: [PATCH 09/12] Redesign Agrifine extension UI to match AG-Refine dark theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace all light-mode Tailwind classes across every module with the AG-Refine dark design system: #0f1621 body, #131c2b header/nav, #1a2438 cards, #1e2d40 borders, agri-green (22c55e/16a34a) accents. - tailwind.config.js: add `night` dark palette (950–300) - sidebar.css: full dark rewrite (cards, tags, inputs, scrollbar) - sidebar.html: AG/REFINE/FIELD INTELLIGENCE logo, dark tab bar with INTEL/INGEST/FIELDS/DATA/CARBON/AGENT labels and dot indicators - sidebar/index.js: manage inactive tab color via inline style - reading-list: card links → agri-400, summary/date → gray-400/500 - data-ingest: drop zone → night borders, file cards → dark theme - field-profile: form → night-700 bg, inputs use .ag-input, cards dark - dashboard: AI query bar and category pills → dark, answer box dark - carbon-estimator: feature list and notify banner → dark palette - ag-refine: suggestions → night-700, chat bubbles dark, tool call cards use night-700/border-night-600, errors use red-900/20 tint Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01KBD2dN2KEjzz3UQFa9hEpu --- agrifine-extension/src/ag-refine/index.js | 32 +++---- .../src/modules/carbon-estimator/index.js | 20 ++--- .../src/modules/dashboard/index.js | 20 ++--- .../src/modules/data-ingest/index.js | 24 +++--- .../src/modules/field-profile/index.js | 46 +++++----- .../src/modules/reading-list/index.js | 14 ++-- agrifine-extension/src/sidebar/index.js | 4 +- agrifine-extension/src/sidebar/sidebar.css | 57 ++++++++----- agrifine-extension/src/sidebar/sidebar.html | 84 +++++++++++-------- agrifine-extension/tailwind.config.js | 10 +++ 10 files changed, 169 insertions(+), 142 deletions(-) diff --git a/agrifine-extension/src/ag-refine/index.js b/agrifine-extension/src/ag-refine/index.js index 15f405b..718eb07 100644 --- a/agrifine-extension/src/ag-refine/index.js +++ b/agrifine-extension/src/ag-refine/index.js @@ -40,10 +40,10 @@ export function AgRefineModule() {
🤖 -

AgriAgent

- AI Agent +

AgriAgent

+ AI Agent
-

Multi-step reasoning over all your farm data

+

Multi-step reasoning over all your farm data

@@ -51,29 +51,29 @@ export function AgRefineModule() {
-

Try asking…

+

Try asking…

${SUGGESTED_PROMPTS.map((p) => ` - `).join('')}
-
+
+ class="ag-input flex-1 rounded-xl resize-none">
- +
`; @@ -197,28 +197,28 @@ export function AgRefineModule() {
${steps.map((step) => { if (step.type === 'status') { - return `
+ return `
${escapeHtml(step.text)}
`; } if (step.type === 'tool') { - return `
+ return `
${step.icon} - ${step.name} + ${step.name} ${step.done ? '' : ''}
`; } return ''; }).join('')} - ${steps.length === 0 ? '
Starting…
' : ''} + ${steps.length === 0 ? '
Starting…
' : ''}
`; } if (msg.role === 'assistant') { return `
-
🤖
-
+
🤖
+
${escapeHtml(msg.text)}
`; @@ -226,7 +226,7 @@ export function AgRefineModule() { if (msg.role === 'error') { return ` -
+
⚠️ ${escapeHtml(msg.text)}
`; } diff --git a/agrifine-extension/src/modules/carbon-estimator/index.js b/agrifine-extension/src/modules/carbon-estimator/index.js index 097e456..afdcc8e 100644 --- a/agrifine-extension/src/modules/carbon-estimator/index.js +++ b/agrifine-extension/src/modules/carbon-estimator/index.js @@ -12,15 +12,15 @@ export function CarbonEstimatorModule() {
-
+
-
🌿
+
🌿
-

Carbon Estimator

+

Carbon Estimator

Coming in Phase 7
-

+

The Carbon Estimator will calculate your operation's Scope 3 emissions profile and estimate carbon sequestration potential per field using USDA emission factors.

@@ -35,19 +35,19 @@ export function CarbonEstimatorModule() { ['📄', 'Carbon Credit PDF', 'Downloadable eligibility summary for carbon marketplaces'], ['📡', 'Marketplace Handoff', 'Send your credit profile to Nori, Pachama, or others (Phase 8)'], ].map(([icon, title, desc]) => ` -
+
${icon}
-

${title}

-

${desc}

+

${title}

+

${desc}

`).join('')}
-
-

Your field profile data is already being collected.

-

Carbon estimates will populate automatically when Phase 7 lands.

+
+

Your field profile data is already being collected.

+

Carbon estimates will populate automatically when Phase 7 lands.

`; diff --git a/agrifine-extension/src/modules/dashboard/index.js b/agrifine-extension/src/modules/dashboard/index.js index bff6de4..566f840 100644 --- a/agrifine-extension/src/modules/dashboard/index.js +++ b/agrifine-extension/src/modules/dashboard/index.js @@ -41,13 +41,13 @@ export function DashboardModule() {
+ class="ag-input flex-1 rounded-xl" />
- +
@@ -55,12 +55,12 @@ export function DashboardModule() {
${CATEGORIES.map((c) => ` `).join('')}
+ class="ag-input" />
@@ -76,7 +76,7 @@ export function DashboardModule() { btn.addEventListener('click', async () => { activeCategory = btn.dataset.cat; container.querySelectorAll('.cat-btn').forEach((b) => { - b.className = `cat-btn text-xs px-2.5 py-1 rounded-full border transition border-gray-300 text-gray-600 hover:border-agri-400`; + b.className = `cat-btn text-xs px-2.5 py-1 rounded-full border transition border-night-500 text-gray-400 hover:border-agri-500`; }); btn.className = `cat-btn text-xs px-2.5 py-1 rounded-full border transition bg-agri-600 text-white border-agri-600`; await this._renderDashboard(container); @@ -124,7 +124,7 @@ export function DashboardModule() { maxTokens: 512, }); - answerEl.innerHTML = `

Answer

${escapeHtml(answer)}`; + answerEl.innerHTML = `

Answer

${escapeHtml(answer)}`; } catch (err) { answerEl.textContent = `Error: ${err.message}`; } finally { @@ -173,12 +173,12 @@ export function DashboardModule() {
${sourceIcon}
-

${escapeHtml(title)}

- ${sub ? `

${escapeHtml(sub)}

` : ''} +

${escapeHtml(title)}

+ ${sub ? `

${escapeHtml(sub)}

` : ''}
- ${escapeHtml(item._category)} + ${escapeHtml(item._category)} ${(item.tags ?? []).filter((t) => t !== item._category).slice(0, 2).map((t) => `${escapeHtml(t)}`).join('')} - ${date ? `${new Date(date).toLocaleDateString()}` : ''} + ${date ? `${new Date(date).toLocaleDateString()}` : ''}
diff --git a/agrifine-extension/src/modules/data-ingest/index.js b/agrifine-extension/src/modules/data-ingest/index.js index 79e4117..2d989f6 100644 --- a/agrifine-extension/src/modules/data-ingest/index.js +++ b/agrifine-extension/src/modules/data-ingest/index.js @@ -20,16 +20,16 @@ export function DataIngestModule() {
+ class="border-2 border-dashed border-night-500 rounded-xl p-6 text-center cursor-pointer hover:border-agri-500 hover:bg-night-800 transition"> -

Drop CSV, Excel, or PDF here

-

or click to select a file

+

Drop CSV, Excel, or PDF here

+

or click to select a file

-
+
@@ -48,16 +48,16 @@ export function DataIngestModule() { dropZone.addEventListener('dragover', (e) => { e.preventDefault(); - dropZone.classList.add('border-agri-600', 'bg-agri-50'); + dropZone.classList.add('border-agri-500', 'bg-night-800'); }); dropZone.addEventListener('dragleave', () => { - dropZone.classList.remove('border-agri-600', 'bg-agri-50'); + dropZone.classList.remove('border-agri-500', 'bg-night-800'); }); dropZone.addEventListener('drop', (e) => { e.preventDefault(); - dropZone.classList.remove('border-agri-600', 'bg-agri-50'); + dropZone.classList.remove('border-agri-500', 'bg-night-800'); const file = e.dataTransfer.files[0]; if (file) this._processFile(file, container); }); @@ -212,17 +212,17 @@ export function DataIngestModule() {
- ${f.type} -

${f.filename}

-

${new Date(f.uploadedAt).toLocaleDateString()}

+ ${f.type} +

${f.filename}

+

${new Date(f.uploadedAt).toLocaleDateString()}

-
- ${f.preview ? `
${f.preview}
` : ''} + ${f.preview ? `
${f.preview}
` : ''}
`).join(''); diff --git a/agrifine-extension/src/modules/field-profile/index.js b/agrifine-extension/src/modules/field-profile/index.js index 958b394..c4f58c1 100644 --- a/agrifine-extension/src/modules/field-profile/index.js +++ b/agrifine-extension/src/modules/field-profile/index.js @@ -23,27 +23,21 @@ export function FieldProfileModule() {
-