this repo has no description

chore: feat

dunkirk.sh 1a4b8da6 2df1b30f

verified
+1180 -259
+98 -63
README.md
··· 13 13 # Run tests 14 14 bun test 15 15 16 - # Evaluate classifier 17 - bun run evaluate 16 + # Build Google Apps Script 17 + bun run gas build 18 18 19 - # Generate GScript for Gmail 20 - bun run generate-gscript 21 - # → Creates build/filter-hybrid.gs 19 + # Copy build/Code.gs and paste into Apps Script editor 20 + # https://script.google.com 22 21 ``` 23 22 24 23 ## What Gets Filtered vs Kept ··· 43 42 44 43 ## How It Works 45 44 46 - 1. **TypeScript Classifier** (`src/classifier.ts`) - Source of truth, rule-based patterns 47 - 2. **GScript Generator** (`src/generate-gscript.ts`) - Converts TS to Apps Script 48 - 3. **Gmail Automation** (`build/filter-hybrid.gs`) - Runs in Gmail every 10 minutes 49 - 50 - ### Architecture 45 + **TypeScript → Google Apps Script Pipeline** 51 46 52 47 ``` 53 - TypeScript Classifier (100% accurate patterns) 48 + src/apps-script/Code.ts (TypeScript with type safety) 54 49 55 - GScript Generator 50 + ↓ bun run gas build (compile) 51 + 52 + build/Code.gs (Google Apps Script) 56 53 57 - Google Apps Script (build/filter-hybrid.gs) 54 + ↓ Manual copy/paste 58 55 59 - Gmail Auto-Filtering 56 + Google Apps Script → Gmail Auto-Filtering 60 57 ``` 61 58 62 - ## Workflow for Improving the Classifier 59 + ## Gmail Deployment 60 + 61 + ```bash 62 + # 1. Build 63 + bun run gas build 64 + 65 + # 2. Copy build/Code.gs contents 66 + 67 + # 3. Paste into Google Apps Script 68 + # https://script.google.com 69 + 70 + # 4. Also paste scripts/export-from-label.gs 71 + ``` 72 + 73 + Once deployed: 74 + 1. Set `DRY_RUN = false` in the Apps Script editor 75 + 2. Run `setupTriggers()` to enable auto-filtering every 10 minutes 76 + 3. Run `ensureLabels()` to create required labels 77 + 78 + ## Development Workflow 79 + 80 + ### Improving the Classifier 63 81 64 82 See [docs/WORKFLOW.md](docs/WORKFLOW.md) for detailed instructions. 65 83 66 84 ```bash 67 - # 1. Export emails from Gmail (run in Apps Script console) 68 - exportEmailsToDrive() 85 + # 1. Export emails from Gmail 86 + # Run exportEmailsToDrive() in Apps Script console 69 87 70 88 # 2. Label them interactively 71 89 bun run label new-emails.json ··· 73 91 # 3. Import and evaluate 74 92 bun run import new-emails-labeled.json 75 93 76 - # 4. If failures, update src/classifier.ts 94 + # 4. Update patterns in src/apps-script/Code.ts 77 95 78 - # 5. Test and deploy 96 + # 5. Test locally 79 97 bun test 80 - bun run generate-gscript 81 - # Copy build/filter-hybrid.gs to Apps Script 98 + 99 + # 6. Build and deploy 100 + bun run gas build 101 + # Copy build/Code.gs to Apps Script editor 82 102 ``` 103 + 104 + ### Adding New Patterns 105 + 106 + 1. Edit `src/apps-script/Code.ts` with type-safe TypeScript 107 + 2. Add tests in `src/classifier.test.ts` 108 + 3. Run `bun test` to verify 109 + 4. Build and deploy: `bun run gas build` then copy to Apps Script 110 + 111 + **Note**: Keep `src/classifier.ts` (local testing) and `src/apps-script/Code.ts` (deployed) in sync manually. 83 112 84 113 ## Project Structure 85 114 86 115 ``` 87 116 src/ 88 - classifier.ts - Main classifier logic (TypeScript) 117 + apps-script/ 118 + Code.ts - Apps Script source (TypeScript) 119 + appsscript.json - Apps Script manifest 120 + classifier.ts - Core classifier (for local testing) 89 121 classifier.test.ts - Unit tests 90 - types.ts - TypeScript types 91 - evaluate.ts - Evaluation tool 92 - generate-gscript.ts - TS → GScript generator 93 - label.ts - Interactive labeling CLI 94 - import-labeled.ts - Import labeled emails 122 + types.ts - TypeScript types 123 + evaluate.ts - Evaluation tool 124 + label.ts - Interactive labeling CLI 125 + import-labeled.ts - Import labeled emails 126 + build-gas.ts - Build/deploy script 95 127 96 128 scripts/ 97 - export-from-label.gs - Export emails from Gmail 129 + export-from-label.gs - Export emails from Gmail 98 130 99 - build/ - Generated files (gitignored) 100 - filter-hybrid.gs - Generated Gmail automation script 131 + build/ - Generated (gitignored) 132 + Code.gs - Compiled Apps Script 133 + compiled/ - Intermediate JavaScript 101 134 102 135 data/ 103 - labeled-emails.json - Main labeled dataset (58 emails) 104 - example-export.json - Example unlabeled export 136 + labeled-emails.json - Main dataset (58 emails) 137 + example-export.json - Example export 105 138 106 - docs/ 107 - WORKFLOW.md - Detailed workflow guide 139 + tsconfig.apps-script.json - TypeScript config for Apps Script 108 140 ``` 109 141 110 - ## Development 111 - 112 - ### Running Tests 142 + ## Commands 113 143 114 144 ```bash 115 - # Unit tests 116 - bun test 145 + # Testing & Evaluation 146 + bun test - Run unit tests 147 + bun run evaluate - Evaluate on labeled dataset 117 148 118 - # Full evaluation on labeled dataset 119 - bun run evaluate 149 + # Apps Script Deployment 150 + bun run gas build - Compile TypeScript → .gs 151 + 152 + # Labeling Workflow 153 + bun run label <file> - Label emails interactively 154 + bun run import <file> - Import labeled emails to dataset 120 155 ``` 121 156 122 - ### Adding New Patterns 157 + ## TypeScript Compilation 123 158 124 - 1. Update `src/classifier.ts` 125 - 2. Add tests in `src/classifier.test.ts` 126 - 3. Run `bun test` to verify 127 - 4. Run `bun run generate-gscript` to update GScript 128 - 5. Deploy `build/filter-hybrid.gs` to Gmail Apps Script 159 + Following [Google's official TypeScript guide](https://developers.google.com/apps-script/guides/typescript): 129 160 130 - ### Metrics 161 + - **Type safety**: Full `@types/google-apps-script` support 162 + - **Modern syntax**: ES6+ features (arrow functions, classes, etc.) 163 + - **Local development**: Edit with VS Code autocomplete 164 + - **Manual deployment**: Build locally, copy/paste to Apps Script 165 + - **No bundler overhead**: Simple TypeScript → JavaScript compilation 131 166 132 - - **Accuracy**: 100% (58/58 emails) 133 - - **Precision**: 100% (no false positives) 134 - - **Recall**: 100% (no false negatives) 135 - - **F1 Score**: 100% 167 + Configuration: 168 + - `tsconfig.apps-script.json` - Targets ES2015, no modules 169 + - `src/build-gas.ts` - Build script 136 170 137 - ## Gmail Deployment 171 + ## Metrics 138 172 139 - 1. Run `bun run generate-gscript` 140 - 2. Open [Google Apps Script](https://script.google.com) 141 - 3. Create new project 142 - 4. Copy contents of `build/filter-hybrid.gs` 143 - 5. Copy contents of `scripts/export-from-label.gs` (for exporting emails) 144 - 6. Set `DRY_RUN = false` when ready 145 - 7. Run `setupTriggers()` to enable auto-filtering 146 - 8. Run `ensureLabels()` to create required labels 173 + - **Accuracy**: 100% (58/58 emails correctly classified) 174 + - **Precision**: 100% (no false positives - no spam in inbox) 175 + - **Recall**: 100% (no false negatives - all important emails reach inbox) 176 + - **F1 Score**: 100% 147 177 148 178 ## Requirements 149 179 150 - - [Bun](https://bun.sh) runtime 180 + - [Bun](https://bun.sh) - JavaScript runtime 151 181 - Gmail account 152 - - Google Apps Script (for Gmail automation) 182 + - Google account for Apps Script 153 183 154 184 ## License 155 185 156 186 MIT 187 + 188 + ## References 189 + 190 + - [Google Apps Script TypeScript Guide](https://developers.google.com/apps-script/guides/typescript) 191 + - [@types/google-apps-script](https://www.npmjs.com/package/@types/google-apps-script)
+559
bun.lock
··· 1 + { 2 + "lockfileVersion": 1, 3 + "configVersion": 1, 4 + "workspaces": { 5 + "": { 6 + "name": "filter-college-spam", 7 + "dependencies": { 8 + "@types/bun": "latest", 9 + }, 10 + "devDependencies": { 11 + "@google/clasp": "^3.1.3", 12 + "@types/google-apps-script": "^2.0.8", 13 + "ts2gas": "^4.2.0", 14 + "typescript": "^5.9.3", 15 + }, 16 + }, 17 + }, 18 + "packages": { 19 + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], 20 + 21 + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], 22 + 23 + "@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.6", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.7", "@formatjs/intl-localematcher": "0.6.2", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } }, "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw=="], 24 + 25 + "@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="], 26 + 27 + "@formatjs/icu-messageformat-parser": ["@formatjs/icu-messageformat-parser@2.11.4", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/icu-skeleton-parser": "1.8.16", "tslib": "^2.8.0" } }, "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw=="], 28 + 29 + "@formatjs/icu-skeleton-parser": ["@formatjs/icu-skeleton-parser@1.8.16", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "tslib": "^2.8.0" } }, "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ=="], 30 + 31 + "@formatjs/intl": ["@formatjs/intl@3.1.8", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/fast-memoize": "2.2.7", "@formatjs/icu-messageformat-parser": "2.11.4", "intl-messageformat": "10.7.18", "tslib": "^2.8.0" }, "peerDependencies": { "typescript": "^5.6.0" }, "optionalPeers": ["typescript"] }, "sha512-LWXgwI5zTMatvR8w8kCNh/priDTOF/ZssokMBHJ7ZWXFoYLVOYo0EJERD9Eajv+xsfQO1QkuAt77KWQ1OI4mOQ=="], 32 + 33 + "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.2", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA=="], 34 + 35 + "@google/clasp": ["@google/clasp@3.1.3", "", { "dependencies": { "@formatjs/intl": "^3.1.6", "@modelcontextprotocol/sdk": "^1.12.1", "chalk": "^5.4.1", "chokidar": "^4.0.3", "cli-truncate": "^4.0.0", "commander": "^13.1.0", "debug": "^4.4.0", "fdir": "^6.4.4", "find-up": "^7.0.0", "fuzzy": "^0.1.3", "google-auth-library": "^9.15.1", "googleapis": "^148.0.0", "googleapis-common": "7.2.0", "inflection": "^3.0.2", "inquirer": "^12.6.0", "inquirer-autocomplete-standalone": "^0.8.1", "loud-rejection": "^2.2.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "open": "^10.1.2", "ora": "^8.1.1", "p-map": "^7.0.3", "picomatch": "^4.0.2", "read-package-up": "^11.0.0", "server-destroy": "^1.0.1", "split-lines": "^3.0.0", "strip-bom": "^5.0.0", "zod": "^3.25.36" }, "bin": { "clasp": "build/src/index.js" } }, "sha512-+X4BaNlP4l3LvuuTHUKiKHJclZNmJuBRycZFZw/Z9FVZJqYmDCZKBm1hdVPPkvfP4Q6xtijKGC+4YZGwt97bJQ=="], 36 + 37 + "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="], 38 + 39 + "@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="], 40 + 41 + "@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="], 42 + 43 + "@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="], 44 + 45 + "@inquirer/editor": ["@inquirer/editor@4.2.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/external-editor": "^1.0.3", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ=="], 46 + 47 + "@inquirer/expand": ["@inquirer/expand@4.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew=="], 48 + 49 + "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], 50 + 51 + "@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="], 52 + 53 + "@inquirer/input": ["@inquirer/input@4.3.1", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g=="], 54 + 55 + "@inquirer/number": ["@inquirer/number@3.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg=="], 56 + 57 + "@inquirer/password": ["@inquirer/password@4.0.23", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA=="], 58 + 59 + "@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="], 60 + 61 + "@inquirer/rawlist": ["@inquirer/rawlist@4.1.11", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw=="], 62 + 63 + "@inquirer/search": ["@inquirer/search@3.2.2", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA=="], 64 + 65 + "@inquirer/select": ["@inquirer/select@4.4.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w=="], 66 + 67 + "@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="], 68 + 69 + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.24.3", "", { "dependencies": { "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "jose": "^6.1.1", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.0" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-YgSHW29fuzKKAHTGe9zjNoo+yF8KaQPzDC2W9Pv41E7/57IfY+AMGJ/aDFlgTLcVVELoggKE4syABCE75u3NCw=="], 70 + 71 + "@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="], 72 + 73 + "@types/google-apps-script": ["@types/google-apps-script@2.0.8", "", {}, "sha512-mGPmzzdgBu1DlwrjOhFQ8u0se6AF/z4OpaTzOGwNKxwXZjE7J+IssfE3oL24j/S/p6aFiSTIptHZvbyqeZD8vA=="], 74 + 75 + "@types/mute-stream": ["@types/mute-stream@0.0.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-0yQLzYhCqGz7CQPE3iDmYjhb7KMBFOP+tBkyw+/Y2YyDI5wpS7itXXxneN1zSsUwWx3Ji6YiVYrhAnpQGS/vkw=="], 76 + 77 + "@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="], 78 + 79 + "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], 80 + 81 + "@types/wrap-ansi": ["@types/wrap-ansi@3.0.0", "", {}, "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g=="], 82 + 83 + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], 84 + 85 + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], 86 + 87 + "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], 88 + 89 + "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], 90 + 91 + "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], 92 + 93 + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], 94 + 95 + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], 96 + 97 + "array-find-index": ["array-find-index@1.0.2", "", {}, "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw=="], 98 + 99 + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], 100 + 101 + "bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="], 102 + 103 + "body-parser": ["body-parser@2.2.1", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw=="], 104 + 105 + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], 106 + 107 + "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], 108 + 109 + "bun-types": ["bun-types@1.3.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ=="], 110 + 111 + "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], 112 + 113 + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], 114 + 115 + "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=="], 116 + 117 + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], 118 + 119 + "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], 120 + 121 + "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], 122 + 123 + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], 124 + 125 + "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], 126 + 127 + "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], 128 + 129 + "cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="], 130 + 131 + "cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="], 132 + 133 + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], 134 + 135 + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], 136 + 137 + "commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], 138 + 139 + "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], 140 + 141 + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], 142 + 143 + "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], 144 + 145 + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], 146 + 147 + "cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="], 148 + 149 + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], 150 + 151 + "currently-unhandled": ["currently-unhandled@0.4.1", "", { "dependencies": { "array-find-index": "^1.0.1" } }, "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng=="], 152 + 153 + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], 154 + 155 + "decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="], 156 + 157 + "default-browser": ["default-browser@5.4.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg=="], 158 + 159 + "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="], 160 + 161 + "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], 162 + 163 + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], 164 + 165 + "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=="], 166 + 167 + "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], 168 + 169 + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], 170 + 171 + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], 172 + 173 + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], 174 + 175 + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], 176 + 177 + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], 178 + 179 + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], 180 + 181 + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], 182 + 183 + "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], 184 + 185 + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], 186 + 187 + "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], 188 + 189 + "eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="], 190 + 191 + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.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-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], 192 + 193 + "express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="], 194 + 195 + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], 196 + 197 + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 198 + 199 + "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], 200 + 201 + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], 202 + 203 + "figures": ["figures@5.0.0", "", { "dependencies": { "escape-string-regexp": "^5.0.0", "is-unicode-supported": "^1.2.0" } }, "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg=="], 204 + 205 + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 206 + 207 + "finalhandler": ["finalhandler@2.1.1", "", { "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-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], 208 + 209 + "find-up": ["find-up@7.0.0", "", { "dependencies": { "locate-path": "^7.2.0", "path-exists": "^5.0.0", "unicorn-magic": "^0.1.0" } }, "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g=="], 210 + 211 + "find-up-simple": ["find-up-simple@1.0.1", "", {}, "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ=="], 212 + 213 + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], 214 + 215 + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], 216 + 217 + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], 218 + 219 + "fuzzy": ["fuzzy@0.1.3", "", {}, "sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w=="], 220 + 221 + "gaxios": ["gaxios@6.7.1", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", "uuid": "^9.0.1" } }, "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ=="], 222 + 223 + "gcp-metadata": ["gcp-metadata@6.1.1", "", { "dependencies": { "gaxios": "^6.1.1", "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" } }, "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A=="], 224 + 225 + "get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="], 226 + 227 + "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=="], 228 + 229 + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], 230 + 231 + "google-auth-library": ["google-auth-library@9.15.1", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^6.1.1", "gcp-metadata": "^6.1.0", "gtoken": "^7.0.0", "jws": "^4.0.0" } }, "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng=="], 232 + 233 + "google-logging-utils": ["google-logging-utils@0.0.2", "", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="], 234 + 235 + "googleapis": ["googleapis@148.0.0", "", { "dependencies": { "google-auth-library": "^9.0.0", "googleapis-common": "^7.0.0" } }, "sha512-8PDG5VItm6E1TdZWDqtRrUJSlBcNwz0/MwCa6AL81y/RxPGXJRUwKqGZfCoVX1ZBbfr3I4NkDxBmeTyOAZSWqw=="], 236 + 237 + "googleapis-common": ["googleapis-common@7.2.0", "", { "dependencies": { "extend": "^3.0.2", "gaxios": "^6.0.3", "google-auth-library": "^9.7.0", "qs": "^6.7.0", "url-template": "^2.0.8", "uuid": "^9.0.0" } }, "sha512-/fhDZEJZvOV3X5jmD+fKxMqma5q2Q9nZNSF3kn1F18tpxmA86BcTxAGBQdM0N89Z3bEaIs+HVznSmFJEAmMTjA=="], 238 + 239 + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], 240 + 241 + "gtoken": ["gtoken@7.1.0", "", { "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" } }, "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw=="], 242 + 243 + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], 244 + 245 + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], 246 + 247 + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], 248 + 249 + "hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], 250 + 251 + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], 252 + 253 + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], 254 + 255 + "iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="], 256 + 257 + "index-to-position": ["index-to-position@1.2.0", "", {}, "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw=="], 258 + 259 + "inflection": ["inflection@3.0.2", "", {}, "sha512-+Bg3+kg+J6JUWn8J6bzFmOWkTQ6L/NHfDRSYU+EVvuKHDxUDHAXgqixHfVlzuBQaPOTac8hn43aPhMNk6rMe3g=="], 260 + 261 + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], 262 + 263 + "inquirer": ["inquirer@12.11.1", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/prompts": "^7.10.1", "@inquirer/type": "^3.0.10", "mute-stream": "^2.0.0", "run-async": "^4.0.6", "rxjs": "^7.8.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw=="], 264 + 265 + "inquirer-autocomplete-standalone": ["inquirer-autocomplete-standalone@0.8.1", "", { "dependencies": { "@inquirer/core": "^3.1.1", "@inquirer/type": "^1.1.2", "figures": "^5.0.0", "picocolors": "^1.0.0" } }, "sha512-mlzwCTiXDX1Cw4yJL5PCq32k23XYLTK8K6BDFoL1a76iJeFB5ul6IoMU9spgdDagl2SM7P6ZaCNjj8VNXRDPOQ=="], 266 + 267 + "intl-messageformat": ["intl-messageformat@10.7.18", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/fast-memoize": "2.2.7", "@formatjs/icu-messageformat-parser": "2.11.4", "tslib": "^2.8.0" } }, "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g=="], 268 + 269 + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], 270 + 271 + "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], 272 + 273 + "is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="], 274 + 275 + "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=="], 276 + 277 + "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="], 278 + 279 + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], 280 + 281 + "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], 282 + 283 + "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], 284 + 285 + "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], 286 + 287 + "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="], 288 + 289 + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 290 + 291 + "jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="], 292 + 293 + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], 294 + 295 + "json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="], 296 + 297 + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], 298 + 299 + "jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="], 300 + 301 + "jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="], 302 + 303 + "locate-path": ["locate-path@7.2.0", "", { "dependencies": { "p-locate": "^6.0.0" } }, "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA=="], 304 + 305 + "log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="], 306 + 307 + "loud-rejection": ["loud-rejection@2.2.0", "", { "dependencies": { "currently-unhandled": "^0.4.1", "signal-exit": "^3.0.2" } }, "sha512-S0FayMXku80toa5sZ6Ro4C+s+EtFDCsyJNG/AzFMfX3AxD5Si4dZsgzm/kKnbOxHl5Cv8jBlno8+3XYIh2pNjQ=="], 308 + 309 + "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], 310 + 311 + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], 312 + 313 + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], 314 + 315 + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], 316 + 317 + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], 318 + 319 + "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], 320 + 321 + "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], 322 + 323 + "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], 324 + 325 + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], 326 + 327 + "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], 328 + 329 + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], 330 + 331 + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], 332 + 333 + "normalize-package-data": ["normalize-package-data@6.0.2", "", { "dependencies": { "hosted-git-info": "^7.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g=="], 334 + 335 + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], 336 + 337 + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], 338 + 339 + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], 340 + 341 + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], 342 + 343 + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], 344 + 345 + "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], 346 + 347 + "open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], 348 + 349 + "ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="], 350 + 351 + "p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], 352 + 353 + "p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], 354 + 355 + "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], 356 + 357 + "parse-json": ["parse-json@8.3.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" } }, "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ=="], 358 + 359 + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], 360 + 361 + "path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], 362 + 363 + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], 364 + 365 + "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], 366 + 367 + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], 368 + 369 + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], 370 + 371 + "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], 372 + 373 + "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=="], 374 + 375 + "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], 376 + 377 + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], 378 + 379 + "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], 380 + 381 + "read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="], 382 + 383 + "read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], 384 + 385 + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], 386 + 387 + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], 388 + 389 + "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], 390 + 391 + "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=="], 392 + 393 + "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], 394 + 395 + "run-async": ["run-async@4.0.6", "", {}, "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ=="], 396 + 397 + "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], 398 + 399 + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], 400 + 401 + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], 402 + 403 + "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], 404 + 405 + "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=="], 406 + 407 + "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=="], 408 + 409 + "server-destroy": ["server-destroy@1.0.1", "", {}, "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ=="], 410 + 411 + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], 412 + 413 + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], 414 + 415 + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], 416 + 417 + "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=="], 418 + 419 + "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], 420 + 421 + "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=="], 422 + 423 + "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=="], 424 + 425 + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], 426 + 427 + "slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="], 428 + 429 + "spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], 430 + 431 + "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], 432 + 433 + "spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], 434 + 435 + "spdx-license-ids": ["spdx-license-ids@3.0.22", "", {}, "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ=="], 436 + 437 + "split-lines": ["split-lines@3.0.0", "", {}, "sha512-d0TpRBL/VfKDXsk8JxPF7zgF5pCUDdBMSlEL36xBgVeaX448t+yGXcJaikUyzkoKOJ0l6KpMfygzJU9naIuivw=="], 438 + 439 + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], 440 + 441 + "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="], 442 + 443 + "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=="], 444 + 445 + "strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], 446 + 447 + "strip-bom": ["strip-bom@5.0.0", "", {}, "sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A=="], 448 + 449 + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], 450 + 451 + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 452 + 453 + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], 454 + 455 + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], 456 + 457 + "ts2gas": ["ts2gas@4.2.0", "", { "dependencies": { "type-fest": "^2.1.0", "typescript": "^4.4.2" } }, "sha512-5xZugaeM3wKQPj/vrWnrtYjNh4xnIz6cGSW/smCe9OTmkh1+KvHpm7M7HLq/OnBaljf4+yKctC4AYimBi4T1/Q=="], 458 + 459 + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], 460 + 461 + "type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], 462 + 463 + "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=="], 464 + 465 + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], 466 + 467 + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], 468 + 469 + "unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], 470 + 471 + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], 472 + 473 + "url-template": ["url-template@2.0.8", "", {}, "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw=="], 474 + 475 + "uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], 476 + 477 + "validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], 478 + 479 + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], 480 + 481 + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], 482 + 483 + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], 484 + 485 + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], 486 + 487 + "wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], 488 + 489 + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], 490 + 491 + "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], 492 + 493 + "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], 494 + 495 + "yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="], 496 + 497 + "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], 498 + 499 + "zod-to-json-schema": ["zod-to-json-schema@3.25.0", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ=="], 500 + 501 + "@inquirer/core/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], 502 + 503 + "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], 504 + 505 + "figures/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], 506 + 507 + "inquirer-autocomplete-standalone/@inquirer/core": ["@inquirer/core@3.1.2", "", { "dependencies": { "@inquirer/type": "^1.1.2", "@types/mute-stream": "^0.0.1", "@types/node": "^20.4.8", "@types/wrap-ansi": "^3.0.0", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "cli-spinners": "^2.9.0", "cli-width": "^4.1.0", "figures": "^3.2.0", "mute-stream": "^1.0.0", "run-async": "^3.0.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^6.2.0" } }, "sha512-lR2GaqBkp42Ew9BOAOqf2pSp+ymVES1qN8OC90WWh45yeoYLl0Ty1GyCxmkKqBJtq/+Ea1MF12AdFcZcpRNFsw=="], 508 + 509 + "inquirer-autocomplete-standalone/@inquirer/type": ["@inquirer/type@1.5.5", "", { "dependencies": { "mute-stream": "^1.0.0" } }, "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA=="], 510 + 511 + "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], 512 + 513 + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 514 + 515 + "parse-json/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], 516 + 517 + "read-package-up/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], 518 + 519 + "read-pkg/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], 520 + 521 + "restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], 522 + 523 + "ts2gas/typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="], 524 + 525 + "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], 526 + 527 + "wrap-ansi/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], 528 + 529 + "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], 530 + 531 + "inquirer-autocomplete-standalone/@inquirer/core/@types/node": ["@types/node@20.19.25", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ=="], 532 + 533 + "inquirer-autocomplete-standalone/@inquirer/core/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], 534 + 535 + "inquirer-autocomplete-standalone/@inquirer/core/figures": ["figures@3.2.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg=="], 536 + 537 + "inquirer-autocomplete-standalone/@inquirer/core/mute-stream": ["mute-stream@1.0.0", "", {}, "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA=="], 538 + 539 + "inquirer-autocomplete-standalone/@inquirer/core/run-async": ["run-async@3.0.0", "", {}, "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q=="], 540 + 541 + "inquirer-autocomplete-standalone/@inquirer/core/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], 542 + 543 + "inquirer-autocomplete-standalone/@inquirer/type/mute-stream": ["mute-stream@1.0.0", "", {}, "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA=="], 544 + 545 + "wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], 546 + 547 + "wrap-ansi/string-width/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], 548 + 549 + "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 550 + 551 + "inquirer-autocomplete-standalone/@inquirer/core/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], 552 + 553 + "inquirer-autocomplete-standalone/@inquirer/core/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], 554 + 555 + "inquirer-autocomplete-standalone/@inquirer/core/figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], 556 + 557 + "inquirer-autocomplete-standalone/@inquirer/core/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 558 + } 559 + }
+7 -1
package.json
··· 6 6 "scripts": { 7 7 "test": "bun test src/classifier.test.ts", 8 8 "evaluate": "bun src/evaluate.ts data/labeled-emails.json", 9 - "generate-gscript": "bun src/generate-gscript.ts", 9 + "gas": "bun src/build-gas.ts", 10 10 "label": "bun src/label.ts", 11 11 "import": "bun src/import-labeled.ts" 12 12 }, 13 13 "dependencies": { 14 14 "@types/bun": "latest" 15 + }, 16 + "devDependencies": { 17 + "@google/clasp": "^3.1.3", 18 + "@types/google-apps-script": "^2.0.8", 19 + "ts2gas": "^4.2.0", 20 + "typescript": "^5.9.3" 15 21 } 16 22 }
+441
src/apps-script/Code.ts
··· 1 + // Apps Script classifier - compiled from TypeScript 2 + // This file is the source of truth for Gmail filtering logic 3 + 4 + // Configuration 5 + const AUTO_LABEL_NAME = "College/Auto"; 6 + const FILTERED_LABEL_NAME = "College/Filtered"; 7 + const APPROVED_LABEL_NAME = "College"; 8 + const DRY_RUN = true; 9 + 10 + const AI_BASE_URL = "https://ai.hackclub.com/proxy/v1/chat/completions"; 11 + const AI_MODEL = "deepseek/deepseek-r1-distill-qwen-32b"; 12 + 13 + const MAX_THREADS_PER_RUN = 75; 14 + const MAX_EXECUTION_TIME_MS = 4.5 * 60 * 1000; 15 + const GMAIL_BATCH_SIZE = 20; 16 + const AI_CONFIDENCE_THRESHOLD = 0.5; 17 + 18 + // Main entry points 19 + function ensureLabels(): void { 20 + getOrCreateLabel(AUTO_LABEL_NAME); 21 + getOrCreateLabel(FILTERED_LABEL_NAME); 22 + getOrCreateLabel(APPROVED_LABEL_NAME); 23 + Logger.log(`Labels ensured: ${AUTO_LABEL_NAME}, ${FILTERED_LABEL_NAME}, ${APPROVED_LABEL_NAME}`); 24 + } 25 + 26 + function runTriage(): void { 27 + const startTime = Date.now(); 28 + const autoLabel = getOrCreateLabel(AUTO_LABEL_NAME); 29 + const filteredLabel = getOrCreateLabel(FILTERED_LABEL_NAME); 30 + const approvedLabel = getOrCreateLabel(APPROVED_LABEL_NAME); 31 + 32 + const threads = autoLabel.getThreads(0, MAX_THREADS_PER_RUN); 33 + if (!threads.length) { 34 + Logger.log("No threads under College/Auto."); 35 + return; 36 + } 37 + 38 + Logger.log(`Processing ${threads.length} threads`); 39 + 40 + let stats = { 41 + wouldInbox: 0, 42 + wouldFiltered: 0, 43 + didInbox: 0, 44 + didFiltered: 0, 45 + errors: 0, 46 + skipped: 0 47 + }; 48 + 49 + for (let i = 0; i < threads.length; i++) { 50 + const elapsed = Date.now() - startTime; 51 + if (elapsed > MAX_EXECUTION_TIME_MS) { 52 + Logger.log(`Time limit reached. Processed ${i}/${threads.length}`); 53 + stats.skipped = threads.length - i; 54 + break; 55 + } 56 + 57 + const thread = threads[i]; 58 + 59 + try { 60 + processThread(thread, autoLabel, approvedLabel, filteredLabel, stats); 61 + } catch (e) { 62 + Logger.log(`ERROR: ${e}. FAIL-SAFE: Moving to inbox.`); 63 + stats.errors += 1; 64 + 65 + if (!DRY_RUN) { 66 + thread.removeLabel(autoLabel); 67 + thread.removeLabel(filteredLabel); 68 + thread.moveToInbox(); 69 + stats.didInbox += 1; 70 + } else { 71 + stats.wouldInbox += 1; 72 + } 73 + } 74 + 75 + if ((i + 1) % GMAIL_BATCH_SIZE === 0) { 76 + Utilities.sleep(100); 77 + } 78 + } 79 + 80 + const totalTime = ((Date.now() - startTime) / 1000).toFixed(2); 81 + Logger.log(`Summary: Inbox=${stats.wouldInbox}/${stats.didInbox}, Filtered=${stats.wouldFiltered}/${stats.didFiltered}, Errors=${stats.errors}, Time=${totalTime}s`); 82 + } 83 + 84 + function processThread( 85 + thread: GoogleAppsScript.Gmail.GmailThread, 86 + autoLabel: GoogleAppsScript.Gmail.GmailLabel, 87 + approvedLabel: GoogleAppsScript.Gmail.GmailLabel, 88 + filteredLabel: GoogleAppsScript.Gmail.GmailLabel, 89 + stats: any 90 + ): void { 91 + const msg = thread.getMessages()[thread.getMessages().length - 1]; 92 + if (!msg) throw new Error("No messages in thread"); 93 + 94 + const meta = { 95 + subject: safeStr(msg.getSubject()), 96 + body: safeStr(msg.getPlainBody(), 10000), 97 + from: safeStr(msg.getFrom()), 98 + }; 99 + 100 + if (!meta.subject && !meta.body) { 101 + Logger.log(`WARNING: No content. FAIL-SAFE: Moving to inbox.`); 102 + applyInboxAction(thread, autoLabel, approvedLabel, filteredLabel, stats, "no content"); 103 + return; 104 + } 105 + 106 + const result = classifyEmail(meta); 107 + 108 + Logger.log(`[${thread.getId()}] Relevant=${result.pertains} Confidence=${result.confidence} Reason="${result.reason}"`); 109 + 110 + if (result.pertains) { 111 + applyInboxAction(thread, autoLabel, approvedLabel, filteredLabel, stats, result.reason); 112 + } else { 113 + applyFilteredAction(thread, autoLabel, filteredLabel, stats, result.reason); 114 + } 115 + } 116 + 117 + function applyInboxAction( 118 + thread: GoogleAppsScript.Gmail.GmailThread, 119 + autoLabel: GoogleAppsScript.Gmail.GmailLabel, 120 + approvedLabel: GoogleAppsScript.Gmail.GmailLabel, 121 + filteredLabel: GoogleAppsScript.Gmail.GmailLabel, 122 + stats: any, 123 + reason: string 124 + ): void { 125 + if (DRY_RUN) { 126 + stats.wouldInbox += 1; 127 + Logger.log(` DRY_RUN: Would move to Inbox (${reason})`); 128 + } else { 129 + thread.removeLabel(autoLabel); 130 + thread.removeLabel(filteredLabel); 131 + thread.addLabel(approvedLabel); 132 + thread.moveToInbox(); 133 + stats.didInbox += 1; 134 + Logger.log(` Applied: Moved to Inbox (${reason})`); 135 + } 136 + } 137 + 138 + function applyFilteredAction( 139 + thread: GoogleAppsScript.Gmail.GmailThread, 140 + autoLabel: GoogleAppsScript.Gmail.GmailLabel, 141 + filteredLabel: GoogleAppsScript.Gmail.GmailLabel, 142 + stats: any, 143 + reason: string 144 + ): void { 145 + if (DRY_RUN) { 146 + stats.wouldFiltered += 1; 147 + Logger.log(` DRY_RUN: Would filter (${reason})`); 148 + } else { 149 + thread.removeLabel(autoLabel); 150 + thread.addLabel(filteredLabel); 151 + if (thread.isInInbox()) thread.moveToArchive(); 152 + stats.didFiltered += 1; 153 + Logger.log(` Applied: Filtered (${reason})`); 154 + } 155 + } 156 + 157 + // Classifier 158 + interface ClassificationResult { 159 + pertains: boolean; 160 + reason: string; 161 + confidence: number; 162 + } 163 + 164 + interface EmailMeta { 165 + subject: string; 166 + body: string; 167 + from: string; 168 + } 169 + 170 + function classifyEmail(meta: EmailMeta): ClassificationResult { 171 + const subject = meta.subject.toLowerCase(); 172 + const body = meta.body.toLowerCase(); 173 + const combined = subject + " " + body; 174 + 175 + // Security alerts - always relevant 176 + const securityResult = checkSecurity(combined); 177 + if (securityResult) return securityResult; 178 + 179 + // Student action confirmations 180 + const actionResult = checkStudentAction(combined); 181 + if (actionResult) return actionResult; 182 + 183 + // Accepted student info 184 + const acceptedResult = checkAccepted(combined); 185 + if (acceptedResult) return acceptedResult; 186 + 187 + // Dual enrollment 188 + const dualResult = checkDualEnrollment(combined); 189 + if (dualResult) return dualResult; 190 + 191 + // Scholarships 192 + const scholarshipResult = checkScholarship(subject, combined); 193 + if (scholarshipResult) return scholarshipResult; 194 + 195 + // Financial aid 196 + const aidResult = checkFinancialAid(combined); 197 + if (aidResult) return aidResult; 198 + 199 + // Marketing/spam 200 + const irrelevantResult = checkIrrelevant(combined); 201 + if (irrelevantResult) return irrelevantResult; 202 + 203 + // Default to not relevant 204 + return { pertains: false, reason: "No clear relevance indicators", confidence: 0.3 }; 205 + } 206 + 207 + function checkSecurity(combined: string): ClassificationResult | null { 208 + const patterns = [ 209 + /\bpassword\s+(reset|change|update|expired)\b/, 210 + /\breset\s+your\s+password\b/, 211 + /\baccount\s+security\b/, 212 + /\bsecurity\s+alert\b/, 213 + /\bunusual\s+(sign[- ]?in|activity)\b/, 214 + /\bverification\s+code\b/, 215 + /\b(2fa|mfa|two[- ]factor)\b/, 216 + /\bcompromised\s+account\b/, 217 + /\baccount\s+(locked|suspended)\b/, 218 + /\bsuspicious\s+activity\b/ 219 + ]; 220 + 221 + for (let i = 0; i < patterns.length; i++) { 222 + if (patterns[i].test(combined)) { 223 + if (/\bsaving.*\bon\s+tuition\b|\btuition.*\bsaving\b/.test(combined)) { 224 + continue; 225 + } 226 + return { pertains: true, reason: "Security/password alert", confidence: 1.0 }; 227 + } 228 + } 229 + return null; 230 + } 231 + 232 + function checkStudentAction(combined: string): ClassificationResult | null { 233 + const patterns = [ 234 + /\bapplication\s+(received|complete|submitted|confirmation)\b/, 235 + /\breceived\s+your\s+application\b/, 236 + /\bthank\s+you\s+for\s+(applying|submitting)\b/, 237 + /\benrollment\s+confirmation\b/, 238 + /\bconfirmation\s+(of|for)\s+(your\s+)?(application|enrollment)\b/, 239 + /\byour\s+application\s+(has\s+been|is)\s+(received|complete)\b/ 240 + ]; 241 + 242 + for (let i = 0; i < patterns.length; i++) { 243 + if (patterns[i].test(combined)) { 244 + if (/\bhow\s+to\s+apply\b|\bapply\s+now\b|\bstart\s+(your\s+)?application\b/.test(combined)) { 245 + continue; 246 + } 247 + return { pertains: true, reason: "Application/enrollment confirmation", confidence: 0.95 }; 248 + } 249 + } 250 + return null; 251 + } 252 + 253 + function checkAccepted(combined: string): ClassificationResult | null { 254 + const patterns = [ 255 + /\baccepted\s+(student\s+)?portal\b/, 256 + /\byour\s+(personalized\s+)?accepted\s+portal\b/, 257 + /\bdeposit\s+(today|now|by|to\s+reserve)\b/, 258 + /\breserve\s+your\s+(place|spot)\b/, 259 + /\bcongratulations.*\baccepted\b/, 260 + /\byou\s+(have\s+been|are|were)\s+accepted\b/, 261 + /\badmission\s+(decision|offer)\b/, 262 + /\benroll(ment)?\s+deposit\b/ 263 + ]; 264 + 265 + for (let i = 0; i < patterns.length; i++) { 266 + if (patterns[i].test(combined)) { 267 + if (/\bacceptance\s+rate\b|\bhigh\s+acceptance\b|\bpre[- ]admit(ted)?\b|\bautomatic\s+admission\b/.test(combined)) { 268 + continue; 269 + } 270 + if (/\byou\s+will\s+(also\s+)?receive\s+(an?\s+)?(accelerated\s+)?admission\s+decision\b/.test(combined)) { 271 + continue; 272 + } 273 + if (/\breceive\s+an\s+admission\s+decision\s+within\b/.test(combined)) { 274 + continue; 275 + } 276 + return { pertains: true, reason: "Accepted student information", confidence: 0.95 }; 277 + } 278 + } 279 + return null; 280 + } 281 + 282 + function checkDualEnrollment(combined: string): ClassificationResult | null { 283 + const patterns = [ 284 + /\bdual\s+enrollment\b/, 285 + /\bcourse\s+(registration|deletion|added|dropped)\b/, 286 + /\bspring\s+\d{4}\s+(course|on[- ]campus)\b/, 287 + /\bhow\s+to\s+register\b.*\b(course|class)/ 288 + ]; 289 + 290 + for (let i = 0; i < patterns.length; i++) { 291 + if (patterns[i].test(combined)) { 292 + if (/\blearn\s+more\s+about\b|\binterested\s+in\b|\bconsider\s+joining\b/.test(combined)) { 293 + continue; 294 + } 295 + return { pertains: true, reason: "Dual enrollment course information", confidence: 0.9 }; 296 + } 297 + } 298 + return null; 299 + } 300 + 301 + function checkScholarship(subject: string, combined: string): ClassificationResult | null { 302 + // Specific scholarship applications 303 + if (/\bapply\s+for\s+(the\s+)?.*\bscholarship\b/.test(subject)) { 304 + if (/\bpresident'?s\b|\bministry\b|\bimpact\b/.test(combined)) { 305 + return { pertains: true, reason: "Scholarship application opportunity", confidence: 0.75 }; 306 + } 307 + } 308 + 309 + // Not awarded patterns (check first) 310 + const notAwardedPatterns = [ 311 + /\bscholarship\b.*\b(held|reserved)\s+for\s+you\b/, 312 + /\b(held|reserved)\s+for\s+you\b/, 313 + /\bconsider(ed|ation)\b.*\bscholarship\b/, 314 + /\bscholarship\b.*\bconsider(ed|ation)\b/, 315 + /\beligible\s+for\b.*\bscholarship\b/, 316 + /\bscholarship\b.*\beligible\b/, 317 + /\bmay\s+qualify\b.*\bscholarship\b/ 318 + ]; 319 + 320 + if (/\bscholarship\b/.test(combined)) { 321 + for (let i = 0; i < notAwardedPatterns.length; i++) { 322 + if (notAwardedPatterns[i].test(combined)) { 323 + return { pertains: false, reason: "Scholarship not actually awarded", confidence: 0.9 }; 324 + } 325 + } 326 + } 327 + 328 + // Awarded patterns 329 + const awardedPatterns = [ 330 + /\bcongratulations\b.*\bscholarship\b/, 331 + /\byou\s+(have|received|are\s+awarded|won)\b.*\bscholarship\b/, 332 + /\bwe\s+(are\s+)?(pleased\s+to\s+)?award(ing)?\b.*\bscholarship\b/, 333 + /\bscholarship\s+(offer|award)\b/ 334 + ]; 335 + 336 + for (let i = 0; i < awardedPatterns.length; i++) { 337 + if (awardedPatterns[i].test(combined)) { 338 + return { pertains: true, reason: "Scholarship awarded", confidence: 0.95 }; 339 + } 340 + } 341 + 342 + return null; 343 + } 344 + 345 + function checkFinancialAid(combined: string): ClassificationResult | null { 346 + const readyPatterns = [ 347 + /\bfinancial\s+aid\b.*\boffer\b.*\b(ready|available)\b/, 348 + /\baward\s+letter\b.*\b(ready|available|posted|view)\b/, 349 + /\b(view|review)\s+(your\s+)?award\s+letter\b/, 350 + /\byour\s+aid\s+is\s+ready\b/ 351 + ]; 352 + 353 + const notReadyPatterns = [ 354 + /\blearn\s+more\s+about\b.*\bfinancial\s+aid\b/, 355 + /\bapply\b.*\b(for\s+)?financial\s+aid\b/, 356 + /\bcomplete\s+(your\s+)?fafsa\b/, 357 + /\bpriority\s+(deadline|consideration)\b.*\bfinancial\s+aid\b/ 358 + ]; 359 + 360 + for (let i = 0; i < readyPatterns.length; i++) { 361 + if (readyPatterns[i].test(combined)) { 362 + for (let j = 0; j < notReadyPatterns.length; j++) { 363 + if (notReadyPatterns[j].test(combined)) { 364 + return null; 365 + } 366 + } 367 + return { pertains: true, reason: "Financial aid offer ready", confidence: 0.95 }; 368 + } 369 + } 370 + return null; 371 + } 372 + 373 + function checkIrrelevant(combined: string): ClassificationResult | null { 374 + const patterns = [ 375 + /\bstudent\s+life\s+blog\b/, 376 + /\bnewsletter\b/, 377 + /\bweekly\s+(digest|update)\b/, 378 + /\bupcoming\s+events\b/, 379 + /\bjoin\s+us\s+(for|at)\b/, 380 + /\bopen\s+house\b/, 381 + /\bvirtual\s+tour\b/, 382 + /\bhaven'?t\s+applied.*yet\b/, 383 + /\bstill\s+time\s+to\s+apply\b/, 384 + /\bhow\s+is\s+your\s+college\s+search\b/, 385 + /\bextended.*\bpriority\s+deadline\b/, 386 + /\bpriority\s+deadline.*\bextended\b/, 387 + /\bsummer\s+(academy|camp|program)\b/, 388 + /\bugly\s+sweater\b/, 389 + /\bi\s+hope\s+you\s+have\s+been\s+receiving\s+my\s+emails\b/, 390 + /\bam\s+i\s+reaching\b/, 391 + /\byou\s+are\s+on\s+.*\s+(radar|list)\b/, 392 + /\bi\s+want\s+to\s+make\s+sure\s+you\s+know\b/, 393 + /\byou'?re\s+invited\s+to\s+submit\b/, 394 + /\bi'?m\s+eager\s+to\s+consider\s+you\b/, 395 + /\bsubmit\s+your\s+.*\s+application\b/, 396 + /\bpriority\s+status\b.*\bsubmit.*application\b/ 397 + ]; 398 + 399 + for (let i = 0; i < patterns.length; i++) { 400 + if (patterns[i].test(combined)) { 401 + return { pertains: false, reason: "Marketing/newsletter/spam", confidence: 0.95 }; 402 + } 403 + } 404 + 405 + if (/\bhaven'?t\s+applied\b/.test(combined)) { 406 + return { pertains: false, reason: "Unsolicited outreach", confidence: 0.95 }; 407 + } 408 + 409 + return null; 410 + } 411 + 412 + // Utilities 413 + function getOrCreateLabel(name: string): GoogleAppsScript.Gmail.GmailLabel { 414 + return GmailApp.getUserLabelByName(name) || GmailApp.createLabel(name); 415 + } 416 + 417 + function safeStr(s: string | null, maxLen?: number): string { 418 + if (s === null || s === undefined) return ""; 419 + const str = s.toString().trim(); 420 + if (maxLen && str.length > maxLen) return str.slice(0, maxLen); 421 + return str; 422 + } 423 + 424 + function setupTriggers(): void { 425 + // Delete existing triggers 426 + const triggers = ScriptApp.getProjectTriggers(); 427 + for (let i = 0; i < triggers.length; i++) { 428 + if (triggers[i].getHandlerFunction() === "runTriage") { 429 + ScriptApp.deleteTrigger(triggers[i]); 430 + } 431 + } 432 + 433 + // Create new trigger 434 + ScriptApp.newTrigger("runTriage") 435 + .timeBased() 436 + .everyMinutes(10) 437 + .create(); 438 + 439 + Logger.log("Trigger created: runTriage every 10 minutes"); 440 + } 441 +
+11
src/apps-script/appsscript.json
··· 1 + { 2 + "timeZone": "America/New_York", 3 + "dependencies": {}, 4 + "exceptionLogging": "STACKDRIVER", 5 + "runtimeVersion": "V8", 6 + "oauthScopes": [ 7 + "https://www.googleapis.com/auth/gmail.modify", 8 + "https://www.googleapis.com/auth/gmail.labels", 9 + "https://www.googleapis.com/auth/script.external_request" 10 + ] 11 + }
+47
src/build-gas.ts
··· 1 + #!/usr/bin/env bun 2 + // Build script for Google Apps Script 3 + 4 + import { execSync } from "child_process"; 5 + 6 + const command = process.argv[2] || "build"; 7 + 8 + if (command === "build") { 9 + console.log("🔨 Building for Apps Script (local .gs file)...\n"); 10 + 11 + // Compile TypeScript 12 + console.log("1️⃣ Compiling TypeScript..."); 13 + try { 14 + execSync("tsc -p tsconfig.apps-script.json", { stdio: "inherit" }); 15 + console.log("✅ TypeScript compiled\n"); 16 + } catch (e) { 17 + console.error("❌ TypeScript compilation failed"); 18 + process.exit(1); 19 + } 20 + 21 + // Create .gs file 22 + console.log("2️⃣ Creating .gs file..."); 23 + const { mkdirSync, readFileSync, writeFileSync } = await import("fs"); 24 + mkdirSync("build", { recursive: true }); 25 + const js = readFileSync("build/compiled/Code.js", "utf-8"); 26 + 27 + const header = `// Auto-generated from TypeScript at: ${new Date().toISOString()} 28 + // Source: src/apps-script/Code.ts 29 + // DO NOT EDIT THIS FILE DIRECTLY - Edit the TypeScript source instead 30 + 31 + `; 32 + 33 + writeFileSync("build/Code.gs", header + js); 34 + console.log("✅ Created build/Code.gs\n"); 35 + 36 + console.log("🎉 Build complete!"); 37 + console.log("\n📋 Next steps:"); 38 + console.log(" 1. Open https://script.google.com"); 39 + console.log(" 2. Create a new project (or open existing)"); 40 + console.log(" 3. Copy build/Code.gs"); 41 + console.log(" 4. Paste into the Code.gs file in Apps Script editor"); 42 + console.log(" 5. Save and run setupTriggers()"); 43 + } else { 44 + console.log("Usage: bun run gas [build]"); 45 + console.log("\nCommands:"); 46 + console.log(" build - Compile TypeScript to .gs file (default)"); 47 + }
-195
src/generate-gscript.ts
··· 1 - #!/usr/bin/env bun 2 - // Generate GScript-compatible classifier code from TypeScript rules 3 - 4 - import { readFile, writeFile } from "fs/promises"; 5 - 6 - // Read the classifier 7 - const classifierSrc = await readFile("src/classifier.ts", "utf-8"); 8 - 9 - // Extract patterns from each rule function 10 - const extractPatterns = (functionName: string): string[] => { 11 - const match = classifierSrc.match(new RegExp(`private ${functionName}[^}]+\\[([^\\]]+)\\]`, "s")); 12 - if (!match) return []; 13 - 14 - return match[1] 15 - .split(/,\s*/) 16 - .map(p => p.trim()) 17 - .filter(p => p.startsWith("/")); 18 - }; 19 - 20 - const securityPatterns = extractPatterns("checkSecurity"); 21 - const studentActionPatterns = extractPatterns("checkStudentAction"); 22 - const acceptedPatterns = extractPatterns("checkAccepted"); 23 - const scholarshipAwardedPatterns = classifierSrc.match(/awardedPatterns = \[([^\]]+)\]/s)?.[1] 24 - .split(/,\s*/).map(p => p.trim()).filter(p => p.startsWith("/")) || []; 25 - const scholarshipNotAwardedPatterns = classifierSrc.match(/notAwardedPatterns = \[([^\]]+)\]/s)?.[1] 26 - .split(/,\s*/).map(p => p.trim()).filter(p => p.startsWith("/")) || []; 27 - const irrelevantPatterns = extractPatterns("checkIrrelevant"); 28 - 29 - // Generate GScript code 30 - const gscript = ` 31 - // Auto-generated from classifier.ts - DO NOT EDIT MANUALLY 32 - // Generated at: ${new Date().toISOString()} 33 - 34 - function classifyEmailTS(meta) { 35 - const subject = (meta.subject || "").toLowerCase(); 36 - const body = (meta.body || "").toLowerCase(); 37 - const from = (meta.from || "").toLowerCase(); 38 - const combined = subject + " " + body; 39 - 40 - // Security alerts - always relevant 41 - const securityPatterns = [ 42 - ${securityPatterns.join(",\n ")} 43 - ]; 44 - 45 - for (const pattern of securityPatterns) { 46 - if (pattern.test(combined)) { 47 - // Exclude tuition savings marketing 48 - if (/\\bsaving.*\\bon\\s+tuition\\b|\\btuition.*\\bsaving\\b/.test(combined)) { 49 - continue; 50 - } 51 - return { 52 - pertains: true, 53 - reason: "Security/password alert - always important", 54 - confidence: 1.0 55 - }; 56 - } 57 - } 58 - 59 - // Student action confirmations 60 - const actionPatterns = [ 61 - ${studentActionPatterns.join(",\n ")} 62 - ]; 63 - 64 - for (const pattern of actionPatterns) { 65 - if (pattern.test(combined)) { 66 - if (/\\bhow\\s+to\\s+apply\\b|\\bapply\\s+now\\b|\\bstart\\s+(your\\s+)?application\\b/.test(combined)) { 67 - continue; 68 - } 69 - return { 70 - pertains: true, 71 - reason: "Confirmation of student action", 72 - confidence: 0.95 73 - }; 74 - } 75 - } 76 - 77 - // Accepted student info 78 - const acceptedPatterns = [ 79 - ${acceptedPatterns.join(",\n ")} 80 - ]; 81 - 82 - for (const pattern of acceptedPatterns) { 83 - if (pattern.test(combined)) { 84 - if (/\\bacceptance\\s+rate\\b|\\bhigh\\s+acceptance\\b|\\bpre[- ]admit(ted)?\\b|\\bautomatic\\s+admission\\b/.test(combined)) { 85 - continue; 86 - } 87 - return { 88 - pertains: true, 89 - reason: "Accepted student portal/deposit information", 90 - confidence: 0.95 91 - }; 92 - } 93 - } 94 - 95 - // Dual enrollment 96 - if (/\\bdual\\s+enrollment\\b|\\bcourse\\s+(registration|deletion|added|dropped)\\b/.test(combined)) { 97 - if (!/\\blearn\\s+more\\s+about\\b|\\binterested\\s+in\\b|\\bconsider\\s+joining\\b/.test(combined)) { 98 - return { 99 - pertains: true, 100 - reason: "Dual enrollment course information", 101 - confidence: 0.9 102 - }; 103 - } 104 - } 105 - 106 - // Scholarships - check specific applications first 107 - if (/\\bapply\\s+for\\s+(the\\s+)?.*\\bscholarship\\b/.test(subject)) { 108 - if (/\\bpresident'?s\\b|\\bministry\\b|\\bimpact\\b/.test(combined)) { 109 - return { 110 - pertains: true, 111 - reason: "Scholarship application opportunity", 112 - confidence: 0.75 113 - }; 114 - } 115 - } 116 - 117 - // Scholarship not awarded (check before awarded) 118 - const scholarshipNotAwardedPatterns = [ 119 - ${scholarshipNotAwardedPatterns.join(",\n ")} 120 - ]; 121 - 122 - if (/\\bscholarship\\b/.test(combined)) { 123 - for (const pattern of scholarshipNotAwardedPatterns) { 124 - if (pattern.test(combined)) { 125 - return { 126 - pertains: false, 127 - reason: "Scholarship not actually awarded", 128 - confidence: 0.9 129 - }; 130 - } 131 - } 132 - } 133 - 134 - // Scholarship awarded 135 - const scholarshipAwardedPatterns = [ 136 - ${scholarshipAwardedPatterns.join(",\n ")} 137 - ]; 138 - 139 - for (const pattern of scholarshipAwardedPatterns) { 140 - if (pattern.test(combined)) { 141 - return { 142 - pertains: true, 143 - reason: "Scholarship actually awarded", 144 - confidence: 0.95 145 - }; 146 - } 147 - } 148 - 149 - // Financial aid ready 150 - if (/\\bfinancial\\s+aid\\b.*\\boffer\\b.*\\b(ready|available)\\b|\\baward\\s+letter\\b.*\\b(ready|available)\\b/.test(combined)) { 151 - if (!/\\blearn\\s+more\\s+about\\b|\\bapply\\b|\\bcomplete\\s+(your\\s+)?fafsa\\b/.test(combined)) { 152 - return { 153 - pertains: true, 154 - reason: "Financial aid offer ready", 155 - confidence: 0.95 156 - }; 157 - } 158 - } 159 - 160 - // Marketing/spam - definitely not relevant 161 - const irrelevantPatterns = [ 162 - ${irrelevantPatterns.join(",\n ")} 163 - ]; 164 - 165 - for (const pattern of irrelevantPatterns) { 166 - if (pattern.test(combined)) { 167 - return { 168 - pertains: false, 169 - reason: "Marketing/newsletter/unsolicited outreach", 170 - confidence: 0.95 171 - }; 172 - } 173 - } 174 - 175 - // Haven't applied yet 176 - if (/\\bhaven'?t\\s+applied\\b/.test(combined)) { 177 - return { 178 - pertains: false, 179 - reason: "Unsolicited email where student has not applied", 180 - confidence: 0.95 181 - }; 182 - } 183 - 184 - // Default to not relevant 185 - return { 186 - pertains: false, 187 - reason: "No clear relevance indicators found", 188 - confidence: 0.3 189 - }; 190 - } 191 - `.trim(); 192 - 193 - await writeFile("build/filter-hybrid.gs", gscript); 194 - console.log("✅ Generated build/filter-hybrid.gs"); 195 - console.log(" Deploy this file to Google Apps Script");
+17
tsconfig.apps-script.json
··· 1 + { 2 + "compilerOptions": { 3 + "target": "ES2015", 4 + "module": "none", 5 + "lib": ["ES2015"], 6 + "noImplicitAny": true, 7 + "strict": false, 8 + "outDir": "build/compiled", 9 + "removeComments": false, 10 + "sourceMap": false, 11 + "esModuleInterop": true, 12 + "skipLibCheck": true, 13 + "types": ["google-apps-script"] 14 + }, 15 + "include": ["src/apps-script/**/*.ts"], 16 + "exclude": ["node_modules"] 17 + }