feat: Introduce biome (#25664)

* Configure biome

* Fix companion build

* fix: remove generated files from formatter ignore list to enable proper formatting

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add explicit stripe dependency to @calcom/features to fix type resolution

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: rename const require to nodeRequire in generate-swagger.ts to avoid TypeScript reserved identifier conflict

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add guard for document in makeBodyVisible to prevent test environment teardown errors

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: replace ESLint with Biome CLI in embed-code-generator.e2e.ts

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: address cubic review comments

- Fix invalid --reporter-path Biome CLI option by using shell redirection
- Fix packages/lib lint report filename (app-store.json -> lib.json)
- Add typescript-eslint and eslint back to companion for lint:react-compiler
- Add missing restricted import rules to biome.json:
  - packages/lib: add ../trpc/** and @trpc/server restrictions
  - packages/trpc: add ../apps/web/** restriction

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: regenerate companion bun.lock after adding eslint dependencies

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Remove remaining eslint things

* add tailwind directives

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Volnei Munhoz
2025-12-29 19:41:41 -03:00
committed by GitHub
parent 96dc3b5cc6
commit 7c373ddad6
80 changed files with 1024 additions and 3946 deletions
-19
View File
@@ -1,19 +0,0 @@
node_modules
.next
public
**/**/node_modules
**/**/.next
**/**/public
*.lock
*.log
.gitignore
.npmignore
.prettierignore
.DS_Store
.eslintignore
packages/prisma/zod
packages/prisma/enums
apps/web/public/embed
packages/ui/components/icon/dynamicIconImports.tsx
-1
View File
@@ -1 +0,0 @@
module.exports = require("./packages/config/prettier-preset");
+8 -9
View File
@@ -1,13 +1,12 @@
{
"recommendations": [
"DavidAnson.vscode-markdownlint", // markdown linting
"yzhang.markdown-all-in-one", // nicer markdown support
"esbenp.prettier-vscode", // prettier plugin
"dbaeumer.vscode-eslint", // eslint plugin
"ban.spellright", // Spell check for docs
"stripe.vscode-stripe", // stripe VSCode extension
"Prisma.prisma", // syntax|format|completion for prisma
"rebornix.project-snippets", // Share useful snippets between collaborators
"inlang.vs-code-extension" // improved i18n DX
"biomejs.biome",
"DavidAnson.vscode-markdownlint",
"yzhang.markdown-all-in-one",
"ban.spellright",
"stripe.vscode-stripe",
"Prisma.prisma",
"rebornix.project-snippets",
"inlang.vs-code-extension"
]
}
+16 -8
View File
@@ -16,6 +16,8 @@ You are a senior Cal.com engineer working in a Yarn/Turbo monorepo. You prioriti
- Use `date-fns` or native `Date` instead of Day.js when timezone awareness isn't needed
- Put permission checks in `page.tsx`, never in `layout.tsx`
- Use `ast-grep` for searching if available; otherwise use `rg` (ripgrep), then fall back to `grep`
- Use Biome for formatting and linting
## Don't
@@ -36,11 +38,8 @@ You are a senior Cal.com engineer working in a Yarn/Turbo monorepo. You prioriti
# Type check - always run on changed files
yarn type-check:ci --force
# Lint single file
yarn eslint --fix path/to/file.tsx
# Format single file
yarn prettier --write path/to/file.tsx
# Lint and format single file
yarn biome check --write path/to/file.tsx
# Unit test specific file
yarn vitest run path/to/file.test.ts
@@ -69,9 +68,9 @@ yarn dev # Start dev server
yarn dx # Dev with database setup
# Build & check
yarn build # Build all packages
yarn lint:fix # Lint and fix all
yarn type-check # Type check all
yarn build # Build all packages
yarn biome check --write . # Lint and format all
yarn type-check # Type check all
# Tests (use TZ=UTC for consistency)
TZ=UTC yarn test # All unit tests
@@ -82,6 +81,14 @@ yarn prisma generate # Regenerate types after schema changes
yarn workspace @calcom/prisma db-migrate # Run migrations
```
### Biome focused workflow
+
```bash
yarn biome check --write .
yarn type-check:ci --force
```
## Boundaries
### Always do
@@ -89,6 +96,7 @@ yarn workspace @calcom/prisma db-migrate # Run migrations
- Run relevant tests before pushing
- Use `select` in Prisma queries
- Follow conventional commits for PR titles
- Run Biome before pushing
### Ask first
- Adding new dependencies
+4 -4
View File
@@ -16,11 +16,11 @@
## Lint & Type Check
- `yarn lint` - Run ESLint on codebase
- `yarn lint:fix` - Run ESLint and fix issues
- `yarn lint:report` - Generate lint report
- `yarn lint` - Run Biome across the codebase
- `yarn lint:fix` - Run Biome and apply safe fixes
- `yarn lint:report` - Generate Biome lint report
- `yarn type-check` - Run TypeScript type checking
- `yarn format` - Format code with Prettier
- `yarn format` - Format code with Biome
## Testing Commands
-3
View File
@@ -13,8 +13,5 @@
"connect": "3.7.0",
"http": "0.0.1-security",
"http-proxy-middleware": "2.0.9"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*"
}
}
-5
View File
@@ -1,5 +0,0 @@
.next/
coverage/
node_modules/
tests/
templates/
-3
View File
@@ -1,3 +0,0 @@
import { nextJsConfig } from "@calcom/eslint-config/next-js";
export default nextJsConfig;
+2 -3
View File
@@ -10,15 +10,14 @@
"build": "next build",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
"dev": "PORT=3003 next dev",
"lint": "eslint .",
"lint:fix": "eslint . --ext .ts,.js,.tsx,.jsx --fix",
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"start": "PORT=3003 next start",
"docker-start-api": "PORT=80 next start",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@calcom/tsconfig": "workspace:*",
"@calcom/types": "workspace:*",
"node-mocks-http": "1.16.2",
-7
View File
@@ -1,7 +0,0 @@
const rootConfig = require("../../../packages/config/prettier-preset");
module.exports = {
...rootConfig,
importOrder: ["^./instrument", ...rootConfig.importOrder],
importOrderParserPlugins: ["typescript", "decorators-legacy"],
};
+2 -5
View File
@@ -7,7 +7,7 @@
"private": true,
"scripts": {
"build": "yarn dev:build && nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"format": "biome format --write src test",
"start": "nest start",
"dev:build:watch": "concurrently --names \"libraries,lru-fix,constants,enums,utils,types\" \"yarn _dev:build:watch:libraries\" \"yarn _dev:build:watch:libraries:lru-fix\" \"yarn _dev:build:watch:constants\" \"yarn _dev:build:watch:enums\" \"yarn _dev:build:watch:utils\" \"yarn _dev:build:watch:types\"",
"_dev:build:watch:libraries": "yarn workspace @calcom/platform-libraries build:watch",
@@ -86,7 +86,7 @@
"zod": "3.25.76"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@biomejs/biome": "^2.3.8",
"@golevelup/ts-jest": "0.4.0",
"@nestjs/cli": "10.3.2",
"@nestjs/schematics": "10.1.1",
@@ -98,14 +98,11 @@
"@types/luxon": "3.4.2",
"@types/passport-jwt": "3.0.13",
"@types/supertest": "2.0.16",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"concurrently": "9.1.2",
"jest": "29.7.0",
"jest-date-mock": "1.0.10",
"jest-junit": "^16.0.0",
"node-mocks-http": "1.16.2",
"prettier": "2.8.7",
"source-map-support": "0.5.21",
"supertest": "6.3.4",
"ts-jest": "29.1.4",
+7 -3
View File
@@ -2,15 +2,19 @@ import { getEnv } from "@/env";
import { Logger } from "@nestjs/common";
import type { NestExpressApplication } from "@nestjs/platform-express";
import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
import {
import type {
PathItemObject,
PathsObject,
OperationObject,
} from "@nestjs/swagger/dist/interfaces/open-api-spec.interface";
import "dotenv/config";
import * as fs from "fs";
import { Server } from "http";
import type { Server } from "http";
import { spawnSync } from "node:child_process";
import { createRequire } from "node:module";
const nodeRequire = createRequire(__filename);
const biomeBin = nodeRequire.resolve("@biomejs/biome/bin/biome");
const HttpMethods: (keyof PathItemObject)[] = ["get", "post", "put", "delete", "patch", "options", "head"];
@@ -28,7 +32,7 @@ export async function generateSwaggerForApp(app: NestExpressApplication<Server>)
if (fs.existsSync(docsOutputFile) && getEnv("NODE_ENV") === "development") {
fs.unlinkSync(docsOutputFile);
fs.writeFileSync(docsOutputFile, stringifiedContents, { encoding: "utf8" });
spawnSync("npx", ["prettier", docsOutputFile, "--write"], { stdio: "inherit" });
spawnSync("node", [biomeBin, "format", "--write", docsOutputFile], { stdio: "inherit" });
}
if (!process.env.DOCS_URL) {
-1
View File
@@ -1 +0,0 @@
public/embed
-3
View File
@@ -1,3 +0,0 @@
import { nextJsConfig } from "@calcom/eslint-config/next-js";
export default [...nextJsConfig];
+3 -4
View File
@@ -20,9 +20,9 @@
"copy-app-store-static": "node scripts/copy-app-store-static.js",
"build": "next build && yarn sentry:release",
"start": "next start",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint:report": "eslint . --format json --output-file ../../lint-results/web.json",
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"lint:report": "biome lint --reporter json . > ../../lint-results/web.json",
"check-changed-files": "ts-node scripts/ts-check-changed-files.ts",
"translate-locales": "ts-node scripts/check-missing-translations.ts",
"stripe:listen": "stripe listen --forward-to http://localhost:3000/api/stripe/webhook"
@@ -152,7 +152,6 @@
"devDependencies": {
"@babel/core": "7.26.10",
"@calcom/config": "workspace:*",
"@calcom/eslint-config": "workspace:*",
"@calcom/types": "workspace:*",
"@microsoft/microsoft-graph-types-beta": "0.15.0-preview",
"@playwright/test": "1.57.0",
+20 -52
View File
@@ -1,6 +1,7 @@
import type { Page } from "@playwright/test";
import { expect } from "@playwright/test";
import { Linter } from "eslint";
import { spawnSync } from "node:child_process";
import { createRequire } from "node:module";
import { parse } from "node-html-parser";
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
@@ -9,11 +10,8 @@ import { MembershipRole } from "@calcom/prisma/enums";
import { test } from "./lib/fixtures";
const linter = new Linter();
const eslintRules = {
"no-undef": "error",
"no-unused-vars": "off",
} as const;
const nodeRequire = createRequire(__filename);
const biomeBin = nodeRequire.resolve("@biomejs/biome/bin/biome");
test.describe.configure({ mode: "parallel" });
test.afterEach(({ users }) => users.deleteAll());
@@ -431,71 +429,41 @@ async function expectValidHtmlEmbedSnippet(
}
function assertThatCodeIsValidVanillaJsCode(code: string) {
const lintResult = linter.verify(code, [
{
languageOptions: {
ecmaVersion: 2021,
sourceType: "module",
parserOptions: { ecmaFeatures: { jsx: true } },
globals: {
window: "readonly",
document: "readonly",
navigator: "readonly",
Cal: "readonly",
console: "readonly",
},
},
rules: eslintRules,
},
]);
// Use Biome to check if the code is syntactically valid JavaScript
const result = spawnSync("node", [biomeBin, "format", "--stdin-file-path", "snippet.js"], {
input: code,
encoding: "utf-8",
});
if (lintResult.length) {
if (result.status !== 0) {
console.log(
JSON.stringify({
lintResult,
biomeError: result.stderr,
code,
})
);
}
expect(lintResult.length).toBe(0);
expect(result.status).toBe(0);
}
function assertThatCodeIsValidReactCode(code: string) {
const lintResult = linter.verify(code, [
{
languageOptions: {
ecmaVersion: 2021,
sourceType: "module",
parserOptions: {
ecmaFeatures: { jsx: true },
},
globals: {
window: "readonly",
document: "readonly",
navigator: "readonly",
console: "readonly",
},
},
rules: {
...eslintRules,
"@typescript-eslint/no-unused-vars": "off",
"no-undef": "off",
semi: "off",
},
},
]);
// Use Biome to check if the code is syntactically valid JSX
const result = spawnSync("node", [biomeBin, "format", "--stdin-file-path", "snippet.jsx"], {
input: code,
encoding: "utf-8",
});
if (lintResult.length) {
if (result.status !== 0) {
console.log(
JSON.stringify({
lintResult,
biomeError: result.stderr,
code,
})
);
}
expect(lintResult.length).toBe(0);
expect(result.status).toBe(0);
}
async function expectValidReactEmbedSnippet(
+188
View File
@@ -0,0 +1,188 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
"root": true,
"css": {
"parser": {
"tailwindDirectives": true
}
},
"formatter": {
"includes": [
"**/*",
"!packages/ui/components/icon/dynamicIconImports.tsx",
"!apps/api/v1/tests",
"!apps/api/v1/templates"
],
"lineWidth": 110,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf"
},
"files": {
"includes": [
"**/*",
"!**/node_modules",
"!**/.next",
"!**/.turbo",
"!**/dist",
"!**/build",
"!**/public",
"!public",
"!apps/web/public/embed",
"!packages/prisma/zod",
"!packages/prisma/enums",
"!*.lock",
"!*.log",
"!.gitignore",
"!.npmignore",
"!.prettierignore",
"!.eslintignore",
"!.DS_Store",
"!coverage",
"!lint-results",
"!test-results"
]
},
"javascript": {
"formatter": {
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": true,
"quoteStyle": "double",
"jsxQuoteStyle": "double",
"semicolons": "always",
"trailingCommas": "es5"
}
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"style": {
"useNodejsImportProtocol": "warn"
},
"correctness": {
"noUnusedVariables": {
"level": "warn",
"options": {
"ignoreRestSiblings": true
}
}
}
}
},
"overrides": [
{
"includes": ["packages/lib/**/*.{ts,tsx,js,jsx,mts,mjs,cjs,cts}"],
"linter": {
"rules": {
"style": {
"noRestrictedImports": {
"level": "error",
"options": {
"patterns": [
{
"group": ["../app-store/**"],
"message": "lib package should not import from app-store to avoid circular dependencies."
},
{
"group": ["../features/**"],
"message": "lib package should not import from features to avoid circular dependencies."
},
{
"group": ["../trpc/**"],
"message": "lib package should not import from trpc to avoid circular dependencies."
},
{
"group": ["@trpc/server"],
"message": "lib package should not import from @trpc/server to avoid circular dependencies."
}
]
}
}
}
}
}
},
{
"includes": ["packages/app-store/**/*.{ts,tsx,js,jsx,mts,mjs,cjs,cts}"],
"linter": {
"rules": {
"style": {
"noRestrictedImports": {
"level": "error",
"options": {
"patterns": [
{
"group": ["../features/**"],
"message": "app-store package should not import from features to avoid circular dependencies."
},
{
"group": ["../trpc/**"],
"message": "app-store package should not import from trpc to avoid circular dependencies."
}
]
}
}
}
}
}
},
{
"includes": ["packages/features/**/*.{ts,tsx,js,jsx,mts,mjs,cjs,cts}"],
"linter": {
"rules": {
"style": {
"noRestrictedImports": {
"level": "error",
"options": {
"patterns": [
{
"group": ["../trpc/**"],
"message": "features package should not import from trpc to avoid circular dependencies."
}
]
}
}
}
}
}
},
{
"includes": ["packages/trpc/**/*.{ts,tsx,js,jsx,mts,mjs,cjs,cts}"],
"linter": {
"rules": {
"style": {
"noRestrictedImports": {
"level": "error",
"options": {
"patterns": [
{
"group": ["../apps/web/**"],
"message": "trpc package should not import from apps/web to avoid circular dependencies."
}
]
}
}
}
}
}
},
{
"includes": ["companion/**/*.{ts,tsx,js,jsx}"],
"javascript": {
"formatter": {
"lineWidth": 100
}
}
},
{
"includes": ["apps/website/lib/utils/wordlist/wordlist.ts"],
"javascript": {
"formatter": {
"quoteProperties": "preserve"
}
}
}
]
}
+78 -175
View File
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "cal-companion",
@@ -47,6 +48,8 @@
"@types/react-dom": "19.2.3",
"babel-plugin-react-compiler": "19.0.0-beta-af1b7da-20250417",
"babel-preset-expo": "54.0.7",
"eslint": "9.28.0",
"eslint-plugin-react-compiler": "19.0.0-beta-af1b7da-20250417",
"husky": "9.0.11",
"lint-staged": "15.2.0",
"tailwindcss": "3.4.17",
@@ -65,7 +68,7 @@
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
"@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
"@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=="],
"@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="],
@@ -119,6 +122,8 @@
"@babel/plugin-proposal-export-default-from": ["@babel/plugin-proposal-export-default-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw=="],
"@babel/plugin-proposal-private-methods": ["@babel/plugin-proposal-private-methods@7.18.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA=="],
"@babel/plugin-syntax-async-generators": ["@babel/plugin-syntax-async-generators@7.8.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw=="],
"@babel/plugin-syntax-bigint": ["@babel/plugin-syntax-bigint@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg=="],
@@ -335,19 +340,19 @@
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
"@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="],
"@eslint/config-array": ["@eslint/config-array@0.20.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw=="],
"@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
"@eslint/config-helpers": ["@eslint/config-helpers@0.2.3", "", {}, "sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg=="],
"@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
"@eslint/core": ["@eslint/core@0.14.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg=="],
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.3", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ=="],
"@eslint/js": ["@eslint/js@9.39.2", "", {}, "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA=="],
"@eslint/js": ["@eslint/js@9.28.0", "", {}, "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg=="],
"@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
"@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.15", "", {}, "sha512-EA+HoleZdmUtefeY8a/M8LFK7VapTUyXRIIzP9IkI8Z7DM9r4mVA1omWgoEZp+Tft1jo8dbdnZu38lGOjLohsg=="],
@@ -715,7 +720,7 @@
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
@@ -793,7 +798,7 @@
"bplist-parser": ["bplist-parser@0.3.2", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ=="],
"brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
@@ -825,7 +830,7 @@
"caniuse-lite": ["caniuse-lite@1.0.30001760", "", {}, "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw=="],
"chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="],
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
@@ -999,7 +1004,9 @@
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
"eslint": ["eslint@9.39.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw=="],
"eslint": ["eslint@9.28.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.28.0", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ=="],
"eslint-plugin-react-compiler": ["eslint-plugin-react-compiler@19.0.0-beta-af1b7da-20250417", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "@babel/plugin-proposal-private-methods": "^7.18.6", "hermes-parser": "^0.25.1", "zod": "^3.22.4", "zod-validation-error": "^3.0.3" }, "peerDependencies": { "eslint": ">=7" } }, "sha512-m3eVzHqtXFtu6rViWx/kBhv9Jcpj+Q4pkfRWyF47TIBa+Jo8DAB90OoeDh0JR896rtG1OXogLKKd+b6lzFup0A=="],
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
@@ -1201,9 +1208,9 @@
"hermes-compiler": ["hermes-compiler@0.14.0", "", {}, "sha512-clxa193o+GYYwykWVFfpHduCATz8fR5jvU7ngXpfKHj+E9hr9vjLNtdLSEe8MUbObvVexV3wcyxQ00xTPIrB1Q=="],
"hermes-estree": ["hermes-estree@0.29.1", "", {}, "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ=="],
"hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
"hermes-parser": ["hermes-parser@0.29.1", "", { "dependencies": { "hermes-estree": "0.29.1" } }, "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA=="],
"hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="],
"hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="],
@@ -1227,7 +1234,7 @@
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": { "image-size": "bin/image-size.js" } }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="],
@@ -1331,7 +1338,7 @@
"jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="],
"js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
@@ -1487,7 +1494,7 @@
"mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
"minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
@@ -1881,7 +1888,7 @@
"strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="],
"strip-json-comments": ["strip-json-comments@5.0.2", "", {}, "sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g=="],
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
"strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="],
@@ -1937,7 +1944,7 @@
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
"ts-api-utils": ["ts-api-utils@2.2.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-L6f5oQRAoLU1RwXz0Ab9mxsE7LtxeVB6AIR1lpkZMsOyg/JXeaxBaXa/FVCBZyNr9S9I4wkHrlZTklX+im+WMw=="],
"ts-api-utils": ["ts-api-utils@2.3.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-6eg3Y9SF7SsAvGzRHQvvc1skDAhwI4YQ32ui1scxD1Ccr0G5qIIbUBT3pFTKX8kmWIQClHobtUdNuaBgwdfdWg=="],
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
@@ -2087,12 +2094,12 @@
"zip-dir": ["zip-dir@2.0.0", "", { "dependencies": { "async": "^3.2.0", "jszip": "^3.2.2" } }, "sha512-uhlsJZWz26FLYXOD6WVuq+fIcZ3aBPGo/cFdiLlv3KNwpa52IF3ISV8fLhQLiqVu5No3VhlqlgthN6gehil1Dg=="],
"zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="],
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"zod-validation-error": ["zod-validation-error@3.5.4", "", { "peerDependencies": { "zod": "^3.24.4" } }, "sha512-+hEiRIiPobgyuFlEojnqjJnhFvg4r/i3cqgcm67eehZf/WBaK3g6cD02YU9mtdVxZjv8CzCA9n/Rhrs3yAAvAw=="],
"@aklinker1/rollup-plugin-visualizer/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
"@babel/core/@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=="],
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
@@ -2103,36 +2110,20 @@
"@babel/highlight/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
"@babel/highlight/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@babel/template/@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=="],
"@babel/traverse/@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=="],
"@babel/traverse--for-generate-function-map/@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=="],
"@devicefarmer/adbkit/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],
"@devicefarmer/adbkit/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
"@eslint/config-array/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"@eslint/eslintrc/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"@eslint/eslintrc/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"@eslint/eslintrc/strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="],
"@expo/cli/@expo/env": ["@expo/env@2.0.8", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0" } }, "sha512-5VQD6GT8HIMRaSaB5JFtOXuvfDVU80YtZIuUT/GDhUF782usIXY13Tn3IdDz1Tm/lqA9qnRZQ1BF4t7LlvdJPA=="],
"@expo/cli/@expo/schema-utils": ["@expo/schema-utils@0.1.8", "", {}, "sha512-9I6ZqvnAvKKDiO+ZF8BpQQFYWXOJvTAL5L/227RUbWG1OVZDInFifzCBiqAZ3b67NRfeAgpgvbA7rejsqhY62A=="],
"@expo/cli/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/cli/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
"@expo/cli/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
@@ -2149,69 +2140,57 @@
"@expo/cli/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"@expo/config/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
"@expo/config/glob": ["glob@13.0.0", "", { "dependencies": { "minimatch": "^10.1.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA=="],
"@expo/config/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"@expo/config-plugins/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/config-plugins/glob": ["glob@13.0.0", "", { "dependencies": { "minimatch": "^10.1.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA=="],
"@expo/config-plugins/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"@expo/devcert/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
"@expo/devtools/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/env/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/env/dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"@expo/env/dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="],
"@expo/fingerprint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/fingerprint/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
"@expo/fingerprint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"@expo/fingerprint/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@expo/fingerprint/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"@expo/image-utils/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/image-utils/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"@expo/json-file/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
"@expo/metro/metro-runtime": ["metro-runtime@0.83.1", "", { "dependencies": { "@babel/runtime": "^7.25.0", "flow-enums-runtime": "^0.0.6" } }, "sha512-3Ag8ZS4IwafL/JUKlaeM6/CbkooY+WcVeqdNlBG0m4S0Qz0om3rdFdy1y6fYBpl6AwXJwWeMuXrvZdMuByTcRA=="],
"@expo/metro/metro-source-map": ["metro-source-map@0.83.1", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-symbolicate": "0.83.1", "nullthrows": "^1.1.1", "ob1": "0.83.1", "source-map": "^0.5.6", "vlq": "^1.0.0" } }, "sha512-De7Vbeo96fFZ2cqmI0fWwVJbtHIwPZv++LYlWSwzTiCzxBDJORncN0LcT48Vi2UlQLzXJg+/CuTAcy7NBVh69A=="],
"@expo/metro-config/@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=="],
"@expo/metro-config/@expo/env": ["@expo/env@2.0.8", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0" } }, "sha512-5VQD6GT8HIMRaSaB5JFtOXuvfDVU80YtZIuUT/GDhUF782usIXY13Tn3IdDz1Tm/lqA9qnRZQ1BF4t7LlvdJPA=="],
"@expo/metro-config/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/metro-config/dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"@expo/metro-config/dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="],
"@expo/metro-config/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
"@expo/metro-config/hermes-parser": ["hermes-parser@0.29.1", "", { "dependencies": { "hermes-estree": "0.29.1" } }, "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA=="],
"@expo/metro-config/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@expo/metro-config/postcss": ["postcss@8.4.49", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA=="],
"@expo/package-manager/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/package-manager/ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-spinners": "^2.0.0", "log-symbols": "^2.2.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="],
"@expo/prebuild-config/@react-native/normalize-colors": ["@react-native/normalize-colors@0.81.5", "", {}, "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g=="],
"@expo/prebuild-config/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"@expo/xcpretty/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@expo/xcpretty/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
@@ -2223,12 +2202,8 @@
"@istanbuljs/load-nyc-config/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
"@jest/transform/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@jest/transform/micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"@jest/types/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="],
"@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
@@ -2261,16 +2236,18 @@
"@react-navigation/core/react-is": ["react-is@19.2.3", "", {}, "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA=="],
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"ansi-align/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=="],
"babel-jest/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"babel-plugin-syntax-hermes-parser/hermes-parser": ["hermes-parser@0.29.1", "", { "dependencies": { "hermes-estree": "0.29.1" } }, "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA=="],
"babel-preset-expo/babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="],
"better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
@@ -2323,12 +2300,6 @@
"dotenv-expand/dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"eslint/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"expo/expo-constants": ["expo-constants@18.0.12", "", { "dependencies": { "@expo/config": "~12.0.12", "@expo/env": "~2.0.8" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-WzcKYMVNRRu4NcSzfIVRD5aUQFnSpTZgXFrlWmm19xJoDa4S3/PQNi6PNTBRc49xz9h8FT7HMxRKaC8lr0gflA=="],
"expo-asset/expo-constants": ["expo-constants@18.0.12", "", { "dependencies": { "@expo/config": "~12.0.12", "@expo/env": "~2.0.8" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-WzcKYMVNRRu4NcSzfIVRD5aUQFnSpTZgXFrlWmm19xJoDa4S3/PQNi6PNTBRc49xz9h8FT7HMxRKaC8lr0gflA=="],
@@ -2339,8 +2310,6 @@
"expo-manifests/@expo/config": ["@expo/config@12.0.13-canary-20251216-3f01dbf", "", { "dependencies": { "@babel/code-frame": "~7.10.4", "@expo/config-plugins": "54.0.5-canary-20251216-3f01dbf", "@expo/config-types": "55.0.0-canary-20251216-3f01dbf", "@expo/json-file": "10.0.9-canary-20251216-3f01dbf", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^13.0.0", "require-from-string": "^2.0.2", "resolve-from": "^5.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4", "sucrase": "~3.35.1" } }, "sha512-c//gL86gImxYqbSMRDyKUPvCWBWGB63JOV0JUtj5LhuKOhlgbo07X2tQPhqAAbzm520EFuAmrUP/HPNe9AS/IQ=="],
"expo-modules-autolinking/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
"expo-modules-autolinking/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
@@ -2371,8 +2340,6 @@
"fx-runner/which": ["which@1.2.4", "", { "dependencies": { "is-absolute": "^0.1.7", "isexe": "^1.1.1" }, "bin": { "which": "./bin/which" } }, "sha512-zDRAqDSBudazdfM9zpiI30Fu9ve47htYXcGi3ln0wfKu2a7SmrT6F3VDoYONu//48V8Vz4TdCRNPjtvyRO3yBA=="],
"glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"global-directory/ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="],
"global-dirs/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
@@ -2389,22 +2356,16 @@
"jest-haste-map/micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"jest-message-util/@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=="],
"jest-message-util/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"jest-message-util/micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"jest-util/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"jest-util/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
"jest-validate/camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="],
"jest-validate/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
"lint-staged/chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="],
"lint-staged/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"log-symbols/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
@@ -2413,16 +2374,12 @@
"log-update/slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="],
"loose-envify/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"metro/@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=="],
"metro/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="],
"metro/hermes-parser": ["hermes-parser@0.29.1", "", { "dependencies": { "hermes-estree": "0.29.1" } }, "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA=="],
"metro/metro-runtime": ["metro-runtime@0.83.1", "", { "dependencies": { "@babel/runtime": "^7.25.0", "flow-enums-runtime": "^0.0.6" } }, "sha512-3Ag8ZS4IwafL/JUKlaeM6/CbkooY+WcVeqdNlBG0m4S0Qz0om3rdFdy1y6fYBpl6AwXJwWeMuXrvZdMuByTcRA=="],
"metro/metro-source-map": ["metro-source-map@0.83.1", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-symbolicate": "0.83.1", "nullthrows": "^1.1.1", "ob1": "0.83.1", "source-map": "^0.5.6", "vlq": "^1.0.0" } }, "sha512-De7Vbeo96fFZ2cqmI0fWwVJbtHIwPZv++LYlWSwzTiCzxBDJORncN0LcT48Vi2UlQLzXJg+/CuTAcy7NBVh69A=="],
@@ -2431,6 +2388,8 @@
"metro/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="],
"metro-babel-transformer/hermes-parser": ["hermes-parser@0.29.1", "", { "dependencies": { "hermes-estree": "0.29.1" } }, "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA=="],
"metro-config/metro-runtime": ["metro-runtime@0.83.1", "", { "dependencies": { "@babel/runtime": "^7.25.0", "flow-enums-runtime": "^0.0.6" } }, "sha512-3Ag8ZS4IwafL/JUKlaeM6/CbkooY+WcVeqdNlBG0m4S0Qz0om3rdFdy1y6fYBpl6AwXJwWeMuXrvZdMuByTcRA=="],
"metro-file-map/micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
@@ -2443,8 +2402,6 @@
"mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
"multimatch/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"node-notifier/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"node-notifier/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
@@ -2457,8 +2414,6 @@
"package-json/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"parse-json/@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=="],
"parse-json/lines-and-columns": ["lines-and-columns@2.0.4", "", {}, "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A=="],
"parse-json/type-fest": ["type-fest@3.13.1", "", {}, "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g=="],
@@ -2469,8 +2424,12 @@
"postcss-load-config/yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="],
"pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
"publish-browser-extension/listr2": ["listr2@8.3.3", "", { "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ=="],
"publish-browser-extension/zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="],
"rc/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
@@ -2521,6 +2480,8 @@
"strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
"strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
"sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
"tailwindcss/lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
@@ -2531,8 +2492,6 @@
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
"test-exclude/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
"unimport/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
@@ -2553,12 +2512,12 @@
"web-ext-run/@babel/runtime": ["@babel/runtime@7.28.2", "", {}, "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA=="],
"web-ext-run/strip-json-comments": ["strip-json-comments@5.0.2", "", {}, "sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g=="],
"whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
"wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"wrap-ansi-cjs/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=="],
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
@@ -2567,6 +2526,8 @@
"wxt/chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
"wxt/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"xcode/uuid": ["uuid@7.0.3", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="],
"xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
@@ -2577,29 +2538,17 @@
"@aklinker1/rollup-plugin-visualizer/open/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"@babel/core/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@babel/highlight/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
"@babel/highlight/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
"@babel/highlight/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
"@babel/template/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@babel/traverse--for-generate-function-map/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@babel/traverse/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"@eslint/eslintrc/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"@expo/cli/@expo/env/dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"@expo/cli/@expo/env/dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="],
"@expo/cli/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/cli/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@expo/cli/ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
@@ -2609,29 +2558,23 @@
"@expo/cli/ora/strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "^4.1.0" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="],
"@expo/cli/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/cli/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=="],
"@expo/cli/wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"@expo/config-plugins/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/config-plugins/glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"@expo/config-plugins/glob/path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
"@expo/config/glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"@expo/config/glob/path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
"@expo/devtools/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/fingerprint/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@expo/env/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/metro-config/hermes-parser/hermes-estree": ["hermes-estree@0.29.1", "", {}, "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ=="],
"@expo/fingerprint/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/image-utils/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/metro-config/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@expo/metro-config/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/metro-config/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@expo/metro/metro-source-map/metro-symbolicate": ["metro-symbolicate@0.83.1", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-source-map": "0.83.1", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "bin": { "metro-symbolicate": "src/index.js" } }, "sha512-wPxYkONlq/Sv8Ji7vHEx5OzFouXAMQJjpcPW41ySKMLP/Ir18SsiJK2h4YkdKpYrTS1+0xf8oqF6nxCsT3uWtg=="],
@@ -2639,8 +2582,6 @@
"@expo/metro/metro-source-map/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="],
"@expo/package-manager/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/package-manager/ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
"@expo/package-manager/ora/cli-cursor": ["cli-cursor@2.1.0", "", { "dependencies": { "restore-cursor": "^2.0.0" } }, "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw=="],
@@ -2649,8 +2590,6 @@
"@expo/package-manager/ora/strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "^4.1.0" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="],
"@expo/xcpretty/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
"@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
@@ -2659,9 +2598,7 @@
"@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"@jest/transform/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@jest/types/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@react-native/babel-plugin-codegen/@react-native/codegen/hermes-parser": ["hermes-parser@0.29.1", "", { "dependencies": { "hermes-estree": "0.29.1" } }, "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA=="],
"@react-native/codegen/hermes-parser/hermes-estree": ["hermes-estree@0.32.0", "", {}, "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ=="],
@@ -2671,10 +2608,6 @@
"@react-native/community-cli-plugin/@react-native/dev-middleware/open": ["open@7.4.2", "", { "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" } }, "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q=="],
"@react-native/community-cli-plugin/metro/@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=="],
"@react-native/community-cli-plugin/metro/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@react-native/community-cli-plugin/metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="],
"@react-native/community-cli-plugin/metro/hermes-parser": ["hermes-parser@0.32.0", "", { "dependencies": { "hermes-estree": "0.32.0" } }, "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw=="],
@@ -2707,11 +2640,13 @@
"@react-native/dev-middleware/open/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"babel-jest/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"babel-plugin-syntax-hermes-parser/hermes-parser/hermes-estree": ["hermes-estree@0.29.1", "", {}, "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ=="],
"better-opn/open/define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="],
@@ -2723,8 +2658,6 @@
"cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"connect/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
@@ -2733,12 +2666,10 @@
"cosmiconfig/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"eslint/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"eslint/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"expo-asset/expo-constants/@expo/env": ["@expo/env@2.0.8", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0" } }, "sha512-5VQD6GT8HIMRaSaB5JFtOXuvfDVU80YtZIuUT/GDhUF782usIXY13Tn3IdDz1Tm/lqA9qnRZQ1BF4t7LlvdJPA=="],
"expo-constants/@expo/config/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
"expo-constants/@expo/config/@expo/config-plugins": ["@expo/config-plugins@54.0.5-canary-20251216-3f01dbf", "", { "dependencies": { "@expo/config-types": "55.0.0-canary-20251216-3f01dbf", "@expo/json-file": "10.0.9-canary-20251216-3f01dbf", "@expo/plist": "0.4.9-canary-20251216-3f01dbf", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^13.0.0", "resolve-from": "^5.0.0", "semver": "^7.5.4", "slash": "^3.0.0", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-lsE9UoBVb2couRNFRin1iy7phwjPSPEkqx0ftLE7LPeDjW80Js0CfSvGbvQ+L0qEYwEUl8GNYwzpLpLqesNdjw=="],
"expo-constants/@expo/config/@expo/config-types": ["@expo/config-types@55.0.0-canary-20251216-3f01dbf", "", {}, "sha512-BcP8G9UMKSkXkKakv4Lhb9j77nH6ERs/QwRQRMAqIw+ql09SDlSaiNSogOdLNvqTGDuZtkYVL5eKQ7a8+dkDkg=="],
@@ -2751,6 +2682,8 @@
"expo-dev-launcher/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"expo-manifests/@expo/config/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
"expo-manifests/@expo/config/@expo/config-plugins": ["@expo/config-plugins@54.0.5-canary-20251216-3f01dbf", "", { "dependencies": { "@expo/config-types": "55.0.0-canary-20251216-3f01dbf", "@expo/json-file": "10.0.9-canary-20251216-3f01dbf", "@expo/plist": "0.4.9-canary-20251216-3f01dbf", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^13.0.0", "resolve-from": "^5.0.0", "semver": "^7.5.4", "slash": "^3.0.0", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-lsE9UoBVb2couRNFRin1iy7phwjPSPEkqx0ftLE7LPeDjW80Js0CfSvGbvQ+L0qEYwEUl8GNYwzpLpLqesNdjw=="],
"expo-manifests/@expo/config/@expo/config-types": ["@expo/config-types@55.0.0-canary-20251216-3f01dbf", "", {}, "sha512-BcP8G9UMKSkXkKakv4Lhb9j77nH6ERs/QwRQRMAqIw+ql09SDlSaiNSogOdLNvqTGDuZtkYVL5eKQ7a8+dkDkg=="],
@@ -2761,8 +2694,6 @@
"expo-manifests/@expo/config/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"expo-modules-autolinking/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"expo-modules-autolinking/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"expo/expo-constants/@expo/env": ["@expo/env@2.0.8", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "getenv": "^2.0.0" } }, "sha512-5VQD6GT8HIMRaSaB5JFtOXuvfDVU80YtZIuUT/GDhUF782usIXY13Tn3IdDz1Tm/lqA9qnRZQ1BF4t7LlvdJPA=="],
@@ -2773,40 +2704,26 @@
"fx-runner/which/isexe": ["isexe@1.1.2", "", {}, "sha512-d2eJzK691yZwPHcv1LbeAOa91yMJ9QmfTgSO1oXB65ezVhXQsxBac2vEB4bMVms9cGzaA99n6V2viHMq82VLDw=="],
"glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"jest-message-util/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"jest-message-util/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"jest-util/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"jest-validate/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"lint-staged/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
"log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="],
"metro-babel-transformer/hermes-parser/hermes-estree": ["hermes-estree@0.29.1", "", {}, "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ=="],
"metro-transform-worker/metro-source-map/metro-symbolicate": ["metro-symbolicate@0.83.1", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-source-map": "0.83.1", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "bin": { "metro-symbolicate": "src/index.js" } }, "sha512-wPxYkONlq/Sv8Ji7vHEx5OzFouXAMQJjpcPW41ySKMLP/Ir18SsiJK2h4YkdKpYrTS1+0xf8oqF6nxCsT3uWtg=="],
"metro-transform-worker/metro-source-map/ob1": ["ob1@0.83.1", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-ngwqewtdUzFyycomdbdIhFLjePPSOt1awKMUXQ0L7iLHgWEPF3DsCerblzjzfAUHaXuvE9ccJymWQ/4PNNqvnQ=="],
"metro-transform-worker/metro-source-map/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="],
"metro/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"metro/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"metro/hermes-parser/hermes-estree": ["hermes-estree@0.29.1", "", {}, "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ=="],
"metro/metro-source-map/ob1": ["ob1@0.83.1", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-ngwqewtdUzFyycomdbdIhFLjePPSOt1awKMUXQ0L7iLHgWEPF3DsCerblzjzfAUHaXuvE9ccJymWQ/4PNNqvnQ=="],
"mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
"multimatch/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"parse-json/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"react-native-css-interop/lightningcss/detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
"react-native-css-interop/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.27.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ=="],
@@ -2839,8 +2756,6 @@
"terminal-link/ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="],
"test-exclude/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"wxt/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
@@ -2881,16 +2796,14 @@
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
"@react-native/babel-plugin-codegen/@react-native/codegen/hermes-parser/hermes-estree": ["hermes-estree@0.29.1", "", {}, "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ=="],
"@react-native/community-cli-plugin/@react-native/dev-middleware/chrome-launcher/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"@react-native/community-cli-plugin/@react-native/dev-middleware/chrome-launcher/lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="],
"@react-native/community-cli-plugin/@react-native/dev-middleware/open/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"@react-native/community-cli-plugin/metro/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@react-native/community-cli-plugin/metro/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@react-native/community-cli-plugin/metro/hermes-parser/hermes-estree": ["hermes-estree@0.32.0", "", {}, "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ=="],
"@react-native/community-cli-plugin/metro/metro-file-map/micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
@@ -2901,25 +2814,23 @@
"chromium-edge-launcher/lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"expo-asset/expo-constants/@expo/env/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"expo-asset/expo-constants/@expo/env/dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"expo-asset/expo-constants/@expo/env/dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="],
"expo-constants/@expo/config/@expo/config-plugins/@expo/plist": ["@expo/plist@0.4.9-canary-20251216-3f01dbf", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-3/kYP08yrjXhpClr7tau8oSeimDZv0SNl6WxurUWhVgzH3pyA5gU0h1WwH5A0LUiyPUHcP9Osf20dZzfpB82Jg=="],
"expo-constants/@expo/config/@expo/config-plugins/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"expo-constants/@expo/config/glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"expo-constants/@expo/config/glob/path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
"expo-manifests/@expo/config/@expo/config-plugins/@expo/plist": ["@expo/plist@0.4.9-canary-20251216-3f01dbf", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-3/kYP08yrjXhpClr7tau8oSeimDZv0SNl6WxurUWhVgzH3pyA5gU0h1WwH5A0LUiyPUHcP9Osf20dZzfpB82Jg=="],
"expo-manifests/@expo/config/@expo/config-plugins/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"expo-manifests/@expo/config/glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"expo-manifests/@expo/config/glob/path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
"expo/expo-constants/@expo/env/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"expo-modules-autolinking/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"expo/expo-constants/@expo/env/dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
@@ -2953,18 +2864,10 @@
"@react-native/dev-middleware/chrome-launcher/lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"expo-asset/expo-constants/@expo/env/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"expo-constants/@expo/config/@expo/config-plugins/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"expo-constants/@expo/config/glob/path-scurry/lru-cache": ["lru-cache@11.2.4", "", {}, "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg=="],
"expo-manifests/@expo/config/@expo/config-plugins/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"expo-manifests/@expo/config/glob/path-scurry/lru-cache": ["lru-cache@11.2.4", "", {}, "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg=="],
"expo/expo-constants/@expo/env/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@expo/cli/ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
"@expo/cli/ora/cli-cursor/restore-cursor/onetime/mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="],
+16 -14
View File
@@ -87,20 +87,22 @@
"react-native-worklets": "0.7.1"
},
"private": true,
"devDependencies": {
"@biomejs/biome": "2.3.10",
"@types/chrome": "0.1.31",
"@types/react": "19.2.3",
"@types/react-dom": "19.2.3",
"babel-plugin-react-compiler": "19.0.0-beta-af1b7da-20250417",
"babel-preset-expo": "54.0.7",
"husky": "9.0.11",
"lint-staged": "15.2.0",
"tailwindcss": "3.4.17",
"typescript": "5.9.3",
"typescript-eslint": "8.50.1",
"wxt": "0.20.11"
},
"devDependencies": {
"@biomejs/biome": "2.3.10",
"@types/chrome": "0.1.31",
"@types/react": "19.2.3",
"@types/react-dom": "19.2.3",
"babel-plugin-react-compiler": "19.0.0-beta-af1b7da-20250417",
"babel-preset-expo": "54.0.7",
"eslint": "9.28.0",
"eslint-plugin-react-compiler": "19.0.0-beta-af1b7da-20250417",
"husky": "9.0.11",
"lint-staged": "15.2.0",
"tailwindcss": "3.4.17",
"typescript": "5.9.3",
"typescript-eslint": "8.50.1",
"wxt": "0.20.11"
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx,json,css,md}": [
"biome format --write"
@@ -9,8 +9,8 @@ We use a number of style guides written by other amazing companies, simply becau
We don't expect you to study every single rule of each style guide, but these are great reference points as to how your code should be styled. We may reject a pull request if your code style significantly differs from these style guides however.
### ESLint & Prettier
Cal.com uses the ESLint and Prettier formatting tools, and the repository comes with defined rules for each tool. We recommend setting up both tools and using these to help automatically style your code to our guidelines.
### Biome
Cal.com now uses Biome for both linting and formatting. The repository already contains the configuration, so we recommend hooking Biome into your editor to keep code aligned with the project guidelines automatically.
### JavaScript/TypeScript
We use the
-3
View File
@@ -1,3 +0,0 @@
import { config } from "@calcom/eslint-config/base";
export default config;
@@ -1,3 +0,0 @@
import { nextJsConfig } from "@calcom/eslint-config/next-js";
export default nextJsConfig;
+1 -2
View File
@@ -6,11 +6,10 @@
"dev": "PORT=5100 next dev",
"build": "next build",
"start": "next start",
"lint": "eslint ."
"lint": "biome lint ."
},
"dependencies": {
"@calcom/atoms": "workspace:*",
"@calcom/eslint-config": "workspace:*",
"@prisma/client": "6.16.1",
"next": "14.2.35",
"prisma": "6.16.1",
@@ -11,9 +11,9 @@ import {
import { generateGoogleCalendarAccessToken, generateZoomAccessToken } from "../../lib/integrations";
export default async function handler(req: NextApiRequest, res) {
const isInvalid = req.query["invalid"] === "1";
const userId = parseInt(req.query["userId"] as string);
const appSlug = req.query["appSlug"];
const isInvalid = req.query.invalid === "1";
const userId = parseInt(req.query.userId as string, 10);
const appSlug = req.query.appSlug;
try {
let accessToken;
+7 -5
View File
@@ -1,8 +1,10 @@
const skipWarnings = ["1", "true", "yes", "on"].includes((process.env.SKIP_WARNINGS ?? "").toLowerCase());
export default {
"(apps|packages)/**/*.{js,ts,jsx,tsx}": (files) =>
process.env.SKIP_WARNINGS === "1"
? `eslint --fix --flag v10_config_lookup_from_file ${files.join(" ")}`
: `eslint --fix --flag v10_config_lookup_from_file --max-warnings=0 ${files.join(" ")}`,
"*.json": ["prettier --write"],
"(apps|packages|companion)/**/*.{js,ts,jsx,tsx}": (files) =>
skipWarnings
? `biome lint --write ${files.join(" ")}`
: `biome lint --write --error-on-warnings ${files.join(" ")}`,
"*.json": (files) => `biome format --write ${files.join(" ")}`,
"packages/prisma/schema.prisma": ["prisma format"],
};
+2 -4
View File
@@ -54,7 +54,7 @@
"embed-tests": "turbo run embed-tests",
"env-check:app-store": "dotenv-checker --schema .env.appStore.example --env .env.appStore",
"env-check:common": "dotenv-checker --schema .env.example --env .env",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"format": "biome format --write .",
"heroku-postbuild": "turbo run @calcom/web#build",
"lint:fix": "turbo lint:fix",
"lint:report": "turbo lint:report",
@@ -85,7 +85,7 @@
"lint-staged": "lint-staged"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@biomejs/biome": "^2.3.8",
"@changesets/changelog-github": "0.5.1",
"@changesets/cli": "2.29.4",
"@faker-js/faker": "9.2.0",
@@ -99,7 +99,6 @@
"c8": "7.13.0",
"checkly": "latest",
"dotenv-checker": "1.1.5",
"eslint": "9.36.0",
"husky": "9.1.7",
"i18n-unused": "0.13.0",
"jest-diff": "29.7.0",
@@ -109,7 +108,6 @@
"next-router-mock": "0.9.12",
"node-gyp": "10.2.0",
"node-ical": "0.16.1",
"prettier": "2.8.7",
"prismock": "1.35.3",
"resize-observer-polyfill": "1.5.1",
"tsc-absolute": "1.0.0",
+1 -2
View File
@@ -26,10 +26,9 @@
"react": "18.2.0"
},
"devDependencies": {
"@biomejs/biome": "^2.3.8",
"@types/react": "18.0.26",
"chokidar": "3.6.0",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "4.6.0",
"ts-node": "10.9.2",
"typescript": "5.9.2"
}
+106 -35
View File
@@ -2,12 +2,8 @@ import chokidar from "chokidar";
import fs from "fs";
// eslint-disable-next-line no-restricted-imports
import { debounce } from "lodash";
import { spawnSync } from "child_process";
import path from "path";
import prettier from "prettier";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
import prettierConfig from "@calcom/config/prettier-preset";
import type { AppMeta } from "@calcom/types/App";
import { AppMetaSchema } from "@calcom/types/AppMetaSchema";
@@ -16,16 +12,30 @@ import { getAppName } from "./utils/getAppName";
const isInWatchMode = process.argv[2] === "--watch";
const formatOutput = (source: string) =>
prettier.format(source, {
parser: "babel",
...prettierConfig,
});
const repoRoot = path.resolve(__dirname, "../../..");
const getVariableName = (appName: string) => appName.replace(/[-.\/]/g, "_");
const formatFileWithBiome = (filePath: string) => {
const { status } = spawnSync(
"yarn",
["biome", "format", "--write", "--no-errors-on-unmatched", filePath],
{
stdio: "inherit",
cwd: repoRoot,
}
);
if (status !== 0) {
throw new Error(`Biome formatting failed for ${filePath}`);
}
};
const formatOutput = (source: string) => source;
const getVariableName = (appName: string) => appName.replace(/[-./]/g, "_");
// INFO: Handle stripe separately as it's an old app with different dirName than slug/appId
const getAppId = (app: { name: string }) => (app.name === "stripepayment" ? "stripe" : app.name);
const getAppId = (app: { name: string }) =>
app.name === "stripepayment" ? "stripe" : app.name;
type App = Partial<AppMeta> & {
name: string;
@@ -41,9 +51,9 @@ function generateFiles() {
const crmOutput = [];
const appDirs: { name: string; path: string }[] = [];
fs.readdirSync(`${APP_STORE_PATH}`).forEach(function (dir) {
fs.readdirSync(`${APP_STORE_PATH}`).forEach((dir) => {
if (dir === "ee" || dir === "templates") {
fs.readdirSync(path.join(APP_STORE_PATH, dir)).forEach(function (subDir) {
fs.readdirSync(path.join(APP_STORE_PATH, dir)).forEach((subDir) => {
if (fs.statSync(path.join(APP_STORE_PATH, dir, subDir)).isDirectory()) {
if (getAppName(subDir)) {
appDirs.push({
@@ -66,11 +76,22 @@ function generateFiles() {
}
});
function forEachAppDir(callback: (arg: App) => void, filter: (arg: App) => boolean = () => true) {
function forEachAppDir(
callback: (arg: App) => void,
filter: (arg: App) => boolean = () => true
) {
for (let i = 0; i < appDirs.length; i++) {
const configPath = path.join(APP_STORE_PATH, appDirs[i].path, "config.json");
const metadataPath = path.join(APP_STORE_PATH, appDirs[i].path, "_metadata.ts");
let app;
const configPath = path.join(
APP_STORE_PATH,
appDirs[i].path,
"config.json"
);
const metadataPath = path.join(
APP_STORE_PATH,
appDirs[i].path,
"_metadata.ts"
);
let app: AppMetaSchema;
if (fs.existsSync(configPath)) {
try {
@@ -78,8 +99,16 @@ function generateFiles() {
const parsedConfig = JSON.parse(rawConfig);
app = AppMetaSchema.parse(parsedConfig);
} catch (error) {
const prefix = `Config error in ${path.join(APP_STORE_PATH, appDirs[i].path, "config.json")}`;
throw new Error(`${prefix}: ${error instanceof Error ? error.message : String(error)}`);
const prefix = `Config error in ${path.join(
APP_STORE_PATH,
appDirs[i].path,
"config.json"
)}`;
throw new Error(
`${prefix}: ${
error instanceof Error ? error.message : String(error)
}`
);
}
} else if (fs.existsSync(metadataPath)) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -148,12 +177,18 @@ function generateFiles() {
const getLocalImportName = (
app: { name: string },
chosenConfig: ReturnType<typeof getChosenImportConfig>
) => `${getVariableName(app.name)}_${getVariableName(chosenConfig.fileToBeImported)}`;
) =>
`${getVariableName(app.name)}_${getVariableName(
chosenConfig.fileToBeImported
)}`;
const fileToBeImportedExists = (
app: { path: string },
chosenConfig: ReturnType<typeof getChosenImportConfig>
) => fs.existsSync(path.join(APP_STORE_PATH, app.path, chosenConfig.fileToBeImported));
) =>
fs.existsSync(
path.join(APP_STORE_PATH, app.path, chosenConfig.fileToBeImported)
);
addImportStatements();
createExportObject();
@@ -163,13 +198,19 @@ function generateFiles() {
function addImportStatements() {
forEachAppDir((app) => {
const chosenConfig = getChosenImportConfig(importConfig, app);
if (fileToBeImportedExists(app, chosenConfig) && chosenConfig.importName) {
if (
fileToBeImportedExists(app, chosenConfig) &&
chosenConfig.importName
) {
const importName = chosenConfig.importName;
if (!lazyImport) {
if (importName !== "default") {
// Import with local alias that will be used by createExportObject
output.push(
`import { ${importName} as ${getLocalImportName(app, chosenConfig)} } from "${getModulePath(
`import { ${importName} as ${getLocalImportName(
app,
chosenConfig
)} } from "${getModulePath(
app.path,
chosenConfig.fileToBeImported
)}"`
@@ -177,7 +218,10 @@ function generateFiles() {
} else {
// Default Import
output.push(
`import ${getLocalImportName(app, chosenConfig)} from "${getModulePath(
`import ${getLocalImportName(
app,
chosenConfig
)} from "${getModulePath(
app.path,
chosenConfig.fileToBeImported
)}"`
@@ -208,7 +252,12 @@ function generateFiles() {
)}")),`
);
} else {
output.push(`"${key}": import("${getModulePath(app.path, chosenConfig.fileToBeImported)}"),`);
output.push(
`"${key}": import("${getModulePath(
app.path,
chosenConfig.fileToBeImported
)}"),`
);
}
}
}
@@ -217,13 +266,24 @@ function generateFiles() {
output.push(`};`);
}
function getChosenImportConfig(importConfig: ImportConfig, app: { path: string }) {
let chosenConfig;
function getChosenImportConfig(
importConfig: ImportConfig,
app: { path: string }
) {
let chosenConfig: ImportConfig;
if (!(importConfig instanceof Array)) {
if (!Array.isArray(importConfig)) {
chosenConfig = importConfig;
} else {
if (fs.existsSync(path.join(APP_STORE_PATH, app.path, importConfig[0].fileToBeImported))) {
if (
fs.existsSync(
path.join(
APP_STORE_PATH,
app.path,
importConfig[0].fileToBeImported
)
)
) {
chosenConfig = importConfig[0];
} else {
chosenConfig = importConfig[1];
@@ -409,7 +469,10 @@ function generateFiles() {
);
if (analyticsExportLineIndex !== -1) {
const exportLine = analyticsServices[analyticsExportLineIndex];
const objectContent = analyticsServices.slice(analyticsExportLineIndex + 1, -1);
const objectContent = analyticsServices.slice(
analyticsExportLineIndex + 1,
-1
);
analyticsOutput.push(
exportLine.replace(
@@ -434,7 +497,9 @@ function generateFiles() {
lazyImport: true,
},
(app: App) => {
const hasPaymentService = fs.existsSync(path.join(APP_STORE_PATH, app.path, "lib/PaymentService.ts"));
const hasPaymentService = fs.existsSync(
path.join(APP_STORE_PATH, app.path, "lib/PaymentService.ts")
);
return hasPaymentService;
}
);
@@ -452,7 +517,9 @@ function generateFiles() {
lazyImport: true,
},
(app: App) => {
return fs.existsSync(path.join(APP_STORE_PATH, app.path, "lib/VideoApiAdapter.ts"));
return fs.existsSync(
path.join(APP_STORE_PATH, app.path, "lib/VideoApiAdapter.ts")
);
}
);
@@ -494,9 +561,13 @@ function generateFiles() {
["video.adapters.generated.ts", videoOutput],
];
filesToGenerate.forEach(([fileName, output]) => {
fs.writeFileSync(`${APP_STORE_PATH}/${fileName}`, formatOutput(`${banner}${output.join("\n")}`));
const filePath = `${APP_STORE_PATH}/${fileName}`;
fs.writeFileSync(filePath, formatOutput(`${banner}${output.join("\n")}`));
formatFileWithBiome(filePath);
});
console.log(`Generated ${filesToGenerate.map(([fileName]) => fileName).join(", ")}`);
console.log(
`Generated ${filesToGenerate.map(([fileName]) => fileName).join(", ")}`
);
}
const debouncedGenerateFiles = debounce(generateFiles);
-1
View File
@@ -1 +0,0 @@
*.generated.*
+125 -44
View File
@@ -5,67 +5,148 @@
import dynamic from "next/dynamic";
export const InstallAppButtonMap = {
exchange2013calendar: dynamic(() => import("./exchange2013calendar/components/InstallAppButton")),
exchange2016calendar: dynamic(() => import("./exchange2016calendar/components/InstallAppButton")),
office365video: dynamic(() => import("./office365video/components/InstallAppButton")),
exchange2013calendar: dynamic(
() => import("./exchange2013calendar/components/InstallAppButton")
),
exchange2016calendar: dynamic(
() => import("./exchange2016calendar/components/InstallAppButton")
),
office365video: dynamic(
() => import("./office365video/components/InstallAppButton")
),
vital: dynamic(() => import("./vital/components/InstallAppButton")),
};
export const AppSettingsComponentsMap = {
"general-app-settings": dynamic(() =>
import("./templates/general-app-settings/components/AppSettingsInterface")
"general-app-settings": dynamic(
() =>
import("./templates/general-app-settings/components/AppSettingsInterface")
),
weather_in_your_calendar: dynamic(() =>
import("./weather_in_your_calendar/components/AppSettingsInterface")
weather_in_your_calendar: dynamic(
() => import("./weather_in_your_calendar/components/AppSettingsInterface")
),
zapier: dynamic(() => import("./zapier/components/AppSettingsInterface")),
};
export const EventTypeAddonMap = {
alby: dynamic(() => import("./alby/components/EventTypeAppCardInterface")),
basecamp3: dynamic(() => import("./basecamp3/components/EventTypeAppCardInterface")),
btcpayserver: dynamic(() => import("./btcpayserver/components/EventTypeAppCardInterface")),
closecom: dynamic(() => import("./closecom/components/EventTypeAppCardInterface")),
databuddy: dynamic(() => import("./databuddy/components/EventTypeAppCardInterface")),
fathom: dynamic(() => import("./fathom/components/EventTypeAppCardInterface")),
basecamp3: dynamic(
() => import("./basecamp3/components/EventTypeAppCardInterface")
),
btcpayserver: dynamic(
() => import("./btcpayserver/components/EventTypeAppCardInterface")
),
closecom: dynamic(
() => import("./closecom/components/EventTypeAppCardInterface")
),
databuddy: dynamic(
() => import("./databuddy/components/EventTypeAppCardInterface")
),
fathom: dynamic(
() => import("./fathom/components/EventTypeAppCardInterface")
),
ga4: dynamic(() => import("./ga4/components/EventTypeAppCardInterface")),
giphy: dynamic(() => import("./giphy/components/EventTypeAppCardInterface")),
gtm: dynamic(() => import("./gtm/components/EventTypeAppCardInterface")),
hitpay: dynamic(() => import("./hitpay/components/EventTypeAppCardInterface")),
hubspot: dynamic(() => import("./hubspot/components/EventTypeAppCardInterface")),
insihts: dynamic(() => import("./insihts/components/EventTypeAppCardInterface")),
matomo: dynamic(() => import("./matomo/components/EventTypeAppCardInterface")),
metapixel: dynamic(() => import("./metapixel/components/EventTypeAppCardInterface")),
"mock-payment-app": dynamic(() => import("./mock-payment-app/components/EventTypeAppCardInterface")),
paypal: dynamic(() => import("./paypal/components/EventTypeAppCardInterface")),
"pipedrive-crm": dynamic(() => import("./pipedrive-crm/components/EventTypeAppCardInterface")),
plausible: dynamic(() => import("./plausible/components/EventTypeAppCardInterface")),
posthog: dynamic(() => import("./posthog/components/EventTypeAppCardInterface")),
qr_code: dynamic(() => import("./qr_code/components/EventTypeAppCardInterface")),
salesforce: dynamic(() => import("./salesforce/components/EventTypeAppCardInterface")),
stripepayment: dynamic(() => import("./stripepayment/components/EventTypeAppCardInterface")),
"booking-pages-tag": dynamic(() =>
import("./templates/booking-pages-tag/components/EventTypeAppCardInterface")
hitpay: dynamic(
() => import("./hitpay/components/EventTypeAppCardInterface")
),
"event-type-app-card": dynamic(() =>
import("./templates/event-type-app-card/components/EventTypeAppCardInterface")
hubspot: dynamic(
() => import("./hubspot/components/EventTypeAppCardInterface")
),
insihts: dynamic(
() => import("./insihts/components/EventTypeAppCardInterface")
),
matomo: dynamic(
() => import("./matomo/components/EventTypeAppCardInterface")
),
metapixel: dynamic(
() => import("./metapixel/components/EventTypeAppCardInterface")
),
"mock-payment-app": dynamic(
() => import("./mock-payment-app/components/EventTypeAppCardInterface")
),
paypal: dynamic(
() => import("./paypal/components/EventTypeAppCardInterface")
),
"pipedrive-crm": dynamic(
() => import("./pipedrive-crm/components/EventTypeAppCardInterface")
),
plausible: dynamic(
() => import("./plausible/components/EventTypeAppCardInterface")
),
posthog: dynamic(
() => import("./posthog/components/EventTypeAppCardInterface")
),
qr_code: dynamic(
() => import("./qr_code/components/EventTypeAppCardInterface")
),
salesforce: dynamic(
() => import("./salesforce/components/EventTypeAppCardInterface")
),
stripepayment: dynamic(
() => import("./stripepayment/components/EventTypeAppCardInterface")
),
"booking-pages-tag": dynamic(
() =>
import(
"./templates/booking-pages-tag/components/EventTypeAppCardInterface"
)
),
"event-type-app-card": dynamic(
() =>
import(
"./templates/event-type-app-card/components/EventTypeAppCardInterface"
)
),
twipla: dynamic(
() => import("./twipla/components/EventTypeAppCardInterface")
),
twipla: dynamic(() => import("./twipla/components/EventTypeAppCardInterface")),
umami: dynamic(() => import("./umami/components/EventTypeAppCardInterface")),
"zoho-bigin": dynamic(() => import("./zoho-bigin/components/EventTypeAppCardInterface")),
zohocrm: dynamic(() => import("./zohocrm/components/EventTypeAppCardInterface")),
"zoho-bigin": dynamic(
() => import("./zoho-bigin/components/EventTypeAppCardInterface")
),
zohocrm: dynamic(
() => import("./zohocrm/components/EventTypeAppCardInterface")
),
};
export const EventTypeSettingsMap = {
alby: dynamic(() => import("./alby/components/EventTypeAppSettingsInterface")),
basecamp3: dynamic(() => import("./basecamp3/components/EventTypeAppSettingsInterface")),
btcpayserver: dynamic(() => import("./btcpayserver/components/EventTypeAppSettingsInterface")),
databuddy: dynamic(() => import("./databuddy/components/EventTypeAppSettingsInterface")),
fathom: dynamic(() => import("./fathom/components/EventTypeAppSettingsInterface")),
alby: dynamic(
() => import("./alby/components/EventTypeAppSettingsInterface")
),
basecamp3: dynamic(
() => import("./basecamp3/components/EventTypeAppSettingsInterface")
),
btcpayserver: dynamic(
() => import("./btcpayserver/components/EventTypeAppSettingsInterface")
),
databuddy: dynamic(
() => import("./databuddy/components/EventTypeAppSettingsInterface")
),
fathom: dynamic(
() => import("./fathom/components/EventTypeAppSettingsInterface")
),
ga4: dynamic(() => import("./ga4/components/EventTypeAppSettingsInterface")),
giphy: dynamic(() => import("./giphy/components/EventTypeAppSettingsInterface")),
giphy: dynamic(
() => import("./giphy/components/EventTypeAppSettingsInterface")
),
gtm: dynamic(() => import("./gtm/components/EventTypeAppSettingsInterface")),
hitpay: dynamic(() => import("./hitpay/components/EventTypeAppSettingsInterface")),
metapixel: dynamic(() => import("./metapixel/components/EventTypeAppSettingsInterface")),
paypal: dynamic(() => import("./paypal/components/EventTypeAppSettingsInterface")),
plausible: dynamic(() => import("./plausible/components/EventTypeAppSettingsInterface")),
qr_code: dynamic(() => import("./qr_code/components/EventTypeAppSettingsInterface")),
stripepayment: dynamic(() => import("./stripepayment/components/EventTypeAppSettingsInterface")),
hitpay: dynamic(
() => import("./hitpay/components/EventTypeAppSettingsInterface")
),
metapixel: dynamic(
() => import("./metapixel/components/EventTypeAppSettingsInterface")
),
paypal: dynamic(
() => import("./paypal/components/EventTypeAppSettingsInterface")
),
plausible: dynamic(
() => import("./plausible/components/EventTypeAppSettingsInterface")
),
qr_code: dynamic(
() => import("./qr_code/components/EventTypeAppSettingsInterface")
),
stripepayment: dynamic(
() => import("./stripepayment/components/EventTypeAppSettingsInterface")
),
};
@@ -52,7 +52,6 @@ import { appKeysSchema as zoho_bigin_zod_ts } from "./zoho-bigin/zod";
import { appKeysSchema as zohocalendar_zod_ts } from "./zohocalendar/zod";
import { appKeysSchema as zohocrm_zod_ts } from "./zohocrm/zod";
import { appKeysSchema as zoomvideo_zod_ts } from "./zoomvideo/zod";
export const appKeysSchemas = {
alby: alby_zod_ts,
basecamp3: basecamp3_zod_ts,
@@ -111,7 +111,6 @@ import zoho_bigin_config_json from "./zoho-bigin/config.json";
import zohocalendar_config_json from "./zohocalendar/config.json";
import zohocrm_config_json from "./zohocrm/config.json";
import { metadata as zoomvideo__metadata_ts } from "./zoomvideo/_metadata";
export const appStoreMetadata = {
alby: alby_config_json,
amie: amie_config_json,
@@ -52,7 +52,6 @@ import { appDataSchema as zoho_bigin_zod_ts } from "./zoho-bigin/zod";
import { appDataSchema as zohocalendar_zod_ts } from "./zohocalendar/zod";
import { appDataSchema as zohocrm_zod_ts } from "./zohocrm/zod";
import { appDataSchema as zoomvideo_zod_ts } from "./zoomvideo/zod";
export const appDataSchemas = {
alby: alby_zod_ts,
basecamp3: basecamp3_zod_ts,
@@ -46,7 +46,6 @@ import webex_config_json from "./webex/config.json";
import whatsapp_config_json from "./whatsapp/config.json";
import whereby_config_json from "./whereby/config.json";
import { metadata as zoomvideo__metadata_ts } from "./zoomvideo/_metadata";
export const appStoreMetadata = {
campfire: campfire_config_json,
dailyvideo: dailyvideo__metadata_ts,
-16
View File
@@ -1,16 +0,0 @@
import { forbid } from "@calcom/eslint-config/base";
import { config } from "@calcom/eslint-config/react-internal";
export default [
...config,
forbid({
from: "../features/**",
target: ".",
message: "app-store package should not import from features to avoid circular dependencies.",
}),
forbid({
from: "../trpc/**",
target: ".",
message: "app-store package should not import from trpc to avoid circular dependencies.",
}),
];
+3 -4
View File
@@ -10,9 +10,9 @@
"scripts": {
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"lint": "eslint .",
"lint:fix": "eslint .",
"lint:report": "eslint . --format json --output-file ../../lint-results/app-store.json"
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"lint:report": "biome lint --reporter json . > ../../lint-results/app-store.json"
},
"dependencies": {
"@calcom/dailyvideo": "workspace:*",
@@ -33,7 +33,6 @@
"zod": "^3.0.0"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@calcom/types": "workspace:*"
}
}
@@ -12,11 +12,10 @@
"react-awesome-query-builder": "5.1.2"
},
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint ."
"lint": "biome lint .",
"lint:fix": "biome lint --write ."
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@calcom/types": "workspace:*",
"@types/json-logic-js": "1.2.1"
}
-15
View File
@@ -5,12 +5,7 @@
"version": "0.0.0",
"main": "index.js",
"license": "MIT",
"files": [
"eslint-preset.js",
"prettier-preset.js"
],
"dependencies": {
"@calcom/eslint-plugin-eslint": "workspace:*",
"@todesktop/tailwind-variants": "1.0.1",
"tailwind-scrollbar": "4.0.2",
"tailwindcss-radix": "4.0.2",
@@ -18,16 +13,6 @@
},
"devDependencies": {
"@tailwindcss/typography": "0.5.4",
"@trivago/prettier-plugin-sort-imports": "4.1.1",
"@typescript-eslint/eslint-plugin": "5.52.0",
"@typescript-eslint/parser": "5.52.0",
"eslint-config-next": "13.5.11",
"eslint-config-prettier": "8.6.0",
"eslint-config-turbo": "0.0.7",
"eslint-plugin-playwright": "0.12.0",
"eslint-plugin-prettier": "4.2.1",
"prettier": "2.8.7",
"prettier-plugin-tailwindcss": "0.2.5",
"typescript": "5.9.2"
}
}
-41
View File
@@ -1,41 +0,0 @@
module.exports = {
bracketSpacing: true,
bracketSameLine: true,
singleQuote: false,
jsxSingleQuote: false,
trailingComma: "es5",
semi: true,
printWidth: 110,
arrowParens: "always",
endOfLine: "auto",
importOrder: [
// Mocks must be at the top as they contain vi.mock calls
"(.*)/__mocks__/(.*)",
// bookingScenario contains prismock that must be imported asap
"(.*)bookingScenario(.*)",
"<THIRD_PARTY_MODULES>",
"^@(calcom|ee)/(.*)$",
"^@lib/(.*)$",
"^@components/(.*)$",
"^@(server|trpc)/(.*)$",
"^~/(.*)$",
"^[./]",
],
importOrderSeparation: true,
plugins: [
"@trivago/prettier-plugin-sort-imports",
/**
* **NOTE** tailwind plugin must come last!
* @see https://github.com/tailwindlabs/prettier-plugin-tailwindcss#compatibility-with-other-prettier-plugins
*/
"prettier-plugin-tailwindcss",
],
overrides: [
{
files: ["apps/website/lib/utils/wordlist/wordlist.ts"],
options: {
quoteProps: "consistent",
},
},
],
};
+2 -2
View File
@@ -9,8 +9,8 @@
"./hooks/*": "./src/hooks/*.ts"
},
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"registry:pull": "ts-node ../../scripts/pull-coss-ui-components.ts"
+2 -2
View File
@@ -28,8 +28,8 @@
"dev-real": "vite dev --port 3100",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"lint": "eslint --ext .ts,.js src",
"lint:fix": "eslint --ext .ts,.js src --fix",
"lint": "biome lint src",
"lint:fix": "biome lint --write src",
"embed-tests": "yarn playwright test --config=playwright/config/playwright.config.ts",
"embed-tests-quick": "QUICK=true yarn embed-tests",
"embed-tests-update-snapshots:ci": "yarn embed-tests-quick --update-snapshots",
@@ -269,6 +269,10 @@ export const useEmbedType = () => {
};
function makeBodyVisible() {
// Guard against test environment teardown where document may no longer exist
if (typeof document === "undefined" || !document.body) {
return;
}
if (document.body.style.visibility !== "visible") {
document.body.style.visibility = "visible";
}
@@ -9,7 +9,7 @@ import type {
} from "../../types";
import { runAsap, log } from "./utils";
export const enum EMBED_IFRAME_STATE {
export enum EMBED_IFRAME_STATE {
NOT_INITIALIZED,
INITIALIZED,
}
+1 -2
View File
@@ -15,7 +15,7 @@
"preview": "vite preview",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"lint": "eslint --ext .ts,.js,.tsx,.jsx ./src",
"lint": "biome lint ./src",
"embed-tests": "yarn playwright test --config=./playwright/config/playwright.config.ts",
"embed-tests-quick": "QUICK=true yarn embed-tests",
"embed-tests-update-snapshots:ci": "yarn embed-tests-quick --update-snapshots",
@@ -44,7 +44,6 @@
}
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@playwright/test": "1.57.0",
"@types/react": "18.0.26",
"@types/react-dom": "18.2.6",
+1 -2
View File
@@ -15,7 +15,7 @@
"build": "rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationDir dist",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"lint": "eslint --ext .ts,.js src",
"lint": "biome lint src",
"withEmbedPublishEnv": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn",
"prepack": "yarn ../../../ lint --filter='@calcom/embed-snippet' && yarn withEmbedPublishEnv build",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
@@ -25,7 +25,6 @@
],
"types": "./dist/index.d.ts",
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"typescript": "5.9.2",
"vite": "4.5.14"
},
-60
View File
@@ -1,60 +0,0 @@
import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import importPlugin from "eslint-plugin-import";
import onlyWarn from "eslint-plugin-only-warn";
import turboPlugin from "eslint-plugin-turbo";
import tseslint from "typescript-eslint";
/**
* A shared ESLint configuration for the repository.
*
* @type {import("eslint").Linter.Config}
*/
export const config = [
js.configs.recommended,
eslintConfigPrettier,
...tseslint.configs.recommended,
{
plugins: {
turbo: turboPlugin,
import: importPlugin,
onlyWarn,
},
rules: {
"turbo/no-undeclared-env-vars": "warn",
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }],
},
languageOptions: {
ecmaVersion: 2021,
sourceType: "module",
},
settings: {
"import/resolver": {
typescript: true,
node: true,
},
},
},
{
ignores: ["dist/**", "**/node_modules/**", "**/.next/**"],
},
];
export function forbid({ from, target, message }) {
return {
rules: {
"import/no-restricted-paths": [
"error",
{
zones: [
{
from: [from],
target: [target],
message: message ?? `Import denied from ${target} to ${from}`,
},
],
},
],
},
};
}
-51
View File
@@ -1,51 +0,0 @@
import js from "@eslint/js";
import pluginNext from "@next/eslint-plugin-next";
import eslintConfigPrettier from "eslint-config-prettier";
import pluginReact from "eslint-plugin-react";
import pluginReactHooks from "eslint-plugin-react-hooks";
import globals from "globals";
import tseslint from "typescript-eslint";
import { config as baseConfig } from "./base.js";
/**
* A custom ESLint configuration for libraries that use Next.js.
*
* @type {import("eslint").Linter.Config}
* */
export const nextJsConfig = [
...baseConfig,
js.configs.recommended,
eslintConfigPrettier,
...tseslint.configs.recommended,
{
...pluginReact.configs.flat.recommended,
languageOptions: {
...pluginReact.configs.flat.recommended.languageOptions,
globals: {
...globals.serviceworker,
},
},
},
{
plugins: {
"@next/next": pluginNext,
},
rules: {
...pluginNext.configs.recommended.rules,
...pluginNext.configs["core-web-vitals"].rules,
},
},
{
plugins: {
"react-hooks": pluginReactHooks,
},
settings: { react: { version: "detect" } },
rules: {
...pluginReactHooks.configs.recommended.rules,
// React scope no longer necessary with new JSX transform.
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
},
},
];
-30
View File
@@ -1,30 +0,0 @@
{
"name": "@calcom/eslint-config",
"version": "0.0.0",
"type": "module",
"private": true,
"exports": {
"./base": "./base.js",
"./next-js": "./next.js",
"./react-internal": "./react-internal.js"
},
"dependencies": {
"@eslint/js": "9.36.0",
"@next/eslint-plugin-next": "15.4.5",
"@typescript-eslint/eslint-plugin": "8.39.0",
"@typescript-eslint/parser": "8.39.0",
"globals": "15.15.0",
"typescript-eslint": "8.40.0"
},
"devDependencies": {
"eslint": "9.36.0",
"eslint-config-prettier": "9.1.2",
"eslint-import-resolver-typescript": "4.4.4",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-only-warn": "1.1.0",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "5.2.0",
"eslint-plugin-turbo": "2.5.5",
"typescript": "5.9.2"
}
}
-41
View File
@@ -1,41 +0,0 @@
import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import pluginReact from "eslint-plugin-react";
import pluginReactHooks from "eslint-plugin-react-hooks";
import globals from "globals";
import tseslint from "typescript-eslint";
import { config as baseConfig } from "./base.js";
/**
* A custom ESLint configuration for libraries that use React.
*
* @type {import("eslint").Linter.Config} */
export const config = [
...baseConfig,
js.configs.recommended,
eslintConfigPrettier,
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
{
languageOptions: {
...pluginReact.configs.flat.recommended.languageOptions,
globals: {
...globals.serviceworker,
...globals.browser,
},
},
},
{
plugins: {
"react-hooks": pluginReactHooks,
},
settings: { react: { version: "detect" } },
rules: {
...pluginReactHooks.configs.recommended.rules,
// React scope no longer necessary with new JSX transform.
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
},
},
];
-16
View File
@@ -1,16 +0,0 @@
{
"name": "@calcom/eslint-plugin-eslint",
"sideEffects": false,
"private": true,
"version": "0.1.0",
"main": "./src/index.js",
"dependencies": {
"@typescript-eslint/parser": "5.52.0",
"@typescript-eslint/utils": "5.52.0",
"ts-node-maintained": "10.9.5"
},
"devDependencies": {
"@types/eslint": "8.4.5",
"typescript": "5.9.2"
}
}
@@ -1,4 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires, import/no-anonymous-default-export */
export default {
recommended: require("./recommended").default,
};
@@ -1,16 +0,0 @@
const recommended = {
parser: "@typescript-eslint/parser",
parserOptions: { sourceType: "module" },
rules: {
"@calcom/eslint/deprecated-imports": "error",
"@calcom/eslint/deprecated-imports-next-router": "error",
"@calcom/eslint/avoid-web-storage": "error",
"@calcom/eslint/avoid-prisma-client-import-for-enums": "error",
"@calcom/eslint/no-prisma-include-true": "warn",
"@calcom/eslint/no-scroll-into-view-embed": "error",
"@calcom/eslint/no-direct-prisma-import": "error",
"@calcom/eslint/no-this-in-static-method": "error",
},
};
export default recommended;
-15
View File
@@ -1,15 +0,0 @@
// This registers Typescript compiler instance onto node.js.
// Now it is possible to just require typescript files without any compilation steps in the environment run by node
require("ts-node-maintained").register({
compilerOptions: {
module: "commonjs",
},
});
// re-export our rules so that eslint run by node can understand them
module.exports = {
// import our rules from the typescript file
rules: require("./rules/index.ts").default,
// import our config from the typescript file
configs: require("./configs/index.ts").default,
};
@@ -1,45 +0,0 @@
import { ESLintUtils } from "@typescript-eslint/utils";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
const rule = createRule({
create(context) {
return {
ImportDeclaration(node) {
node.source.value === "@prisma/client" &&
node.importKind !== "type" &&
node.specifiers.forEach((item) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const enumType = item.imported?.name; // ts doesn't know about imported, bad type?
if (!enumType || enumType === "Prisma" || enumType === "PrismaClient") return null;
return context.report({
node: item,
loc: node.loc,
messageId: "avoid-prisma-client-import",
data: {
enumType,
},
});
});
},
};
},
name: "avoid-prisma-client-import-for-enums",
meta: {
fixable: "code",
docs: {
description: "Avoid prisma client import for enums",
recommended: "error",
},
messages: {
"avoid-prisma-client-import": `Import { {{enumType}} } from '@calcom/prisma/enums' to avoid including @prisma/client.`,
},
type: "suggestion",
schema: [],
},
defaultOptions: [],
});
export default rule;
@@ -1,127 +0,0 @@
import { ESLintUtils } from "@typescript-eslint/utils";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
const rule = createRule({
create(context) {
// Track imported names from @calcom/lib/webstorage
const safeImportedNames = new Set<string>();
return {
ImportDeclaration(node) {
// Check if this is an import from the safe webstorage module
if (node.source.value === "@calcom/lib/webstorage") {
node.specifiers.forEach((specifier) => {
if (specifier.type === "ImportSpecifier") {
// Track the local name used for the import
safeImportedNames.add(specifier.local.name);
}
});
}
},
CallExpression(node) {
const webStorages = ["localStorage", "sessionStorage"];
const callee = node.callee;
// Check for window.localStorage or window.sessionStorage
if (
// Can't figure out how to fix this TS issue
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
callee.object?.object?.name === "window" &&
// Can't figure out how to fix this TS issue
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
webStorages.includes(node?.callee?.object?.property?.name)
) {
return context.report({
node: node,
loc: node.loc,
messageId: "possible-issue-with-embed",
});
}
// Check for direct localStorage or sessionStorage usage
if (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
callee.type === "MemberExpression" &&
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
callee.object?.type === "Identifier" &&
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
webStorages.includes(callee.object?.name) &&
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
!safeImportedNames.has(callee.object?.name)
) {
return context.report({
node: node,
loc: node.loc,
messageId: "possible-issue-with-embed",
});
}
},
// Also check for property access like localStorage.length
MemberExpression(node) {
const webStorages = ["localStorage", "sessionStorage"];
// Check for direct property access on localStorage/sessionStorage
if (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
node.object?.type === "Identifier" &&
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
webStorages.includes(node.object?.name) &&
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
!safeImportedNames.has(node.object?.name)
) {
return context.report({
node: node,
loc: node.loc,
messageId: "possible-issue-with-embed",
});
}
// Check for window.localStorage/sessionStorage property access
if (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
node.object?.type === "MemberExpression" &&
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
node.object?.object?.name === "window" &&
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
webStorages.includes(node.object?.property?.name)
) {
return context.report({
node: node,
loc: node.loc,
messageId: "possible-issue-with-embed",
});
}
},
};
},
name: "avoid-web-storage",
meta: {
fixable: "code",
docs: {
description: "Avoid deprecated imports",
recommended: "warn",
},
messages: {
"possible-issue-with-embed": `Be aware that accessing localStorage/sessionStorage throws error in Chrome Incognito mode when embed is in cross domain context. If you know what you are doing, \`import {localStorage, sessionStorage} from "@calcom/lib/webstorage"\` for safe usage. See https://github.com/calcom/cal.com/issues/2618`,
},
type: "suggestion",
schema: [],
},
defaultOptions: [],
});
export default rule;
@@ -1,38 +0,0 @@
import { ESLintUtils } from "@typescript-eslint/utils";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
const rule = createRule({
name: "deprecated-imports-next-router",
meta: {
fixable: "code",
docs: {
description: "Importing router from 'next/router' is deprecated, use 'next/navigation' instead",
recommended: "error",
},
messages: {
"deprecated-next-router":
"Importing router from 'next/router' is deprecated, use 'next/navigation' instead",
},
type: "problem",
schema: [],
},
defaultOptions: [],
create(context) {
return {
ImportDeclaration(node) {
if (node.source.value === "next/router") {
context.report({
node,
messageId: "deprecated-next-router",
fix: function (fixer) {
return fixer.replaceText(node.source, "'next/navigation'");
},
});
}
},
};
},
});
export default rule;
@@ -1,41 +0,0 @@
import { ESLintUtils } from "@typescript-eslint/utils";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
const rule = createRule({
create(context) {
return {
ImportDeclaration(node) {
node.specifiers.length &&
node.source.value === "dayjs" &&
node.specifiers.forEach((item) => {
if (item.local.name === "dayjs") {
return context.report({
node: item,
loc: node.loc,
messageId: "dayjs-moved",
fix: (fixer) => fixer.replaceText(node, "import dayjs from '@calcom/dayjs'"),
});
}
return null;
});
},
};
},
name: "deprecated-imports",
meta: {
fixable: "code",
docs: {
description: "Avoid deprecated imports",
recommended: "warn",
},
messages: {
"dayjs-moved": `Import dayjs from '@calcom/daysjs' to avoid plugin conflicts.`,
},
type: "suggestion",
schema: [],
},
defaultOptions: [],
});
export default rule;
-13
View File
@@ -1,13 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires*/
import type { ESLint } from "eslint";
export default {
"deprecated-imports": require("./deprecated-imports").default,
"avoid-web-storage": require("./avoid-web-storage").default,
"avoid-prisma-client-import-for-enums": require("./avoid-prisma-client-import-for-enums").default,
"no-prisma-include-true": require("./no-prisma-include-true").default,
"deprecated-imports-next-router": require("./deprecated-imports-next-router").default,
"no-scroll-into-view-embed": require("./no-scroll-into-view-embed").default,
"no-direct-prisma-import": require("./no-direct-prisma-import").default,
"no-this-in-static-method": require("./no-this-in-static-method").default,
} as ESLint.Plugin["rules"];
@@ -1,23 +0,0 @@
import type { Rule } from "eslint";
const rule: Rule.RuleModule = {
meta: {
docs: {
description: "This rule is run on typescript!",
},
},
create: (context) => {
return {
VariableDeclarator: (node) => {
if (node.id.type === "Identifier" && node.id.name !== "bla") {
context.report({
node,
message: 'All variabled should be named "bla"!',
});
}
},
};
},
};
export default rule;
@@ -1,43 +0,0 @@
import { ESLintUtils } from "@typescript-eslint/utils";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
const rule = createRule({
create(context) {
return {
ImportDeclaration(node) {
if (node.source.value === "@prisma/client") {
return context.report({
node,
messageId: "no-direct-prisma-import",
data: {},
fix(fixer) {
return fixer.replaceText(
node.source,
node.source.raw
.replace('"@prisma/client"', '"@calcom/prisma/client"')
.replace("'@prisma/client'", "'@calcom/prisma/client'")
);
},
});
}
},
};
},
name: "no-direct-prisma-import",
meta: {
fixable: "code",
docs: {
description: "Prevent direct imports from @prisma/client",
recommended: "error",
},
messages: {
"no-direct-prisma-import": `Direct imports from '@prisma/client' are not allowed. Use '@calcom/prisma/client' instead.`,
},
type: "problem",
schema: [],
},
defaultOptions: [],
});
export default rule;
@@ -1,100 +0,0 @@
import type { TSESTree } from "@typescript-eslint/utils";
import { ESLintUtils } from "@typescript-eslint/utils";
import type { ReportDescriptor } from "@typescript-eslint/utils/dist/ts-eslint";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
const assesIncludePropertyIncludesTrue = (
includeProperty: TSESTree.Property,
reporter: { (reportObj: ReportDescriptor<"no-prisma-include-true">): void }
) => {
if (includeProperty.value.type === "ObjectExpression") {
includeProperty.value.properties.forEach((childProperty) => {
if (
childProperty.type === "Property" &&
childProperty.value.type === "Literal" &&
childProperty.value.value === true
) {
reporter({
node: childProperty,
messageId: "no-prisma-include-true",
});
}
});
}
};
const searchIncludeProperty = (
property: TSESTree.Property,
reporter: { (reportObj: ReportDescriptor<"no-prisma-include-true">): void }
) => {
if (property.type === "Property") {
// If property is include, check if it has a child property with value true
if (property.key.type === "Identifier" && property.key.name === "include") {
assesIncludePropertyIncludesTrue(property, reporter);
}
// If property value is also an object, recursively search for include property
if (property.value.type === "ObjectExpression") {
property.value.properties.forEach((childProperty) => {
if (childProperty.type === "Property") {
searchIncludeProperty(childProperty, reporter);
}
});
}
}
};
const rule = createRule({
create: function (context) {
return {
CallExpression(node) {
if (!(node.callee as TSESTree.MemberExpression).property) {
return null;
}
const nodeName = ((node.callee as TSESTree.MemberExpression).property as TSESTree.Identifier).name;
if (
!["findUnique", "findUniqueOrThrow", "findFirst", "findFirstOrThrow", "findMany"].includes(nodeName)
) {
return null;
}
const nodeArgs = node.arguments[0] as TSESTree.ObjectExpression;
if (!nodeArgs) {
return null;
}
const backReporter = (reportObj: ReportDescriptor<"no-prisma-include-true">) => {
context.report(reportObj);
};
nodeArgs.properties?.forEach((property) => {
if (property.type === "Property") {
searchIncludeProperty(property, backReporter);
}
});
return null;
},
};
},
name: "no-prisma-include-true",
meta: {
type: "problem",
docs: {
description:
"Disallow passing argument object with include: { AnyPropertyName: true } to prisma methods",
recommended: "error",
},
messages: {
"no-prisma-include-true": `Do not pass argument object with include: { AnyPropertyName: true } to prisma methods`,
},
fixable: "code",
schema: [],
},
defaultOptions: [],
});
export default rule;
@@ -1,48 +0,0 @@
import type { TSESTree } from "@typescript-eslint/utils";
import { ESLintUtils } from "@typescript-eslint/utils";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
export default createRule({
name: "no-scroll-into-view-embed",
meta: {
docs: {
description: "Disallow usage of scrollIntoView and scrollIntoViewSmooth in embed mode",
recommended: "error",
},
messages: {
noScrollIntoViewForEmbed:
"Make sure to call scrollIntoView/scrollIntoViewSmooth conditionally if it is called without user action. Use useIsEmbed() to detect if embed mode and then don't call it for embed case.",
},
type: "problem",
schema: [],
},
defaultOptions: [],
create(context) {
return {
CallExpression(node: TSESTree.CallExpression) {
const { callee } = node;
if (callee.type === "MemberExpression") {
if (
callee.property.type === "Identifier" &&
(callee.property.name === "scrollIntoView" || callee.property.name === "scrollIntoViewSmooth")
) {
context.report({
node,
messageId: "noScrollIntoViewForEmbed",
});
}
} else if (
callee.type === "Identifier" &&
(callee.name === "scrollIntoView" || callee.name === "scrollIntoViewSmooth")
) {
context.report({
node,
messageId: "noScrollIntoViewForEmbed",
});
}
},
};
},
});
@@ -1,109 +0,0 @@
import type { TSESTree } from "@typescript-eslint/utils";
import { ESLintUtils } from "@typescript-eslint/utils";
const createRule = ESLintUtils.RuleCreator((name) => `https://developer.cal.com/eslint/rule/${name}`);
const rule = createRule({
create(context) {
let currentMethodIsStatic = false;
let currentClassName = "";
return {
MethodDefinition(node) {
if (node.static && node.key.type === "Identifier") {
currentMethodIsStatic = true;
if (node.parent?.type === "ClassBody" && node.parent.parent?.type === "ClassDeclaration") {
const classNode = node.parent.parent as TSESTree.ClassDeclaration;
if (classNode.id?.name) {
currentClassName = classNode.id.name;
}
}
}
},
"MethodDefinition:exit"(node: TSESTree.MethodDefinition) {
if (node.static) {
currentMethodIsStatic = false;
currentClassName = "";
}
},
MemberExpression(node) {
if (
currentMethodIsStatic &&
node.object.type === "ThisExpression" &&
node.property.type === "Identifier"
) {
const parent = node.parent;
const isPassedToCallback =
parent?.type === "CallExpression" &&
parent.arguments.includes(node) &&
parent.callee.type === "MemberExpression" &&
parent.callee.property.type === "Identifier" &&
["map", "filter", "forEach", "reduce", "find", "some", "every"].includes(
parent.callee.property.name
);
const isVariableAssignment = parent?.type === "VariableDeclarator" && parent.init === node;
const isObjectProperty = parent?.type === "Property" && parent.value === node;
const isArrayElement = parent?.type === "ArrayExpression" && parent.elements.includes(node);
const isFunctionArgument =
parent?.type === "CallExpression" &&
parent.arguments.includes(node) &&
!(
parent.callee.type === "MemberExpression" &&
parent.callee.property.type === "Identifier" &&
["map", "filter", "forEach", "reduce", "find", "some", "every"].includes(
parent.callee.property.name
)
);
const isReturnStatement = parent?.type === "ReturnStatement" && parent.argument === node;
if (
isPassedToCallback ||
isVariableAssignment ||
isObjectProperty ||
isArrayElement ||
isFunctionArgument ||
isReturnStatement
) {
context.report({
node,
messageId: "no-this-in-static-method",
data: {
className: currentClassName,
methodName: node.property.name,
},
fix(fixer) {
if (currentClassName && node.property.type === "Identifier") {
return fixer.replaceText(node, `${currentClassName}.${node.property.name}`);
}
return null;
},
});
}
}
},
};
},
name: "no-this-in-static-method",
meta: {
type: "problem",
docs: {
description: "Disallow using 'this' to reference static methods within static methods",
recommended: "error",
},
messages: {
"no-this-in-static-method":
"Do not use 'this.{{methodName}}' in static methods. Use '{{className}}.{{methodName}}' instead to avoid context loss when passed to callbacks.",
},
fixable: "code",
schema: [],
},
defaultOptions: [],
});
export default rule;
-11
View File
@@ -1,11 +0,0 @@
import { forbid } from "@calcom/eslint-config/base";
import { config } from "@calcom/eslint-config/base";
export default [
...config,
forbid({
from: "../trpc/**",
target: ".",
message: "features package should not import from trpc to avoid circular dependencies.",
}),
];
+2 -1
View File
@@ -7,7 +7,7 @@
"version": "1.0.0",
"main": "index.ts",
"scripts": {
"lint": "eslint .",
"lint": "biome lint .",
"dev:trigger": "npx trigger.dev@latest dev --analyze",
"deploy:trigger": "npx trigger.dev@latest deploy"
},
@@ -30,6 +30,7 @@
"react-select": "5.8.0",
"react-sticky-box": "2.0.4",
"recharts": "3.0.2",
"stripe": "9.16.0",
"stripe-event-types": "3.1.0",
"web-push": "3.6.7",
"zustand": "4.5.2"
+82 -23
View File
@@ -1,4 +1,4 @@
import React from "react";
import type React from "react";
import { CAL_URL, LOGO, WEBAPP_URL } from "./constants";
@@ -47,7 +47,8 @@ const joinMultipleNames = (names: string[] = []) => {
return `${names.length > 0 ? `${names.join(", ")} & ${lastName}` : lastName}`;
};
const makeAbsoluteUrl = (url: string) => (/^https?:\/\//.test(url) ? url : `${CAL_URL}${url}`);
const makeAbsoluteUrl = (url: string) =>
/^https?:\/\//.test(url) ? url : `${CAL_URL}${url}`;
const OG_ASSETS = {
meeting: {
@@ -81,12 +82,20 @@ export const getOGImageVersion = async (
...(additionalInputs ?? {}),
};
const content = JSON.stringify(versionInputs, Object.keys(versionInputs).sort());
const content = JSON.stringify(
versionInputs,
Object.keys(versionInputs).sort()
);
// Use Web Crypto API instead of Node.js crypto for Edge Runtime compatibility (`/api/social/og/image` is an Edge Runtime route)
const hashBuffer = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(content));
const hashBuffer = await crypto.subtle.digest(
"SHA-256",
new TextEncoder().encode(content)
);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
const hashHex = hashArray
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
return hashHex.substring(0, 8);
};
@@ -147,7 +156,10 @@ export const constructAppImage = async ({
return encodeURIComponent(`/api/social/og/image?${params.toString()}`);
};
export const constructGenericImage = async ({ title, description }: GenericImageProps): Promise<string> => {
export const constructGenericImage = async ({
title,
description,
}: GenericImageProps): Promise<string> => {
const params = new URLSearchParams({
type: "generic",
title,
@@ -159,7 +171,11 @@ export const constructGenericImage = async ({ title, description }: GenericImage
return encodeURIComponent(`/api/social/og/image?${params.toString()}`);
};
const Wrapper = ({ children, variant = "light", rotateBackground }: WrapperProps) => (
const Wrapper = ({
children,
variant = "light",
rotateBackground,
}: WrapperProps) => (
<div tw="flex w-full h-full">
<img
tw="flex absolute left-0 top-0 w-full h-[110%]"
@@ -169,7 +185,9 @@ const Wrapper = ({ children, variant = "light", rotateBackground }: WrapperProps
width="1200"
height="600"
/>
<div tw="flex flex-col w-full h-full px-[80px] py-[70px] items-start justify-center">{children}</div>
<div tw="flex flex-col w-full h-full px-[80px] py-[70px] items-start justify-center">
{children}
</div>
</div>
);
@@ -186,7 +204,8 @@ export const Meeting = ({ title, users = [], profile }: MeetingImageProps) => {
// any non existing images for dynamic collectives, while at the same time removing them from
// the names list, because the profile name of that event is a concatenation of all names.
const attendees = (profile.image ? [profile, ...users] : users).filter(
(value, index, self) => self.findIndex((v) => v.name === value.name) == index
(value, index, self) =>
self.findIndex((v) => v.name === value.name) === index
);
// Construct list of avatar urls, removes duplicates and empty profile images
@@ -199,15 +218,26 @@ export const Meeting = ({ title, users = [], profile }: MeetingImageProps) => {
// In case there is NO other attendee than the single meeting profile without an image, we add
// that name back in here, since the event probably is a round robin event.
const names = attendees.length > 0 ? attendees.map((user) => user.name) : [profile.name];
const names =
attendees.length > 0 ? attendees.map((user) => user.name) : [profile.name];
return (
<Wrapper variant={config.variant}>
<div tw="h-full flex flex-col justify-start">
<div tw="flex items-center justify-center" style={{ fontFamily: "cal", fontWeight: 300 }}>
<img src={`${WEBAPP_URL}/${config.logo}`} width={config.logoWidth} alt="Logo" />
<div
tw="flex items-center justify-center"
style={{ fontFamily: "cal", fontWeight: 300 }}
>
<img
src={`${WEBAPP_URL}/${config.logo}`}
width={config.logoWidth}
alt="Logo"
/>
{avatars.length > 0 && (
<div style={{ color: "#111827" }} tw="font-bold text-[92px] mx-8 bottom-2">
<div
style={{ color: "#111827" }}
tw="font-bold text-[92px] mx-8 bottom-2"
>
/
</div>
)}
@@ -217,28 +247,44 @@ export const Meeting = ({ title, users = [], profile }: MeetingImageProps) => {
tw="rounded-full mr-[-36px] border-[6px] border-[#CDCED2]"
key={avatar}
src={avatar}
alt="Profile picture"
alt="Profile"
width={config.avatarSize}
height={config.avatarSize}
/>
))}
{avatars.length > 3 && (
<div
tw={`flex items-center justify-center w-[${config.avatarSize}px] h-[${config.avatarSize}px] rounded-full bg-black text-inverted text-[54px] font-bold`}>
<span tw="flex top-[-5px] left-[-5px]">+{avatars.length - 3}</span>
tw={`flex items-center justify-center w-[${config.avatarSize}px] h-[${config.avatarSize}px] rounded-full bg-black text-inverted text-[54px] font-bold`}
>
<span tw="flex top-[-5px] left-[-5px]">
+{avatars.length - 3}
</span>
</div>
)}
</div>
</div>
<div style={{ color: "#111827" }} tw="relative flex text-[54px] w-full flex-col mt-auto">
<div
style={{ color: "#111827" }}
tw="relative flex text-[54px] w-full flex-col mt-auto"
>
<div
tw="flex w-[1040px] overflow-hidden"
style={{ whiteSpace: "nowrap", fontFamily: "cal", textOverflow: "ellipsis" }}>
style={{
whiteSpace: "nowrap",
fontFamily: "cal",
textOverflow: "ellipsis",
}}
>
Meet {joinMultipleNames(names)}
</div>
<div
tw="flex mt-3 w-[1040px] overflow-hidden"
style={{ whiteSpace: "nowrap", fontFamily: "inter", textOverflow: "ellipsis" }}>
style={{
whiteSpace: "nowrap",
fontFamily: "inter",
textOverflow: "ellipsis",
}}
>
{title}
</div>
</div>
@@ -309,7 +355,10 @@ export const App = ({ name, description, logoUrl }: AppImageProps) => {
</div>
</div>
<div style={{ color: "#111827" }} tw="flex mt-auto w-full flex-col">
<div tw="flex text-[64px] mb-7" style={{ fontFamily: "cal", fontWeight: 600 }}>
<div
tw="flex text-[64px] mb-7"
style={{ fontFamily: "cal", fontWeight: 600 }}
>
{name}
</div>
<div tw="flex text-[36px]" style={{ fontFamily: "inter" }}>
@@ -331,11 +380,21 @@ export const Generic = ({ title, description }: GenericImageProps) => {
return (
<Wrapper variant={config.variant}>
<div tw="h-full flex flex-col justify-start">
<div tw="flex items-center justify-center" style={{ fontFamily: "cal", fontWeight: 300 }}>
<img src={`${WEBAPP_URL}/${config.logo}`} width={config.logoWidth} alt="Logo" />
<div
tw="flex items-center justify-center"
style={{ fontFamily: "cal", fontWeight: 300 }}
>
<img
src={`${WEBAPP_URL}/${config.logo}`}
width={config.logoWidth}
alt="Logo"
/>
</div>
<div style={{ color: "#111827" }} tw="relative flex text-[54px] w-full flex-col mt-auto">
<div
style={{ color: "#111827" }}
tw="relative flex text-[54px] w-full flex-col mt-auto"
>
<div tw="flex w-[1040px]" style={{ fontFamily: "cal" }}>
{title}
</div>
@@ -1,6 +1,6 @@
import type { AppMeta } from "@calcom/types/App";
export const shouldRedirectToAppOnboarding = (appMetadata: AppMeta) => {
const hasEventTypes = appMetadata?.extendsFeature == "EventType";
const hasEventTypes = appMetadata?.extendsFeature === "EventType";
return hasEventTypes;
};
-39
View File
@@ -1,39 +0,0 @@
import { forbid } from "@calcom/eslint-config/base";
import { config } from "@calcom/eslint-config/base";
export default [
...config,
forbid({
from: "../app-store/**",
target: ".",
message: "lib package should not import from app-store to avoid circular dependencies.",
}),
forbid({
from: "../features/**",
target: ".",
message: "lib package should not import from features to avoid circular dependencies.",
}),
forbid({
from: "../trpc/**",
target: ".",
message: "lib package should not import from trpc to avoid circular dependencies.",
}),
{
// Block @trpc/server imports to keep packages/lib framework-agnostic.
// defaultResponder.ts is temporarily excluded until it can be refactored.
ignores: ["server/defaultResponder.ts", "server/defaultResponder.test.ts"],
rules: {
"no-restricted-imports": [
"error",
{
paths: [
{
name: "@trpc/server",
message: "packages/lib should not import from @trpc/server to keep it framework-agnostic.",
},
],
},
],
},
},
];
+3 -4
View File
@@ -5,9 +5,9 @@
"version": "0.0.0",
"license": "MIT",
"scripts": {
"lint": "eslint . --ext .ts,.js,.tsx,.jsx",
"lint:fix": "eslint . --ext .ts,.js,.tsx,.jsx --fix",
"lint:report": "eslint . --format json --output-file ../../lint-results/app-store.json"
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"lint:report": "biome lint --reporter json . > ../../lint-results/lib.json"
},
"dependencies": {
"@calcom/config": "workspace:*",
@@ -30,7 +30,6 @@
"uuid": "8.3.2"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@calcom/tsconfig": "workspace:*",
"@calcom/types": "workspace:*",
"@faker-js/faker": "7.6.0",
+18 -7
View File
@@ -1,8 +1,12 @@
import { createHmac } from "crypto";
import { createHmac } from "node:crypto";
// 262992 minutes is 6 months
export function generateVideoToken(recordingId: string, expiresInMinutes = 262992) {
const secret = process.env.CAL_VIDEO_RECORDING_TOKEN_SECRET || "default-secret-change-me";
export function generateVideoToken(
recordingId: string,
expiresInMinutes = 262992
) {
const secret =
process.env.CAL_VIDEO_RECORDING_TOKEN_SECRET || "default-secret-change-me";
const expires = Date.now() + expiresInMinutes * 60 * 1000;
const payload = `${recordingId}:${expires}`;
@@ -11,18 +15,25 @@ export function generateVideoToken(recordingId: string, expiresInMinutes = 26299
return `${payload}:${hmac}`;
}
export function verifyVideoToken(token: string): { valid: boolean; recordingId?: string } {
export function verifyVideoToken(token: string): {
valid: boolean;
recordingId?: string;
} {
try {
const [recordingId, expires, receivedHmac] = token.split(":");
const secret = process.env.CAL_VIDEO_RECORDING_TOKEN_SECRET || "default-secret-change-me";
const secret =
process.env.CAL_VIDEO_RECORDING_TOKEN_SECRET ||
"default-secret-change-me";
if (Date.now() > parseInt(expires)) {
if (Date.now() > parseInt(expires, 10)) {
return { valid: false };
}
// Verify HMAC
const payload = `${recordingId}:${expires}`;
const expectedHmac = createHmac("sha256", secret).update(payload).digest("hex");
const expectedHmac = createHmac("sha256", secret)
.update(payload)
.digest("hex");
if (receivedHmac !== expectedHmac) {
return { valid: false };
@@ -1,3 +0,0 @@
import { nextJsConfig } from "@calcom/eslint-config/next-js";
export default nextJsConfig;
+1 -2
View File
@@ -7,7 +7,7 @@
"dev": "PORT=4321 next dev",
"build": "next build",
"start": "next start",
"lint": "eslint .",
"lint": "biome lint .",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui"
},
@@ -21,7 +21,6 @@
"react-select": "5.8.0"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@playwright/test": "1.57.0",
"@tailwindcss/postcss": "4.1.15",
"@types/node": "20.17.23",
@@ -13,7 +13,7 @@ export type Data = {
};
// example endpoint to endpoint to fetch managed users
export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
export default async function handler(_req: NextApiRequest, res: NextApiResponse<Data>) {
const existingUsers = await prisma.user.findMany({ orderBy: { createdAt: "desc" } });
if (existingUsers && existingUsers.length > 2) {
return res.status(200).json({
-6
View File
@@ -1,6 +0,0 @@
const rootConfig = require("../../config/prettier-preset");
module.exports = {
...rootConfig,
importOrderParserPlugins: ["typescript", "decorators-legacy"],
};
-14
View File
@@ -1,14 +0,0 @@
import { config } from "@calcom/eslint-config/base";
import { forbid } from "@calcom/eslint-config/base";
export default [
...config,
{
ignores: ["./types/**"],
},
forbid({
from: "../apps/web/**",
target: ".",
message: "trpc package should not import from apps/web to avoid circular dependencies.",
}),
];
+2 -3
View File
@@ -7,8 +7,8 @@
"version": "1.0.0",
"main": "index.ts",
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . ",
"lint": "biome lint .",
"lint:fix": "biome lint --write .",
"build": "yarn build:server && yarn build:react",
"build:server": "yarn tsc --project tsconfig.server.json",
"build:react": "yarn tsc --project tsconfig.react.json"
@@ -30,7 +30,6 @@
"react-dom": "^18.0.0 || ^19.0.0"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*",
"@tanstack/react-query": "5.17.19",
"@types/cookie": "0.6.0",
"@types/uuid": "8.3.4",
+156 -156
View File
@@ -1,159 +1,159 @@
// This file is generated by yarn run build:icons
export type IconName =
| "activity"
| "arrow-down"
| "arrow-left"
| "arrow-right"
| "arrow-up-right"
| "arrow-up"
| "asterisk"
| "at-sign"
| "atom"
| "badge-check"
| "ban"
| "bell"
| "binary"
| "blocks"
| "bold"
| "book-open-check"
| "book-open"
| "book-user"
| "book"
| "bookmark"
| "building"
| "calendar-check-2"
| "calendar-days"
| "calendar-heart"
| "calendar-range"
| "calendar-search"
| "calendar-x-2"
| "calendar"
| "chart-bar"
| "chart-line"
| "check-check"
| "check"
| "chevron-down"
| "chevron-left"
| "chevron-right"
| "chevron-up"
| "chevrons-down-up"
| "chevrons-left"
| "chevrons-right"
| "chevrons-up-down"
| "circle-alert"
| "circle-arrow-up"
| "circle-check-big"
| "circle-check"
| "circle-help"
| "circle-plus"
| "circle-x"
| "circle"
| "clipboard-check"
| "clipboard"
| "clock"
| "code"
| "columns-3"
| "command"
| "contact"
| "copy"
| "corner-down-left"
| "corner-down-right"
| "credit-card"
| "disc"
| "dot"
| "download"
| "ellipsis-vertical"
| "ellipsis"
| "external-link"
| "eye-off"
| "eye"
| "file-down"
| "file-text"
| "file"
| "filter"
| "fingerprint"
| "flag"
| "folder"
| "gift"
| "git-merge"
| "github"
| "globe"
| "grid-3x3"
| "handshake"
| "info"
| "italic"
| "key"
| "layers"
| "layout-dashboard"
| "link-2"
| "link"
| "list-filter"
| "loader"
| "lock-open"
| "lock"
| "log-out"
| "mail-open"
| "mail"
| "map-pin"
| "map"
| "menu"
| "message-circle"
| "messages-square"
| "mic-off"
| "mic"
| "monitor"
| "moon"
| "paintbrush"
| "paperclip"
| "pause"
| "pencil"
| "phone-call"
| "phone-incoming"
| "phone-off"
| "phone-outgoing"
| "phone"
| "play"
| "plus"
| "refresh-ccw"
| "refresh-cw"
| "repeat"
| "rocket"
| "rotate-ccw"
| "rotate-cw"
| "search"
| "send"
| "settings"
| "share-2"
| "shield-check"
| "shield"
| "shuffle"
| "sliders-horizontal"
| "sliders-vertical"
| "smartphone"
| "sparkles"
| "split"
| "square-check"
| "square-pen"
| "star"
| "sun"
| "sunrise"
| "sunset"
| "tags"
| "terminal"
| "trash-2"
| "trash"
| "trello"
| "triangle-alert"
| "upload"
| "user-check"
| "user-plus"
| "user-x"
| "user"
| "users"
| "venetian-mask"
| "video"
| "waypoints"
| "webhook"
| "x"
| "zap";
| "activity"
| "arrow-down"
| "arrow-left"
| "arrow-right"
| "arrow-up-right"
| "arrow-up"
| "asterisk"
| "at-sign"
| "atom"
| "badge-check"
| "ban"
| "bell"
| "binary"
| "blocks"
| "bold"
| "book-open-check"
| "book-open"
| "book-user"
| "book"
| "bookmark"
| "building"
| "calendar-check-2"
| "calendar-days"
| "calendar-heart"
| "calendar-range"
| "calendar-search"
| "calendar-x-2"
| "calendar"
| "chart-bar"
| "chart-line"
| "check-check"
| "check"
| "chevron-down"
| "chevron-left"
| "chevron-right"
| "chevron-up"
| "chevrons-down-up"
| "chevrons-left"
| "chevrons-right"
| "chevrons-up-down"
| "circle-alert"
| "circle-arrow-up"
| "circle-check-big"
| "circle-check"
| "circle-help"
| "circle-plus"
| "circle-x"
| "circle"
| "clipboard-check"
| "clipboard"
| "clock"
| "code"
| "columns-3"
| "command"
| "contact"
| "copy"
| "corner-down-left"
| "corner-down-right"
| "credit-card"
| "disc"
| "dot"
| "download"
| "ellipsis-vertical"
| "ellipsis"
| "external-link"
| "eye-off"
| "eye"
| "file-down"
| "file-text"
| "file"
| "filter"
| "fingerprint"
| "flag"
| "folder"
| "gift"
| "git-merge"
| "github"
| "globe"
| "grid-3x3"
| "handshake"
| "info"
| "italic"
| "key"
| "layers"
| "layout-dashboard"
| "link-2"
| "link"
| "list-filter"
| "loader"
| "lock-open"
| "lock"
| "log-out"
| "mail-open"
| "mail"
| "map-pin"
| "map"
| "menu"
| "message-circle"
| "messages-square"
| "mic-off"
| "mic"
| "monitor"
| "moon"
| "paintbrush"
| "paperclip"
| "pause"
| "pencil"
| "phone-call"
| "phone-incoming"
| "phone-off"
| "phone-outgoing"
| "phone"
| "play"
| "plus"
| "refresh-ccw"
| "refresh-cw"
| "repeat"
| "rocket"
| "rotate-ccw"
| "rotate-cw"
| "search"
| "send"
| "settings"
| "share-2"
| "shield-check"
| "shield"
| "shuffle"
| "sliders-horizontal"
| "sliders-vertical"
| "smartphone"
| "sparkles"
| "split"
| "square-check"
| "square-pen"
| "star"
| "sun"
| "sunrise"
| "sunset"
| "tags"
| "terminal"
| "trash-2"
| "trash"
| "trello"
| "triangle-alert"
| "upload"
| "user-check"
| "user-plus"
| "user-x"
| "user"
| "users"
| "venetian-mask"
| "video"
| "waypoints"
| "webhook"
| "x"
| "zap";
+4 -4
View File
@@ -61,11 +61,11 @@
},
"license": "MIT",
"scripts": {
"lint": "eslint .",
"lint": "biome lint .",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"lint:fix": "eslint . --fix",
"lint:report": "eslint . --format json --output-file ../../lint-results/ui.json",
"lint:fix": "biome lint --write .",
"lint:report": "biome lint --reporter json . > ../../lint-results/ui.json",
"dx": "node ./scripts/build-icons.mjs",
"dev": "node ./scripts/build-icons.mjs",
"build": "node ./scripts/build-icons.mjs",
@@ -119,8 +119,8 @@
"react-dom": "^18.0.0 || ^19.0.0"
},
"devDependencies": {
"@biomejs/biome": "^2.3.8",
"@calcom/config": "workspace:*",
"@calcom/eslint-config": "workspace:*",
"@calcom/tsconfig": "workspace:*",
"@testing-library/user-event": "14.6.1",
"@types/react": "18.0.26",
+5 -1
View File
@@ -5,9 +5,13 @@ import glob from "fast-glob";
import fsExtra from "fs-extra";
import { parse } from "node-html-parser";
import * as path from "node:path";
import { createRequire } from "node:module";
import { copyIcons, removeTempDir } from "./generate-icons.mjs";
const require = createRequire(import.meta.url);
const biomeBin = require.resolve("@biomejs/biome/bin/biome");
const cwd = process.cwd();
const inputDir = path.join(cwd, "svg-icons");
const inputDirRelative = path.relative(cwd, inputDir);
@@ -118,7 +122,7 @@ async function writeIfChanged(filepath, newContent) {
const currentContent = await fsExtra.readFile(filepath, "utf8").catch(() => "");
if (currentContent === newContent) return false;
await fsExtra.writeFile(filepath, newContent, "utf8");
await $`prettier --write ${filepath} --ignore-unknown`;
await $`node ${biomeBin} format --write ${filepath}`;
return true;
}
+142 -2335
View File
File diff suppressed because it is too large Load Diff