← back to Homesonspec
initial scaffold: pnpm monorepo, Prisma schema (published + raw pipeline sides), migrations applied
1aad19ce354924680c02fb92dfdf9aee1a0a1c7e · 2026-07-22 11:16:50 -0700 · Steve Abrams
Files touched
A .env.exampleA .gitignoreA apps/admin/next.config.tsA apps/admin/package.jsonA apps/admin/postcss.config.mjsA apps/admin/src/app/globals.cssA apps/admin/tsconfig.jsonA apps/web/next.config.tsA apps/web/package.jsonA apps/web/postcss.config.mjsA apps/web/src/app/globals.cssA apps/web/tsconfig.jsonA apps/workers/package.jsonA apps/workers/tsconfig.jsonA collectors/common/package.jsonA collectors/common/tsconfig.jsonA collectors/meridian-homes/package.jsonA collectors/meridian-homes/tsconfig.jsonA package.jsonA packages/database/package.jsonA packages/database/prisma/migrations/20260722181638_init/migration.sqlA packages/database/prisma/migrations/20260722181700_trgm_search_index/migration.sqlA packages/database/prisma/migrations/migration_lock.tomlA packages/database/prisma/schema.prismaA packages/database/src/index.tsA packages/database/tsconfig.jsonA packages/schemas/package.jsonA packages/schemas/tsconfig.jsonA packages/search/package.jsonA packages/search/tsconfig.jsonA packages/shared-ui/package.jsonA packages/shared-ui/tsconfig.jsonA packages/shared/package.jsonA packages/shared/tsconfig.jsonA packages/source-registry/package.jsonA packages/source-registry/tsconfig.jsonA packages/validation/package.jsonA packages/validation/tsconfig.jsonA pnpm-lock.yamlA pnpm-workspace.yamlA tsconfig.base.json
Diff
commit 1aad19ce354924680c02fb92dfdf9aee1a0a1c7e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 22 11:16:50 2026 -0700
initial scaffold: pnpm monorepo, Prisma schema (published + raw pipeline sides), migrations applied
---
.env.example | 7 +
.gitignore | 16 +
apps/admin/next.config.ts | 18 +
apps/admin/package.json | 35 +
apps/admin/postcss.config.mjs | 1 +
apps/admin/src/app/globals.css | 1 +
apps/admin/tsconfig.json | 20 +
apps/web/next.config.ts | 18 +
apps/web/package.json | 35 +
apps/web/postcss.config.mjs | 1 +
apps/web/src/app/globals.css | 1 +
apps/web/tsconfig.json | 20 +
apps/workers/package.json | 22 +
apps/workers/tsconfig.json | 1 +
collectors/common/package.json | 11 +
collectors/common/tsconfig.json | 1 +
collectors/meridian-homes/package.json | 11 +
collectors/meridian-homes/tsconfig.json | 1 +
package.json | 22 +
packages/database/package.json | 19 +
.../migrations/20260722181638_init/migration.sql | 573 ++++
.../20260722181700_trgm_search_index/migration.sql | 5 +
.../database/prisma/migrations/migration_lock.toml | 3 +
packages/database/prisma/schema.prisma | 526 ++++
packages/database/src/index.ts | 15 +
packages/database/tsconfig.json | 1 +
packages/schemas/package.json | 11 +
packages/schemas/tsconfig.json | 1 +
packages/search/package.json | 11 +
packages/search/tsconfig.json | 1 +
packages/shared-ui/package.json | 12 +
packages/shared-ui/tsconfig.json | 1 +
packages/shared/package.json | 11 +
packages/shared/tsconfig.json | 1 +
packages/source-registry/package.json | 11 +
packages/source-registry/tsconfig.json | 1 +
packages/validation/package.json | 11 +
packages/validation/tsconfig.json | 1 +
pnpm-lock.yaml | 2850 ++++++++++++++++++++
pnpm-workspace.yaml | 10 +
tsconfig.base.json | 27 +
41 files changed, 4344 insertions(+)
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..9d771e7
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,7 @@
+# Copy to .env — never commit real values.
+DATABASE_URL="postgresql://macstudio3@localhost/spechomes?host=/tmp"
+DATABASE_URL_TEST="postgresql://macstudio3@localhost/spechomes_test?host=/tmp"
+# Admin app HTTP Basic Auth (user:pass)
+BASIC_AUTH="admin:REDACTED_ADMIN_PW"
+# Snapshot storage root (raw fetched bodies live on disk, not in PG)
+SNAPSHOT_DIR="./var/snapshots"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3d86005
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+node_modules/
+.env
+.env.*
+!.env.example
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
+var/snapshots/
+coverage/
+playwright-report/
+test-results/
+.turbo/
+*.tsbuildinfo
diff --git a/apps/admin/next.config.ts b/apps/admin/next.config.ts
new file mode 100644
index 0000000..c63dd4e
--- /dev/null
+++ b/apps/admin/next.config.ts
@@ -0,0 +1,18 @@
+import type { NextConfig } from "next";
+import { fileURLToPath } from "node:url";
+
+const nextConfig: NextConfig = {
+ // Pin the workspace root (a stray parent lockfile confuses Turbopack's inference).
+ turbopack: { root: fileURLToPath(new URL("../..", import.meta.url)) },
+ // Prisma client stays external so the query-engine binary resolves at runtime.
+ serverExternalPackages: ["@prisma/client", "pg-boss"],
+ transpilePackages: [
+ "@spechomes/database",
+ "@spechomes/schemas",
+ "@spechomes/search",
+ "@spechomes/shared",
+ "@spechomes/shared-ui",
+ ],
+};
+
+export default nextConfig;
diff --git a/apps/admin/package.json b/apps/admin/package.json
new file mode 100644
index 0000000..06f4a39
--- /dev/null
+++ b/apps/admin/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "@spechomes/admin",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev --port 3101",
+ "build": "next build",
+ "start": "next start --port 3101",
+ "test": "vitest run --passWithNoTests",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@spechomes/database": "workspace:*",
+ "@spechomes/schemas": "workspace:*",
+ "@spechomes/search": "workspace:*",
+ "@spechomes/shared": "workspace:*",
+ "@spechomes/shared-ui": "workspace:*",
+ "leaflet": "^1.9.4",
+ "react-leaflet": "^5.0.0",
+ "next": "16.2.10",
+ "react": "19.2.7",
+ "react-dom": "19.2.7",
+ "zod": "^3.24.1"
+ },
+ "devDependencies": {
+ "@tailwindcss/postcss": "^4.0.0",
+ "tailwindcss": "^4.0.0",
+ "@types/node": "^22.10.5",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "@types/leaflet": "^1.9.14",
+ "typescript": "^5.7.2",
+ "vitest": "^4.0.0"
+ }
+}
diff --git a/apps/admin/postcss.config.mjs b/apps/admin/postcss.config.mjs
new file mode 100644
index 0000000..a9b5c43
--- /dev/null
+++ b/apps/admin/postcss.config.mjs
@@ -0,0 +1 @@
+export default { plugins: { "@tailwindcss/postcss": {} } };
diff --git a/apps/admin/src/app/globals.css b/apps/admin/src/app/globals.css
new file mode 100644
index 0000000..f1d8c73
--- /dev/null
+++ b/apps/admin/src/app/globals.css
@@ -0,0 +1 @@
+@import "tailwindcss";
diff --git a/apps/admin/tsconfig.json b/apps/admin/tsconfig.json
new file mode 100644
index 0000000..b8eeb84
--- /dev/null
+++ b/apps/admin/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "noEmit": true,
+ "allowJs": true,
+ "incremental": true,
+ "module": "esnext",
+ "plugins": [{ "name": "next" }],
+ "paths": {
+ "@/*": ["./src/*"],
+ "@spechomes/database": ["../../packages/database/src/index.ts"],
+ "@spechomes/schemas": ["../../packages/schemas/src/index.ts"],
+ "@spechomes/search": ["../../packages/search/src/index.ts"],
+ "@spechomes/shared": ["../../packages/shared/src/index.ts"],
+ "@spechomes/shared-ui": ["../../packages/shared-ui/src/index.ts"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts
new file mode 100644
index 0000000..c63dd4e
--- /dev/null
+++ b/apps/web/next.config.ts
@@ -0,0 +1,18 @@
+import type { NextConfig } from "next";
+import { fileURLToPath } from "node:url";
+
+const nextConfig: NextConfig = {
+ // Pin the workspace root (a stray parent lockfile confuses Turbopack's inference).
+ turbopack: { root: fileURLToPath(new URL("../..", import.meta.url)) },
+ // Prisma client stays external so the query-engine binary resolves at runtime.
+ serverExternalPackages: ["@prisma/client", "pg-boss"],
+ transpilePackages: [
+ "@spechomes/database",
+ "@spechomes/schemas",
+ "@spechomes/search",
+ "@spechomes/shared",
+ "@spechomes/shared-ui",
+ ],
+};
+
+export default nextConfig;
diff --git a/apps/web/package.json b/apps/web/package.json
new file mode 100644
index 0000000..478bb7e
--- /dev/null
+++ b/apps/web/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "@spechomes/web",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev --port 3100",
+ "build": "next build",
+ "start": "next start --port 3100",
+ "test": "vitest run --passWithNoTests",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@spechomes/database": "workspace:*",
+ "@spechomes/schemas": "workspace:*",
+ "@spechomes/search": "workspace:*",
+ "@spechomes/shared": "workspace:*",
+ "@spechomes/shared-ui": "workspace:*",
+ "leaflet": "^1.9.4",
+ "react-leaflet": "^5.0.0",
+ "next": "16.2.10",
+ "react": "19.2.7",
+ "react-dom": "19.2.7",
+ "zod": "^3.24.1"
+ },
+ "devDependencies": {
+ "@tailwindcss/postcss": "^4.0.0",
+ "tailwindcss": "^4.0.0",
+ "@types/node": "^22.10.5",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "@types/leaflet": "^1.9.14",
+ "typescript": "^5.7.2",
+ "vitest": "^4.0.0"
+ }
+}
diff --git a/apps/web/postcss.config.mjs b/apps/web/postcss.config.mjs
new file mode 100644
index 0000000..a9b5c43
--- /dev/null
+++ b/apps/web/postcss.config.mjs
@@ -0,0 +1 @@
+export default { plugins: { "@tailwindcss/postcss": {} } };
diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css
new file mode 100644
index 0000000..f1d8c73
--- /dev/null
+++ b/apps/web/src/app/globals.css
@@ -0,0 +1 @@
+@import "tailwindcss";
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
new file mode 100644
index 0000000..b8eeb84
--- /dev/null
+++ b/apps/web/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "noEmit": true,
+ "allowJs": true,
+ "incremental": true,
+ "module": "esnext",
+ "plugins": [{ "name": "next" }],
+ "paths": {
+ "@/*": ["./src/*"],
+ "@spechomes/database": ["../../packages/database/src/index.ts"],
+ "@spechomes/schemas": ["../../packages/schemas/src/index.ts"],
+ "@spechomes/search": ["../../packages/search/src/index.ts"],
+ "@spechomes/shared": ["../../packages/shared/src/index.ts"],
+ "@spechomes/shared-ui": ["../../packages/shared-ui/src/index.ts"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/apps/workers/package.json b/apps/workers/package.json
new file mode 100644
index 0000000..5ed604b
--- /dev/null
+++ b/apps/workers/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@spechomes/workers",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "pipeline": "tsx src/cli.ts",
+ "start": "tsx src/index.ts",
+ "test": "vitest run --passWithNoTests",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@spechomes/database": "workspace:*",
+ "@spechomes/schemas": "workspace:*",
+ "@spechomes/validation": "workspace:*",
+ "@spechomes/shared": "workspace:*",
+ "@spechomes/collectors-common": "workspace:*",
+ "@spechomes/collector-meridian-homes": "workspace:*",
+ "pg-boss": "^10.1.5"
+ },
+ "devDependencies": { "tsx": "^4.19.2", "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/apps/workers/tsconfig.json b/apps/workers/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/apps/workers/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/collectors/common/package.json b/collectors/common/package.json
new file mode 100644
index 0000000..d46211d
--- /dev/null
+++ b/collectors/common/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@spechomes/collectors-common",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "@spechomes/schemas": "workspace:*", "@spechomes/shared": "workspace:*", "node-html-parser": "^7.0.1" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/collectors/common/tsconfig.json b/collectors/common/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/collectors/common/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/collectors/meridian-homes/package.json b/collectors/meridian-homes/package.json
new file mode 100644
index 0000000..4ebde17
--- /dev/null
+++ b/collectors/meridian-homes/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@spechomes/collector-meridian-homes",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "@spechomes/collectors-common": "workspace:*", "@spechomes/schemas": "workspace:*", "@spechomes/shared": "workspace:*", "node-html-parser": "^7.0.1" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/collectors/meridian-homes/tsconfig.json b/collectors/meridian-homes/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/collectors/meridian-homes/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..c8b3dae
--- /dev/null
+++ b/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "spechomes",
+ "version": "0.1.0",
+ "private": true,
+ "description": "SpecHomes.com — nationwide search and comparison platform for newly constructed homes. Evidence-backed, verification-labeled inventory.",
+ "scripts": {
+ "dev:web": "pnpm --filter @spechomes/web dev",
+ "dev:admin": "pnpm --filter @spechomes/admin dev",
+ "build": "pnpm -r build",
+ "test": "pnpm -r --no-bail test",
+ "typecheck": "pnpm -r typecheck",
+ "db:migrate": "pnpm --filter @spechomes/database db:migrate",
+ "db:seed": "pnpm --filter @spechomes/database db:seed",
+ "pipeline": "pnpm --filter @spechomes/workers pipeline",
+ "e2e": "playwright test"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.49.1",
+ "typescript": "^5.7.2"
+ },
+ "engines": { "node": ">=22" }
+}
diff --git a/packages/database/package.json b/packages/database/package.json
new file mode 100644
index 0000000..f596b07
--- /dev/null
+++ b/packages/database/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "@spechomes/database",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "prisma": { "seed": "tsx prisma/seed.ts" },
+ "scripts": {
+ "db:generate": "prisma generate",
+ "db:migrate": "prisma migrate dev",
+ "db:deploy": "prisma migrate deploy",
+ "db:seed": "tsx prisma/seed.ts",
+ "test": "vitest run --passWithNoTests",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": { "@prisma/client": "6.19.3" },
+ "devDependencies": { "prisma": "6.19.3", "tsx": "^4.19.2", "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/packages/database/prisma/migrations/20260722181638_init/migration.sql b/packages/database/prisma/migrations/20260722181638_init/migration.sql
new file mode 100644
index 0000000..95f0591
--- /dev/null
+++ b/packages/database/prisma/migrations/20260722181638_init/migration.sql
@@ -0,0 +1,573 @@
+-- CreateEnum
+CREATE TYPE "CommunityStatus" AS ENUM ('ACTIVE', 'COMING_SOON', 'SOLD_OUT', 'CLOSED');
+
+-- CreateEnum
+CREATE TYPE "HomeType" AS ENUM ('SINGLE_FAMILY', 'TOWNHOME', 'CONDO', 'DUPLEX', 'OTHER');
+
+-- CreateEnum
+CREATE TYPE "ConstructionStatus" AS ENUM ('PLANNED', 'UNDER_CONSTRUCTION', 'MOVE_IN_READY');
+
+-- CreateEnum
+CREATE TYPE "PublishStatus" AS ENUM ('PUBLISHED', 'INACTIVE');
+
+-- CreateEnum
+CREATE TYPE "Freshness" AS ENUM ('FRESH', 'AGING', 'REVIEW_REQUIRED', 'STALE', 'INACTIVE');
+
+-- CreateEnum
+CREATE TYPE "VerificationLabel" AS ENUM ('VERIFIED_FROM_BUILDER', 'BUILDER_WEBSITE', 'BUILDER_SUBMITTED', 'NEEDS_REVERIFICATION', 'NO_LONGER_AVAILABLE', 'DEMONSTRATION');
+
+-- CreateEnum
+CREATE TYPE "IncentiveScope" AS ENUM ('BUILDER', 'COMMUNITY', 'HOME');
+
+-- CreateEnum
+CREATE TYPE "CollectionMethod" AS ENUM ('FEED', 'CRAWL', 'MANUAL', 'FIXTURE', 'SYNTHETIC');
+
+-- CreateEnum
+CREATE TYPE "MediaRights" AS ENUM ('NONE', 'LINK_ONLY', 'LICENSED');
+
+-- CreateEnum
+CREATE TYPE "SourceHealth" AS ENUM ('HEALTHY', 'DEGRADED', 'FAILING', 'PAUSED');
+
+-- CreateEnum
+CREATE TYPE "EntityType" AS ENUM ('BUILDER', 'COMMUNITY', 'FLOOR_PLAN', 'INVENTORY_HOME', 'INCENTIVE', 'SALES_OFFICE', 'LOT');
+
+-- CreateEnum
+CREATE TYPE "StagedStatus" AS ENUM ('EXTRACTED', 'VALIDATED', 'NEEDS_REVIEW', 'APPROVED', 'REJECTED', 'PUBLISHED');
+
+-- CreateEnum
+CREATE TYPE "ReviewStatus" AS ENUM ('OPEN', 'APPROVED', 'REJECTED');
+
+-- CreateTable
+CREATE TABLE "Builder" (
+ "id" TEXT NOT NULL,
+ "slug" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "legalName" TEXT,
+ "websiteUrl" TEXT,
+ "logoRightsStatus" TEXT,
+ "coverageArea" TEXT,
+ "contactEmail" TEXT,
+ "contactPhone" TEXT,
+ "partnershipStatus" TEXT,
+ "isDemo" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Builder_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Division" (
+ "id" TEXT NOT NULL,
+ "builderId" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "region" TEXT,
+ "states" TEXT[],
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "Division_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Community" (
+ "id" TEXT NOT NULL,
+ "builderId" TEXT NOT NULL,
+ "divisionId" TEXT,
+ "slug" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "description" TEXT,
+ "street" TEXT,
+ "city" TEXT NOT NULL,
+ "state" TEXT NOT NULL,
+ "zip" TEXT NOT NULL,
+ "county" TEXT,
+ "metro" TEXT,
+ "lat" DECIMAL(9,6),
+ "lon" DECIMAL(9,6),
+ "status" "CommunityStatus" NOT NULL DEFAULT 'ACTIVE',
+ "hoaFeeMonthly" DECIMAL(8,2),
+ "hoaRequired" BOOLEAN,
+ "schoolDistrict" TEXT,
+ "ageRestricted" BOOLEAN NOT NULL DEFAULT false,
+ "amenities" JSONB,
+ "searchText" TEXT,
+ "priceMin" DECIMAL(12,2),
+ "priceMax" DECIMAL(12,2),
+ "sourceUrl" TEXT,
+ "isDemo" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Community_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "FloorPlan" (
+ "id" TEXT NOT NULL,
+ "communityId" TEXT NOT NULL,
+ "builderId" TEXT NOT NULL,
+ "builderPlanId" TEXT,
+ "name" TEXT NOT NULL,
+ "beds" INTEGER,
+ "bedsMax" INTEGER,
+ "bathsFull" INTEGER,
+ "bathsHalf" INTEGER,
+ "sqft" INTEGER,
+ "sqftMax" INTEGER,
+ "stories" INTEGER,
+ "garageSpaces" INTEGER,
+ "basePrice" DECIMAL(12,2),
+ "homeType" "HomeType" NOT NULL DEFAULT 'SINGLE_FAMILY',
+ "planMediaRights" TEXT,
+ "sourceUrl" TEXT,
+ "isDemo" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "FloorPlan_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "InventoryHome" (
+ "id" TEXT NOT NULL,
+ "canonicalKey" TEXT NOT NULL,
+ "communityId" TEXT NOT NULL,
+ "builderId" TEXT NOT NULL,
+ "floorPlanId" TEXT,
+ "builderInventoryId" TEXT,
+ "street" TEXT,
+ "city" TEXT NOT NULL,
+ "state" TEXT NOT NULL,
+ "zip" TEXT NOT NULL,
+ "normalizedAddress" TEXT,
+ "lotNumber" TEXT,
+ "lat" DECIMAL(9,6),
+ "lon" DECIMAL(9,6),
+ "price" DECIMAL(12,2),
+ "previousPrice" DECIMAL(12,2),
+ "beds" INTEGER,
+ "bathsTotal" DECIMAL(3,1),
+ "sqft" INTEGER,
+ "stories" INTEGER,
+ "garageSpaces" INTEGER,
+ "homeType" "HomeType" NOT NULL DEFAULT 'SINGLE_FAMILY',
+ "constructionStatus" "ConstructionStatus" NOT NULL DEFAULT 'UNDER_CONSTRUCTION',
+ "estCompletionDate" TIMESTAMP(3),
+ "availabilityStatus" TEXT,
+ "status" "PublishStatus" NOT NULL DEFAULT 'PUBLISHED',
+ "freshness" "Freshness" NOT NULL DEFAULT 'FRESH',
+ "verificationLabel" "VerificationLabel" NOT NULL,
+ "lastVerifiedAt" TIMESTAMP(3),
+ "sourceId" TEXT,
+ "sourceUrl" TEXT,
+ "sourceUpdatedAt" TIMESTAMP(3),
+ "publishedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "isDemo" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "InventoryHome_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Lot" (
+ "id" TEXT NOT NULL,
+ "communityId" TEXT NOT NULL,
+ "lotNumber" TEXT NOT NULL,
+ "street" TEXT,
+ "sizeSqft" INTEGER,
+ "status" TEXT,
+ "price" DECIMAL(12,2),
+ "isDemo" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "Lot_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Incentive" (
+ "id" TEXT NOT NULL,
+ "scope" "IncentiveScope" NOT NULL,
+ "builderId" TEXT,
+ "communityId" TEXT,
+ "homeId" TEXT,
+ "title" TEXT NOT NULL,
+ "description" TEXT,
+ "valueUsd" DECIMAL(12,2),
+ "expiresAt" TIMESTAMP(3),
+ "evergreenLabel" TEXT,
+ "sourceId" TEXT,
+ "sourceUrl" TEXT,
+ "isDemo" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Incentive_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "SalesOffice" (
+ "id" TEXT NOT NULL,
+ "communityId" TEXT NOT NULL,
+ "street" TEXT,
+ "city" TEXT,
+ "state" TEXT,
+ "zip" TEXT,
+ "phone" TEXT,
+ "hours" JSONB,
+ "isDemo" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "SalesOffice_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Lead" (
+ "id" TEXT NOT NULL,
+ "homeId" TEXT,
+ "communityId" TEXT,
+ "name" TEXT NOT NULL,
+ "email" TEXT NOT NULL,
+ "phone" TEXT,
+ "message" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "Lead_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "SavedSearch" (
+ "id" TEXT NOT NULL,
+ "email" TEXT NOT NULL,
+ "criteria" JSONB NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "SavedSearch_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Alert" (
+ "id" TEXT NOT NULL,
+ "email" TEXT NOT NULL,
+ "homeId" TEXT,
+ "kind" TEXT NOT NULL,
+ "active" BOOLEAN NOT NULL DEFAULT true,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "Alert_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "SourceRegistry" (
+ "id" TEXT NOT NULL,
+ "key" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "builderId" TEXT,
+ "baseUrl" TEXT,
+ "collectionMethod" "CollectionMethod" NOT NULL,
+ "termsUrl" TEXT,
+ "permissions" JSONB,
+ "attribution" TEXT,
+ "mediaRights" "MediaRights" NOT NULL DEFAULT 'NONE',
+ "rateLimitRpm" INTEGER,
+ "freshIntervalHours" INTEGER NOT NULL DEFAULT 24,
+ "agingIntervalHours" INTEGER NOT NULL DEFAULT 72,
+ "health" "SourceHealth" NOT NULL DEFAULT 'HEALTHY',
+ "active" BOOLEAN NOT NULL DEFAULT true,
+ "notes" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "SourceRegistry_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "RawSnapshot" (
+ "id" TEXT NOT NULL,
+ "sourceId" TEXT NOT NULL,
+ "url" TEXT NOT NULL,
+ "retrievedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "contentHash" TEXT NOT NULL,
+ "storagePath" TEXT NOT NULL,
+ "contentType" TEXT,
+ "httpStatus" INTEGER,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "RawSnapshot_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "StagedRecord" (
+ "id" TEXT NOT NULL,
+ "sourceId" TEXT NOT NULL,
+ "snapshotId" TEXT,
+ "entityType" "EntityType" NOT NULL,
+ "canonicalKey" TEXT NOT NULL,
+ "payload" JSONB NOT NULL,
+ "extractorVersion" TEXT NOT NULL,
+ "status" "StagedStatus" NOT NULL DEFAULT 'EXTRACTED',
+ "publishedEntityId" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "StagedRecord_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "SourceEvidence" (
+ "id" TEXT NOT NULL,
+ "stagedRecordId" TEXT,
+ "entityType" "EntityType",
+ "entityId" TEXT,
+ "field" TEXT NOT NULL,
+ "sourceUrl" TEXT NOT NULL,
+ "retrievedAt" TIMESTAMP(3) NOT NULL,
+ "contentHash" TEXT,
+ "extractorVersion" TEXT NOT NULL,
+ "rawValue" TEXT,
+ "normalizedValue" TEXT,
+ "evidenceText" TEXT,
+ "confidence" DOUBLE PRECISION NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "SourceEvidence_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "ValidationEvent" (
+ "id" TEXT NOT NULL,
+ "stagedRecordId" TEXT NOT NULL,
+ "ruleId" TEXT NOT NULL,
+ "severity" TEXT NOT NULL,
+ "passed" BOOLEAN NOT NULL,
+ "message" TEXT,
+ "details" JSONB,
+ "validatorVersion" TEXT NOT NULL,
+ "runAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "ValidationEvent_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "ChangeEvent" (
+ "id" TEXT NOT NULL,
+ "entityType" "EntityType" NOT NULL,
+ "entityId" TEXT NOT NULL,
+ "field" TEXT NOT NULL,
+ "oldValue" TEXT,
+ "newValue" TEXT,
+ "sourceId" TEXT,
+ "requiresReview" BOOLEAN NOT NULL DEFAULT false,
+ "detectedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "ChangeEvent_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "ReviewItem" (
+ "id" TEXT NOT NULL,
+ "stagedRecordId" TEXT,
+ "changeEventId" TEXT,
+ "reason" TEXT NOT NULL,
+ "status" "ReviewStatus" NOT NULL DEFAULT 'OPEN',
+ "reviewer" TEXT,
+ "resolutionNote" TEXT,
+ "resolvedAt" TIMESTAMP(3),
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "ReviewItem_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "CorrectionReport" (
+ "id" TEXT NOT NULL,
+ "entityType" "EntityType" NOT NULL,
+ "entityId" TEXT NOT NULL,
+ "field" TEXT,
+ "message" TEXT NOT NULL,
+ "reporterEmail" TEXT,
+ "status" "ReviewStatus" NOT NULL DEFAULT 'OPEN',
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "CorrectionReport_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Builder_slug_key" ON "Builder"("slug");
+
+-- CreateIndex
+CREATE INDEX "Division_builderId_idx" ON "Division"("builderId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Community_slug_key" ON "Community"("slug");
+
+-- CreateIndex
+CREATE INDEX "Community_state_city_idx" ON "Community"("state", "city");
+
+-- CreateIndex
+CREATE INDEX "Community_zip_idx" ON "Community"("zip");
+
+-- CreateIndex
+CREATE INDEX "Community_lat_idx" ON "Community"("lat");
+
+-- CreateIndex
+CREATE INDEX "Community_lon_idx" ON "Community"("lon");
+
+-- CreateIndex
+CREATE INDEX "FloorPlan_communityId_idx" ON "FloorPlan"("communityId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "InventoryHome_canonicalKey_key" ON "InventoryHome"("canonicalKey");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_lat_idx" ON "InventoryHome"("lat");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_lon_idx" ON "InventoryHome"("lon");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_price_idx" ON "InventoryHome"("price");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_beds_idx" ON "InventoryHome"("beds");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_sqft_idx" ON "InventoryHome"("sqft");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_status_freshness_idx" ON "InventoryHome"("status", "freshness");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_communityId_idx" ON "InventoryHome"("communityId");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_builderId_idx" ON "InventoryHome"("builderId");
+
+-- CreateIndex
+CREATE INDEX "InventoryHome_constructionStatus_idx" ON "InventoryHome"("constructionStatus");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Lot_communityId_lotNumber_key" ON "Lot"("communityId", "lotNumber");
+
+-- CreateIndex
+CREATE INDEX "Incentive_communityId_idx" ON "Incentive"("communityId");
+
+-- CreateIndex
+CREATE INDEX "Incentive_homeId_idx" ON "Incentive"("homeId");
+
+-- CreateIndex
+CREATE INDEX "Incentive_expiresAt_idx" ON "Incentive"("expiresAt");
+
+-- CreateIndex
+CREATE INDEX "SalesOffice_communityId_idx" ON "SalesOffice"("communityId");
+
+-- CreateIndex
+CREATE INDEX "Lead_createdAt_idx" ON "Lead"("createdAt");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "SourceRegistry_key_key" ON "SourceRegistry"("key");
+
+-- CreateIndex
+CREATE INDEX "RawSnapshot_sourceId_retrievedAt_idx" ON "RawSnapshot"("sourceId", "retrievedAt");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "RawSnapshot_sourceId_contentHash_key" ON "RawSnapshot"("sourceId", "contentHash");
+
+-- CreateIndex
+CREATE INDEX "StagedRecord_status_idx" ON "StagedRecord"("status");
+
+-- CreateIndex
+CREATE INDEX "StagedRecord_canonicalKey_idx" ON "StagedRecord"("canonicalKey");
+
+-- CreateIndex
+CREATE INDEX "SourceEvidence_entityType_entityId_idx" ON "SourceEvidence"("entityType", "entityId");
+
+-- CreateIndex
+CREATE INDEX "SourceEvidence_stagedRecordId_idx" ON "SourceEvidence"("stagedRecordId");
+
+-- CreateIndex
+CREATE INDEX "ValidationEvent_stagedRecordId_idx" ON "ValidationEvent"("stagedRecordId");
+
+-- CreateIndex
+CREATE INDEX "ValidationEvent_ruleId_passed_idx" ON "ValidationEvent"("ruleId", "passed");
+
+-- CreateIndex
+CREATE INDEX "ChangeEvent_entityType_entityId_idx" ON "ChangeEvent"("entityType", "entityId");
+
+-- CreateIndex
+CREATE INDEX "ChangeEvent_detectedAt_idx" ON "ChangeEvent"("detectedAt");
+
+-- CreateIndex
+CREATE INDEX "ReviewItem_status_idx" ON "ReviewItem"("status");
+
+-- CreateIndex
+CREATE INDEX "ReviewItem_createdAt_idx" ON "ReviewItem"("createdAt");
+
+-- CreateIndex
+CREATE INDEX "CorrectionReport_status_idx" ON "CorrectionReport"("status");
+
+-- AddForeignKey
+ALTER TABLE "Division" ADD CONSTRAINT "Division_builderId_fkey" FOREIGN KEY ("builderId") REFERENCES "Builder"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Community" ADD CONSTRAINT "Community_builderId_fkey" FOREIGN KEY ("builderId") REFERENCES "Builder"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Community" ADD CONSTRAINT "Community_divisionId_fkey" FOREIGN KEY ("divisionId") REFERENCES "Division"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "FloorPlan" ADD CONSTRAINT "FloorPlan_communityId_fkey" FOREIGN KEY ("communityId") REFERENCES "Community"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "FloorPlan" ADD CONSTRAINT "FloorPlan_builderId_fkey" FOREIGN KEY ("builderId") REFERENCES "Builder"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "InventoryHome" ADD CONSTRAINT "InventoryHome_communityId_fkey" FOREIGN KEY ("communityId") REFERENCES "Community"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "InventoryHome" ADD CONSTRAINT "InventoryHome_builderId_fkey" FOREIGN KEY ("builderId") REFERENCES "Builder"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "InventoryHome" ADD CONSTRAINT "InventoryHome_floorPlanId_fkey" FOREIGN KEY ("floorPlanId") REFERENCES "FloorPlan"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "InventoryHome" ADD CONSTRAINT "InventoryHome_sourceId_fkey" FOREIGN KEY ("sourceId") REFERENCES "SourceRegistry"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Lot" ADD CONSTRAINT "Lot_communityId_fkey" FOREIGN KEY ("communityId") REFERENCES "Community"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Incentive" ADD CONSTRAINT "Incentive_builderId_fkey" FOREIGN KEY ("builderId") REFERENCES "Builder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Incentive" ADD CONSTRAINT "Incentive_communityId_fkey" FOREIGN KEY ("communityId") REFERENCES "Community"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Incentive" ADD CONSTRAINT "Incentive_homeId_fkey" FOREIGN KEY ("homeId") REFERENCES "InventoryHome"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "SalesOffice" ADD CONSTRAINT "SalesOffice_communityId_fkey" FOREIGN KEY ("communityId") REFERENCES "Community"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Lead" ADD CONSTRAINT "Lead_homeId_fkey" FOREIGN KEY ("homeId") REFERENCES "InventoryHome"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "SourceRegistry" ADD CONSTRAINT "SourceRegistry_builderId_fkey" FOREIGN KEY ("builderId") REFERENCES "Builder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "RawSnapshot" ADD CONSTRAINT "RawSnapshot_sourceId_fkey" FOREIGN KEY ("sourceId") REFERENCES "SourceRegistry"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "StagedRecord" ADD CONSTRAINT "StagedRecord_sourceId_fkey" FOREIGN KEY ("sourceId") REFERENCES "SourceRegistry"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "StagedRecord" ADD CONSTRAINT "StagedRecord_snapshotId_fkey" FOREIGN KEY ("snapshotId") REFERENCES "RawSnapshot"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "SourceEvidence" ADD CONSTRAINT "SourceEvidence_stagedRecordId_fkey" FOREIGN KEY ("stagedRecordId") REFERENCES "StagedRecord"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "ValidationEvent" ADD CONSTRAINT "ValidationEvent_stagedRecordId_fkey" FOREIGN KEY ("stagedRecordId") REFERENCES "StagedRecord"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "ReviewItem" ADD CONSTRAINT "ReviewItem_stagedRecordId_fkey" FOREIGN KEY ("stagedRecordId") REFERENCES "StagedRecord"("id") ON DELETE SET NULL ON UPDATE CASCADE;
diff --git a/packages/database/prisma/migrations/20260722181700_trgm_search_index/migration.sql b/packages/database/prisma/migrations/20260722181700_trgm_search_index/migration.sql
new file mode 100644
index 0000000..072a189
--- /dev/null
+++ b/packages/database/prisma/migrations/20260722181700_trgm_search_index/migration.sql
@@ -0,0 +1,5 @@
+-- pg_trgm GIN index for fuzzy location search on Community.searchText.
+-- The extension itself is created at DB provision time (createdb + CREATE EXTENSION).
+CREATE EXTENSION IF NOT EXISTS pg_trgm;
+CREATE INDEX IF NOT EXISTS "Community_searchText_trgm_idx"
+ ON "Community" USING GIN ("searchText" gin_trgm_ops);
diff --git a/packages/database/prisma/migrations/migration_lock.toml b/packages/database/prisma/migrations/migration_lock.toml
new file mode 100644
index 0000000..044d57c
--- /dev/null
+++ b/packages/database/prisma/migrations/migration_lock.toml
@@ -0,0 +1,3 @@
+# Please do not edit this file manually
+# It should be added in your version-control system (e.g., Git)
+provider = "postgresql"
diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma
new file mode 100644
index 0000000..d4f50eb
--- /dev/null
+++ b/packages/database/prisma/schema.prisma
@@ -0,0 +1,526 @@
+// SpecHomes data model.
+//
+// Two strictly separated sides:
+// PUBLISHED side — consumer-facing tables. Only the publish pipeline stage
+// writes here; collectors and extractors never do.
+// RAW/PIPELINE side — source registry, snapshots, staged records, evidence,
+// validation events, review queue. Everything upstream of publish.
+//
+// Every published fact must be traceable to SourceEvidence rows. Missing
+// values stay null — they are never inferred.
+
+generator client {
+ provider = "prisma-client-js"
+}
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+
+// ───────────────────────── PUBLISHED SIDE ─────────────────────────
+
+model Builder {
+ id String @id @default(cuid())
+ slug String @unique
+ name String
+ legalName String?
+ websiteUrl String?
+ logoRightsStatus String? // e.g. "none", "licensed", "builder-provided"
+ coverageArea String?
+ contactEmail String?
+ contactPhone String?
+ partnershipStatus String? // never implies sponsorship without a commercial relationship
+ isDemo Boolean @default(false)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ divisions Division[]
+ communities Community[]
+ floorPlans FloorPlan[]
+ homes InventoryHome[]
+ incentives Incentive[]
+ sources SourceRegistry[]
+}
+
+model Division {
+ id String @id @default(cuid())
+ builderId String
+ name String
+ region String?
+ states String[]
+ createdAt DateTime @default(now())
+
+ builder Builder @relation(fields: [builderId], references: [id])
+ communities Community[]
+
+ @@index([builderId])
+}
+
+model Community {
+ id String @id @default(cuid())
+ builderId String
+ divisionId String?
+ slug String @unique
+ name String
+ description String? // only with confirmed media/text rights
+ street String?
+ city String
+ state String
+ zip String
+ county String?
+ metro String?
+ lat Decimal? @db.Decimal(9, 6)
+ lon Decimal? @db.Decimal(9, 6)
+ status CommunityStatus @default(ACTIVE)
+ hoaFeeMonthly Decimal? @db.Decimal(8, 2)
+ hoaRequired Boolean?
+ schoolDistrict String? // objective district name only — no subjective ratings
+ ageRestricted Boolean @default(false)
+ amenities Json?
+ searchText String? // app-maintained: "name city state zip metro county" for trgm
+ priceMin Decimal? @db.Decimal(12, 2) // cached rollup from active homes
+ priceMax Decimal? @db.Decimal(12, 2)
+ sourceUrl String?
+ isDemo Boolean @default(false)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ builder Builder @relation(fields: [builderId], references: [id])
+ division Division? @relation(fields: [divisionId], references: [id])
+ floorPlans FloorPlan[]
+ homes InventoryHome[]
+ lots Lot[]
+ incentives Incentive[]
+ salesOffices SalesOffice[]
+
+ @@index([state, city])
+ @@index([zip])
+ @@index([lat])
+ @@index([lon])
+}
+
+enum CommunityStatus {
+ ACTIVE
+ COMING_SOON
+ SOLD_OUT
+ CLOSED
+}
+
+enum HomeType {
+ SINGLE_FAMILY
+ TOWNHOME
+ CONDO
+ DUPLEX
+ OTHER
+}
+
+model FloorPlan {
+ id String @id @default(cuid())
+ communityId String
+ builderId String
+ builderPlanId String?
+ name String
+ beds Int?
+ bedsMax Int?
+ bathsFull Int?
+ bathsHalf Int?
+ sqft Int?
+ sqftMax Int?
+ stories Int?
+ garageSpaces Int?
+ basePrice Decimal? @db.Decimal(12, 2)
+ homeType HomeType @default(SINGLE_FAMILY)
+ planMediaRights String? // registry-confirmed rights before any media renders
+ sourceUrl String?
+ isDemo Boolean @default(false)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ community Community @relation(fields: [communityId], references: [id])
+ builder Builder @relation(fields: [builderId], references: [id])
+ homes InventoryHome[]
+
+ @@index([communityId])
+}
+
+enum ConstructionStatus {
+ PLANNED
+ UNDER_CONSTRUCTION
+ MOVE_IN_READY
+}
+
+enum PublishStatus {
+ PUBLISHED
+ INACTIVE
+}
+
+enum Freshness {
+ FRESH
+ AGING
+ REVIEW_REQUIRED
+ STALE
+ INACTIVE
+}
+
+enum VerificationLabel {
+ VERIFIED_FROM_BUILDER // direct feed / partnership
+ BUILDER_WEBSITE // verified from builder website
+ BUILDER_SUBMITTED
+ NEEDS_REVERIFICATION
+ NO_LONGER_AVAILABLE
+ DEMONSTRATION // synthetic demo inventory — never a production claim
+}
+
+model InventoryHome {
+ id String @id @default(cuid())
+ canonicalKey String @unique // sha256(builder|community|addr|lot|invId|lat5|lon5|plan)
+ communityId String
+ builderId String
+ floorPlanId String?
+ builderInventoryId String?
+ street String?
+ city String
+ state String
+ zip String
+ normalizedAddress String?
+ lotNumber String?
+ lat Decimal? @db.Decimal(9, 6)
+ lon Decimal? @db.Decimal(9, 6)
+ price Decimal? @db.Decimal(12, 2) // null when source omits — never guessed
+ previousPrice Decimal? @db.Decimal(12, 2)
+ beds Int?
+ bathsTotal Decimal? @db.Decimal(3, 1)
+ sqft Int?
+ stories Int?
+ garageSpaces Int?
+ homeType HomeType @default(SINGLE_FAMILY)
+ constructionStatus ConstructionStatus @default(UNDER_CONSTRUCTION)
+ estCompletionDate DateTime?
+ availabilityStatus String?
+ status PublishStatus @default(PUBLISHED)
+ freshness Freshness @default(FRESH)
+ verificationLabel VerificationLabel
+ lastVerifiedAt DateTime?
+ sourceId String?
+ sourceUrl String?
+ sourceUpdatedAt DateTime?
+ publishedAt DateTime @default(now())
+ isDemo Boolean @default(false)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ community Community @relation(fields: [communityId], references: [id])
+ builder Builder @relation(fields: [builderId], references: [id])
+ floorPlan FloorPlan? @relation(fields: [floorPlanId], references: [id])
+ source SourceRegistry? @relation(fields: [sourceId], references: [id])
+ incentives Incentive[]
+ leads Lead[]
+
+ @@index([lat])
+ @@index([lon])
+ @@index([price])
+ @@index([beds])
+ @@index([sqft])
+ @@index([status, freshness])
+ @@index([communityId])
+ @@index([builderId])
+ @@index([constructionStatus])
+}
+
+model Lot {
+ id String @id @default(cuid())
+ communityId String
+ lotNumber String
+ street String?
+ sizeSqft Int?
+ status String? // available / reserved / sold
+ price Decimal? @db.Decimal(12, 2)
+ isDemo Boolean @default(false)
+ createdAt DateTime @default(now())
+
+ community Community @relation(fields: [communityId], references: [id])
+
+ @@unique([communityId, lotNumber])
+}
+
+enum IncentiveScope {
+ BUILDER
+ COMMUNITY
+ HOME
+}
+
+model Incentive {
+ id String @id @default(cuid())
+ scope IncentiveScope
+ builderId String?
+ communityId String?
+ homeId String?
+ title String
+ description String?
+ valueUsd Decimal? @db.Decimal(12, 2)
+ expiresAt DateTime?
+ evergreenLabel String? // "expiration not provided" when source omits a date
+ sourceId String?
+ sourceUrl String?
+ isDemo Boolean @default(false)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ builder Builder? @relation(fields: [builderId], references: [id])
+ community Community? @relation(fields: [communityId], references: [id])
+ home InventoryHome? @relation(fields: [homeId], references: [id])
+
+ @@index([communityId])
+ @@index([homeId])
+ @@index([expiresAt])
+}
+
+model SalesOffice {
+ id String @id @default(cuid())
+ communityId String
+ street String?
+ city String?
+ state String?
+ zip String?
+ phone String?
+ hours Json?
+ isDemo Boolean @default(false)
+ createdAt DateTime @default(now())
+
+ community Community @relation(fields: [communityId], references: [id])
+
+ @@index([communityId])
+}
+
+model Lead {
+ id String @id @default(cuid())
+ homeId String?
+ communityId String?
+ name String
+ email String
+ phone String?
+ message String?
+ createdAt DateTime @default(now())
+
+ home InventoryHome? @relation(fields: [homeId], references: [id])
+
+ @@index([createdAt])
+}
+
+// Schema present; delivery deferred (no sender in v1).
+model SavedSearch {
+ id String @id @default(cuid())
+ email String
+ criteria Json
+ createdAt DateTime @default(now())
+}
+
+model Alert {
+ id String @id @default(cuid())
+ email String
+ homeId String?
+ kind String // price_change | availability
+ active Boolean @default(true)
+ createdAt DateTime @default(now())
+}
+
+// ─────────────────────── RAW / PIPELINE SIDE ───────────────────────
+
+enum CollectionMethod {
+ FEED // builder-provided feed or API
+ CRAWL // permissioned crawling only
+ MANUAL // builder-submitted / hand-entered
+ FIXTURE // local fixture files (tests + demo pipeline)
+ SYNTHETIC // generated demonstration data
+}
+
+enum MediaRights {
+ NONE // facts only — no photos, renderings, plans, or descriptions
+ LINK_ONLY
+ LICENSED
+}
+
+enum SourceHealth {
+ HEALTHY
+ DEGRADED
+ FAILING
+ PAUSED
+}
+
+model SourceRegistry {
+ id String @id @default(cuid())
+ key String @unique // adapter key, e.g. "meridian-homes-fixtures"
+ name String
+ builderId String?
+ baseUrl String?
+ collectionMethod CollectionMethod
+ termsUrl String?
+ permissions Json? // recorded permissions / partnership terms
+ attribution String? // required attribution text, if any
+ mediaRights MediaRights @default(NONE)
+ rateLimitRpm Int?
+ freshIntervalHours Int @default(24)
+ agingIntervalHours Int @default(72)
+ health SourceHealth @default(HEALTHY)
+ active Boolean @default(true)
+ notes String?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ builder Builder? @relation(fields: [builderId], references: [id])
+ snapshots RawSnapshot[]
+ staged StagedRecord[]
+ homes InventoryHome[]
+}
+
+model RawSnapshot {
+ id String @id @default(cuid())
+ sourceId String
+ url String
+ retrievedAt DateTime @default(now())
+ contentHash String // sha256 of body; new hash on same url = change detected
+ storagePath String // body on disk under var/snapshots/, never in PG
+ contentType String?
+ httpStatus Int?
+ createdAt DateTime @default(now())
+
+ source SourceRegistry @relation(fields: [sourceId], references: [id])
+ staged StagedRecord[]
+
+ @@unique([sourceId, contentHash])
+ @@index([sourceId, retrievedAt])
+}
+
+enum EntityType {
+ BUILDER
+ COMMUNITY
+ FLOOR_PLAN
+ INVENTORY_HOME
+ INCENTIVE
+ SALES_OFFICE
+ LOT
+}
+
+enum StagedStatus {
+ EXTRACTED
+ VALIDATED
+ NEEDS_REVIEW
+ APPROVED
+ REJECTED
+ PUBLISHED
+}
+
+model StagedRecord {
+ id String @id @default(cuid())
+ sourceId String
+ snapshotId String?
+ entityType EntityType
+ canonicalKey String
+ payload Json // per-field FieldValue envelope {value,raw,evidenceText,sourceUrl,confidence}
+ extractorVersion String
+ status StagedStatus @default(EXTRACTED)
+ publishedEntityId String?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ source SourceRegistry @relation(fields: [sourceId], references: [id])
+ snapshot RawSnapshot? @relation(fields: [snapshotId], references: [id])
+ evidence SourceEvidence[]
+ events ValidationEvent[]
+ reviews ReviewItem[]
+
+ @@index([status])
+ @@index([canonicalKey])
+}
+
+model SourceEvidence {
+ id String @id @default(cuid())
+ stagedRecordId String?
+ entityType EntityType?
+ entityId String? // set at publish so consumer pages can cite evidence
+ field String
+ sourceUrl String
+ retrievedAt DateTime
+ contentHash String?
+ extractorVersion String
+ rawValue String?
+ normalizedValue String?
+ evidenceText String?
+ confidence Float
+ createdAt DateTime @default(now())
+
+ stagedRecord StagedRecord? @relation(fields: [stagedRecordId], references: [id])
+
+ @@index([entityType, entityId])
+ @@index([stagedRecordId])
+}
+
+model ValidationEvent {
+ id String @id @default(cuid())
+ stagedRecordId String
+ ruleId String
+ severity String // error | review | warn
+ passed Boolean
+ message String?
+ details Json?
+ validatorVersion String
+ runAt DateTime @default(now())
+
+ stagedRecord StagedRecord @relation(fields: [stagedRecordId], references: [id])
+
+ @@index([stagedRecordId])
+ @@index([ruleId, passed])
+}
+
+model ChangeEvent {
+ id String @id @default(cuid())
+ entityType EntityType
+ entityId String
+ field String
+ oldValue String?
+ newValue String?
+ sourceId String?
+ requiresReview Boolean @default(false)
+ detectedAt DateTime @default(now())
+
+ @@index([entityType, entityId])
+ @@index([detectedAt])
+}
+
+enum ReviewStatus {
+ OPEN
+ APPROVED
+ REJECTED
+}
+
+model ReviewItem {
+ id String @id @default(cuid())
+ stagedRecordId String?
+ changeEventId String?
+ reason String
+ status ReviewStatus @default(OPEN)
+ reviewer String?
+ resolutionNote String?
+ resolvedAt DateTime?
+ createdAt DateTime @default(now())
+
+ stagedRecord StagedRecord? @relation(fields: [stagedRecordId], references: [id])
+
+ @@index([status])
+ @@index([createdAt])
+}
+
+// Consumer-facing correction reports ("report a problem with this listing").
+model CorrectionReport {
+ id String @id @default(cuid())
+ entityType EntityType
+ entityId String
+ field String?
+ message String
+ reporterEmail String?
+ status ReviewStatus @default(OPEN)
+ createdAt DateTime @default(now())
+
+ @@index([status])
+}
diff --git a/packages/database/src/index.ts b/packages/database/src/index.ts
new file mode 100644
index 0000000..26a5116
--- /dev/null
+++ b/packages/database/src/index.ts
@@ -0,0 +1,15 @@
+import { PrismaClient } from "@prisma/client";
+
+// Singleton across Next.js hot reloads and worker processes.
+const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient };
+
+export const prisma =
+ globalForPrisma.prisma ??
+ new PrismaClient({
+ datasourceUrl: process.env.DATABASE_URL,
+ });
+
+if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
+
+export * from "@prisma/client";
+export { PrismaClient };
diff --git a/packages/database/tsconfig.json b/packages/database/tsconfig.json
new file mode 100644
index 0000000..a653c3d
--- /dev/null
+++ b/packages/database/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts", "prisma/**/*.ts"] }
diff --git a/packages/schemas/package.json b/packages/schemas/package.json
new file mode 100644
index 0000000..d908071
--- /dev/null
+++ b/packages/schemas/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@spechomes/schemas",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "zod": "^3.24.1" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/packages/schemas/tsconfig.json b/packages/schemas/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/packages/schemas/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/packages/search/package.json b/packages/search/package.json
new file mode 100644
index 0000000..93a3dd4
--- /dev/null
+++ b/packages/search/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@spechomes/search",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "@spechomes/database": "workspace:*", "@spechomes/shared": "workspace:*" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/packages/search/tsconfig.json b/packages/search/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/packages/search/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/packages/shared-ui/package.json b/packages/shared-ui/package.json
new file mode 100644
index 0000000..60e9546
--- /dev/null
+++ b/packages/shared-ui/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "@spechomes/shared-ui",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "leaflet": "^1.9.4", "react-leaflet": "^5.0.0" },
+ "peerDependencies": { "react": "^19", "react-dom": "^19" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/react": "^19", "@types/leaflet": "^1.9.14", "@types/node": "^22.10.5" }
+}
diff --git a/packages/shared-ui/tsconfig.json b/packages/shared-ui/tsconfig.json
new file mode 100644
index 0000000..f576327
--- /dev/null
+++ b/packages/shared-ui/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts", "src/**/*.tsx"] }
diff --git a/packages/shared/package.json b/packages/shared/package.json
new file mode 100644
index 0000000..f49e00f
--- /dev/null
+++ b/packages/shared/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@spechomes/shared",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "pg-boss": "^10.1.5" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/packages/shared/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/packages/source-registry/package.json b/packages/source-registry/package.json
new file mode 100644
index 0000000..45acda9
--- /dev/null
+++ b/packages/source-registry/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@spechomes/source-registry",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "@spechomes/database": "workspace:*", "zod": "^3.24.1" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/packages/source-registry/tsconfig.json b/packages/source-registry/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/packages/source-registry/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/packages/validation/package.json b/packages/validation/package.json
new file mode 100644
index 0000000..1ae8f46
--- /dev/null
+++ b/packages/validation/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@spechomes/validation",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+ "dependencies": { "@spechomes/schemas": "workspace:*", "@spechomes/shared": "workspace:*", "@spechomes/database": "workspace:*" },
+ "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/packages/validation/tsconfig.json b/packages/validation/tsconfig.json
new file mode 100644
index 0000000..e9bfc48
--- /dev/null
+++ b/packages/validation/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..391fb4a
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,2850 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ devDependencies:
+ '@playwright/test':
+ specifier: ^1.49.1
+ version: 1.61.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ apps/admin:
+ dependencies:
+ '@spechomes/database':
+ specifier: workspace:*
+ version: link:../../packages/database
+ '@spechomes/schemas':
+ specifier: workspace:*
+ version: link:../../packages/schemas
+ '@spechomes/search':
+ specifier: workspace:*
+ version: link:../../packages/search
+ '@spechomes/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@spechomes/shared-ui':
+ specifier: workspace:*
+ version: link:../../packages/shared-ui
+ leaflet:
+ specifier: ^1.9.4
+ version: 1.9.4
+ next:
+ specifier: 16.2.10
+ version: 16.2.10(@playwright/test@1.61.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ react:
+ specifier: 19.2.7
+ version: 19.2.7
+ react-dom:
+ specifier: 19.2.7
+ version: 19.2.7(react@19.2.7)
+ react-leaflet:
+ specifier: ^5.0.0
+ version: 5.0.0(leaflet@1.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ zod:
+ specifier: ^3.24.1
+ version: 3.25.76
+ devDependencies:
+ '@tailwindcss/postcss':
+ specifier: ^4.0.0
+ version: 4.3.3
+ '@types/leaflet':
+ specifier: ^1.9.14
+ version: 1.9.21
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ '@types/react':
+ specifier: ^19
+ version: 19.2.17
+ '@types/react-dom':
+ specifier: ^19
+ version: 19.2.3(@types/react@19.2.17)
+ tailwindcss:
+ specifier: ^4.0.0
+ version: 4.3.3
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ apps/web:
+ dependencies:
+ '@spechomes/database':
+ specifier: workspace:*
+ version: link:../../packages/database
+ '@spechomes/schemas':
+ specifier: workspace:*
+ version: link:../../packages/schemas
+ '@spechomes/search':
+ specifier: workspace:*
+ version: link:../../packages/search
+ '@spechomes/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@spechomes/shared-ui':
+ specifier: workspace:*
+ version: link:../../packages/shared-ui
+ leaflet:
+ specifier: ^1.9.4
+ version: 1.9.4
+ next:
+ specifier: 16.2.10
+ version: 16.2.10(@playwright/test@1.61.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ react:
+ specifier: 19.2.7
+ version: 19.2.7
+ react-dom:
+ specifier: 19.2.7
+ version: 19.2.7(react@19.2.7)
+ react-leaflet:
+ specifier: ^5.0.0
+ version: 5.0.0(leaflet@1.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ zod:
+ specifier: ^3.24.1
+ version: 3.25.76
+ devDependencies:
+ '@tailwindcss/postcss':
+ specifier: ^4.0.0
+ version: 4.3.3
+ '@types/leaflet':
+ specifier: ^1.9.14
+ version: 1.9.21
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ '@types/react':
+ specifier: ^19
+ version: 19.2.17
+ '@types/react-dom':
+ specifier: ^19
+ version: 19.2.3(@types/react@19.2.17)
+ tailwindcss:
+ specifier: ^4.0.0
+ version: 4.3.3
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ apps/workers:
+ dependencies:
+ '@spechomes/collector-meridian-homes':
+ specifier: workspace:*
+ version: link:../../collectors/meridian-homes
+ '@spechomes/collectors-common':
+ specifier: workspace:*
+ version: link:../../collectors/common
+ '@spechomes/database':
+ specifier: workspace:*
+ version: link:../../packages/database
+ '@spechomes/schemas':
+ specifier: workspace:*
+ version: link:../../packages/schemas
+ '@spechomes/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@spechomes/validation':
+ specifier: workspace:*
+ version: link:../../packages/validation
+ pg-boss:
+ specifier: ^10.1.5
+ version: 10.4.2
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ tsx:
+ specifier: ^4.19.2
+ version: 4.23.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ collectors/common:
+ dependencies:
+ '@spechomes/schemas':
+ specifier: workspace:*
+ version: link:../../packages/schemas
+ '@spechomes/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ node-html-parser:
+ specifier: ^7.0.1
+ version: 7.1.0
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ collectors/meridian-homes:
+ dependencies:
+ '@spechomes/collectors-common':
+ specifier: workspace:*
+ version: link:../common
+ '@spechomes/schemas':
+ specifier: workspace:*
+ version: link:../../packages/schemas
+ '@spechomes/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ node-html-parser:
+ specifier: ^7.0.1
+ version: 7.1.0
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ packages/database:
+ dependencies:
+ '@prisma/client':
+ specifier: 6.19.3
+ version: 6.19.3(prisma@6.19.3(typescript@5.9.3))(typescript@5.9.3)
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ prisma:
+ specifier: 6.19.3
+ version: 6.19.3(typescript@5.9.3)
+ tsx:
+ specifier: ^4.19.2
+ version: 4.23.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ packages/schemas:
+ dependencies:
+ zod:
+ specifier: ^3.24.1
+ version: 3.25.76
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ packages/search:
+ dependencies:
+ '@spechomes/database':
+ specifier: workspace:*
+ version: link:../database
+ '@spechomes/shared':
+ specifier: workspace:*
+ version: link:../shared
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ packages/shared:
+ dependencies:
+ pg-boss:
+ specifier: ^10.1.5
+ version: 10.4.2
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ packages/shared-ui:
+ dependencies:
+ leaflet:
+ specifier: ^1.9.4
+ version: 1.9.4
+ react:
+ specifier: ^19
+ version: 19.2.7
+ react-dom:
+ specifier: ^19
+ version: 19.2.7(react@19.2.7)
+ react-leaflet:
+ specifier: ^5.0.0
+ version: 5.0.0(leaflet@1.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ devDependencies:
+ '@types/leaflet':
+ specifier: ^1.9.14
+ version: 1.9.21
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ '@types/react':
+ specifier: ^19
+ version: 19.2.17
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ packages/source-registry:
+ dependencies:
+ '@spechomes/database':
+ specifier: workspace:*
+ version: link:../database
+ zod:
+ specifier: ^3.24.1
+ version: 3.25.76
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+ packages/validation:
+ dependencies:
+ '@spechomes/database':
+ specifier: workspace:*
+ version: link:../database
+ '@spechomes/schemas':
+ specifier: workspace:*
+ version: link:../schemas
+ '@spechomes/shared':
+ specifier: workspace:*
+ version: link:../shared
+ devDependencies:
+ '@types/node':
+ specifier: ^22.10.5
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.0
+ version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
+packages:
+
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ '@emnapi/core@1.11.1':
+ resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==}
+
+ '@emnapi/runtime@1.11.1':
+ resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==}
+
+ '@emnapi/runtime@1.11.2':
+ resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==}
+
+ '@emnapi/wasi-threads@1.2.2':
+ resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
+
+ '@esbuild/aix-ppc64@0.28.1':
+ resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.28.1':
+ resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.28.1':
+ resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.28.1':
+ resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.28.1':
+ resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.28.1':
+ resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.28.1':
+ resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.28.1':
+ resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.28.1':
+ resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.28.1':
+ resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.28.1':
+ resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.28.1':
+ resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.28.1':
+ resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.28.1':
+ resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.28.1':
+ resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.28.1':
+ resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.28.1':
+ resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.28.1':
+ resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.28.1':
+ resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.28.1':
+ resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.28.1':
+ resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.28.1':
+ resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.28.1':
+ resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.28.1':
+ resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.28.1':
+ resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.28.1':
+ resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@napi-rs/wasm-runtime@1.1.6':
+ resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1
+ '@emnapi/runtime': ^1.7.1
+
+ '@next/env@16.2.10':
+ resolution: {integrity: sha512-zLPxg9M0MEHmygpj5OuxjQ+vHMiy/K7cSp74G8ecYolmgUWw0RwN02tF56npup/+qaI8JB97hQgS/r2Hb6QwVA==}
+
+ '@next/swc-darwin-arm64@16.2.10':
+ resolution: {integrity: sha512-v9IdJCa0H0mbo+8z5zwUpOk1Vj7RjkcI5uNYf5Ws1y6szf/p3Mzl9hLaST8SCt6L9h8NGnruZcd2+o0NTNwDhA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@16.2.10':
+ resolution: {integrity: sha512-17IS0jJRViROGmA9uGdNR8VPJpfbnaVG7E9qhso5jDLkmyd0lSDORWxbcKINzcFqzZqGwGtMSnrFRxBpuUYjLQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@16.2.10':
+ resolution: {integrity: sha512-GRQRsRtuciNJvB54AvvuQTiq0oZtFwa1owQqtZD8wwnGpM2L39MV22kpI72YSXLKIyY40LC66EiLFv4PiicXxg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-arm64-musl@16.2.10':
+ resolution: {integrity: sha512-zkN9MQYS7UQBro+FnISUq1itaQjXI9xqISzuQ+2bc921NcJ1x4yPCqrn77tVN6/dOOXaaWVX3k6/bR07pPwK+A==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-x64-gnu@16.2.10':
+ resolution: {integrity: sha512-iCVJnwvrPYECvA6WM/7+oo+OiTvedIKLxtCLAZP4xZR3nXa1zmzZyLPbYCmWvpd4CvMYF1EMTafd0ii3DygLvA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-x64-musl@16.2.10':
+ resolution: {integrity: sha512-ov2g4H0dHY9bPoOU83m91hWT7Iq5qy13bUnyyshLU3HGR1Ownn0X9QpmDPc5iIUaahTp7f7LeGAhV4DSFtackw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-win32-arm64-msvc@16.2.10':
+ resolution: {integrity: sha512-DwAnhLX76HQiFFQNgWlcK+JzlnD1rZ+UK/WY0ZMI/deXpvgnesjNYrqcfo1JzBuz4Kf7o3brIBL0glI1junatA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@16.2.10':
+ resolution: {integrity: sha512-0JXq3b85Jk9Jg4ntLUbXSPvoDw3gpZou7twuKdoFG2jOw635v7+IiXfTaa0TxVMyx78pUjnrVYwLgjKfX4e6/A==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@oxc-project/types@0.139.0':
+ resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==}
+
+ '@playwright/test@1.61.1':
+ resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ '@prisma/client@6.19.3':
+ resolution: {integrity: sha512-mKq3jQFhjvko5LTJFHGilsuQs+W+T3Gm451NzuTDGQxwCzwXHYnIu2zGkRoW+Exq3Rob7yp2MfzSrdIiZVhrBg==}
+ engines: {node: '>=18.18'}
+ peerDependencies:
+ prisma: '*'
+ typescript: '>=5.1.0'
+ peerDependenciesMeta:
+ prisma:
+ optional: true
+ typescript:
+ optional: true
+
+ '@prisma/config@6.19.3':
+ resolution: {integrity: sha512-CBPT44BjlQxEt8kiMEauji2WHTDoVBOKl7UlewXmUgBPnr/oPRZC3psci5chJnYmH0ivEIog2OU9PGWoki3DLQ==}
+
+ '@prisma/debug@6.19.3':
+ resolution: {integrity: sha512-ljkJ+SgpXNktLG0Q/n4JGYCkKf0f8oYLyjImS2I8e2q2WCfdRRtWER062ZV/ixaNP2M2VKlWXVJiGzZaUgbKZw==}
+
+ '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7':
+ resolution: {integrity: sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==}
+
+ '@prisma/engines@6.19.3':
+ resolution: {integrity: sha512-RSYxtlYFl5pJ8ZePgMv0lZ9IzVCOdTPOegrs2qcbAEFrBI1G33h6wyC9kjQvo0DnYEhEVY0X4LsuFHXLKQk88g==}
+
+ '@prisma/fetch-engine@6.19.3':
+ resolution: {integrity: sha512-tKtl/qco9Nt7LU5iKhpultD8O4vMCZcU2CHjNTnRrL1QvSUr5W/GcyFPjNL87GtRrwBc7ubXXD9xy4EvLvt8JA==}
+
+ '@prisma/get-platform@6.19.3':
+ resolution: {integrity: sha512-xFj1VcJ1N3MKooOQAGO0W5tsd0W2QzIvW7DD7c/8H14Zmp4jseeWAITm+w2LLoLrlhoHdPPh0NMZ8mfL6puoHA==}
+
+ '@react-leaflet/core@3.0.0':
+ resolution: {integrity: sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==}
+ peerDependencies:
+ leaflet: ^1.9.0
+ react: ^19.0.0
+ react-dom: ^19.0.0
+
+ '@rolldown/binding-android-arm64@1.1.5':
+ resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@rolldown/binding-darwin-arm64@1.1.5':
+ resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rolldown/binding-darwin-x64@1.1.5':
+ resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rolldown/binding-freebsd-x64@1.1.5':
+ resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.1.5':
+ resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@rolldown/binding-linux-arm64-gnu@1.1.5':
+ resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-arm64-musl@1.1.5':
+ resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rolldown/binding-linux-ppc64-gnu@1.1.5':
+ resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-s390x-gnu@1.1.5':
+ resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-x64-gnu@1.1.5':
+ resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rolldown/binding-linux-x64-musl@1.1.5':
+ resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rolldown/binding-openharmony-arm64@1.1.5':
+ resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rolldown/binding-wasm32-wasi@1.1.5':
+ resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [wasm32]
+
+ '@rolldown/binding-win32-arm64-msvc@1.1.5':
+ resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rolldown/binding-win32-x64-msvc@1.1.5':
+ resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@rolldown/pluginutils@1.0.1':
+ resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@swc/helpers@0.5.15':
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+
+ '@tailwindcss/node@4.3.3':
+ resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==}
+
+ '@tailwindcss/oxide-android-arm64@4.3.3':
+ resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.3.3':
+ resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.3.3':
+ resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.3.3':
+ resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3':
+ resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==}
+ engines: {node: '>= 20'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.3.3':
+ resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.3.3':
+ resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.3.3':
+ resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.3.3':
+ resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@tailwindcss/oxide-wasm32-wasi@4.3.3':
+ resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+ bundledDependencies:
+ - '@napi-rs/wasm-runtime'
+ - '@emnapi/core'
+ - '@emnapi/runtime'
+ - '@tybys/wasm-util'
+ - '@emnapi/wasi-threads'
+ - tslib
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.3.3':
+ resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.3.3':
+ resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.3.3':
+ resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==}
+ engines: {node: '>= 20'}
+
+ '@tailwindcss/postcss@4.3.3':
+ resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==}
+
+ '@tybys/wasm-util@0.10.3':
+ resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
+
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/geojson@7946.0.16':
+ resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
+
+ '@types/leaflet@1.9.21':
+ resolution: {integrity: sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==}
+
+ '@types/node@22.20.1':
+ resolution: {integrity: sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==}
+
+ '@types/react-dom@19.2.3':
+ resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
+ peerDependencies:
+ '@types/react': ^19.2.0
+
+ '@types/react@19.2.17':
+ resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==}
+
+ '@vitest/expect@4.1.10':
+ resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==}
+
+ '@vitest/mocker@4.1.10':
+ resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@4.1.10':
+ resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==}
+
+ '@vitest/runner@4.1.10':
+ resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==}
+
+ '@vitest/snapshot@4.1.10':
+ resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==}
+
+ '@vitest/spy@4.1.10':
+ resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==}
+
+ '@vitest/utils@4.1.10':
+ resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==}
+
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
+ baseline-browser-mapping@2.11.0:
+ resolution: {integrity: sha512-oCu2wfipvX3AePSgmOuKkIywOu+8n9psz7hXYmk56ghpu3+7KzNIBopaOs4c9BrtdnTtW30unG9GTfHo7EwERQ==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ boolbase@1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+
+ c12@3.1.0:
+ resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==}
+ peerDependencies:
+ magicast: ^0.3.5
+ peerDependenciesMeta:
+ magicast:
+ optional: true
+
+ caniuse-lite@1.0.30001806:
+ resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==}
+
+ chai@6.2.2:
+ resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
+ engines: {node: '>=18'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ citty@0.1.6:
+ resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
+
+ citty@0.2.2:
+ resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==}
+
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ confbox@0.2.4:
+ resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
+
+ consola@3.4.2:
+ resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
+ engines: {node: ^14.18.0 || >=16.10.0}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cron-parser@4.9.0:
+ resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==}
+ engines: {node: '>=12.0.0'}
+
+ css-select@5.2.2:
+ resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
+
+ css-what@6.2.2:
+ resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
+ engines: {node: '>= 6'}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ deepmerge-ts@7.1.5:
+ resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==}
+ engines: {node: '>=16.0.0'}
+
+ defu@6.1.7:
+ resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
+
+ destr@2.0.5:
+ resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
+ domelementtype@2.3.0:
+ resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
+ domutils@3.2.2:
+ resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
+
+ dotenv@16.6.1:
+ resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
+ engines: {node: '>=12'}
+
+ effect@3.21.0:
+ resolution: {integrity: sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==}
+
+ empathic@2.0.0:
+ resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==}
+ engines: {node: '>=14'}
+
+ enhanced-resolve@5.24.3:
+ resolution: {integrity: sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==}
+ engines: {node: '>=10.13.0'}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ es-module-lexer@2.3.1:
+ resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==}
+
+ esbuild@0.28.1:
+ resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ expect-type@1.4.0:
+ resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
+ engines: {node: '>=12.0.0'}
+
+ exsolve@1.1.0:
+ resolution: {integrity: sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==}
+
+ fast-check@3.23.2:
+ resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
+ engines: {node: '>=8.0.0'}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ giget@2.0.0:
+ resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
+ hasBin: true
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
+ jiti@2.7.0:
+ resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
+ hasBin: true
+
+ leaflet@1.9.4:
+ resolution: {integrity: sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==}
+
+ lightningcss-android-arm64@1.32.0:
+ resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-android-arm64@1.33.0:
+ resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.32.0:
+ resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-arm64@1.33.0:
+ resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.32.0:
+ resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.33.0:
+ resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.32.0:
+ resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-freebsd-x64@1.33.0:
+ resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ lightningcss-linux-x64-musl@1.32.0:
+ resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-linux-x64-musl@1.33.0:
+ resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.32.0:
+ resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
+ engines: {node: '>= 12.0.0'}
+
+ lightningcss@1.33.0:
+ resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
+ engines: {node: '>= 12.0.0'}
+
+ luxon@3.7.2:
+ resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==}
+ engines: {node: '>=12'}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ nanoid@3.3.16:
+ resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ next@16.2.10:
+ resolution: {integrity: sha512-2som5AVXb3kE6Yjine3/mNbBayYF58eguBWIVVUdr1y/L426xyVEgYxgBG+1QC34P2x5E+tcDup6XkuOAX3dCA==}
+ engines: {node: '>=20.9.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
+ node-fetch-native@1.6.7:
+ resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
+
+ node-html-parser@7.1.0:
+ resolution: {integrity: sha512-iJo8b2uYGT40Y8BTyy5ufL6IVbN8rbm/1QK2xffXU/1a/v3AAa0d1YAoqBNYqaS4R/HajkWIpIfdE6KcyFh1AQ==}
+
+ nth-check@2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+
+ nypm@0.6.8:
+ resolution: {integrity: sha512-Q9K4Diu6l5u6xJQogeFSs/zKtyMSgFKFtRQV+tHP4kL7KPm2grpBU0dFIwFaXwNxN0MtfKWc43VpCugAa+LPsw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ obug@2.1.4:
+ resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==}
+ engines: {node: '>=12.20.0'}
+
+ ohash@2.0.11:
+ resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ perfect-debounce@1.0.0:
+ resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+
+ pg-boss@10.4.2:
+ resolution: {integrity: sha512-AttEWOtSzn53av8OnCMWEanwRBvjkZCE1y5nLrZnwvkkMnlZ5XpWDpZ7sKI/BYjvi2OVieMX37arD2ACgJ750w==}
+ engines: {node: '>=20'}
+
+ pg-cloudflare@1.4.0:
+ resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==}
+
+ pg-connection-string@2.14.0:
+ resolution: {integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==}
+
+ pg-int8@1.0.1:
+ resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
+ engines: {node: '>=4.0.0'}
+
+ pg-pool@3.14.0:
+ resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==}
+ peerDependencies:
+ pg: '>=8.0'
+
+ pg-protocol@1.15.0:
+ resolution: {integrity: sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ==}
+
+ pg-types@2.2.0:
+ resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
+ engines: {node: '>=4'}
+
+ pg@8.22.0:
+ resolution: {integrity: sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA==}
+ engines: {node: '>= 16.0.0'}
+ peerDependencies:
+ pg-native: '>=3.0.1'
+ peerDependenciesMeta:
+ pg-native:
+ optional: true
+
+ pgpass@1.0.5:
+ resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.5:
+ resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
+ engines: {node: '>=12'}
+
+ pkg-types@2.3.1:
+ resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==}
+
+ playwright-core@1.61.1:
+ resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ playwright@1.61.1:
+ resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.5.21:
+ resolution: {integrity: sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postgres-array@2.0.0:
+ resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
+ engines: {node: '>=4'}
+
+ postgres-bytea@1.0.1:
+ resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-date@1.0.7:
+ resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-interval@1.2.0:
+ resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
+ engines: {node: '>=0.10.0'}
+
+ prisma@6.19.3:
+ resolution: {integrity: sha512-++ZJ0ijLrDJF6hNB4t4uxg2br3fC4H9Yc9tcbjr2fcNFP3rh/SBNrAgjhsqBU4Ght8JPrVofG/ZkXfnSfnYsFg==}
+ engines: {node: '>=18.18'}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.1.0'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ pure-rand@6.1.0:
+ resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
+
+ rc9@2.1.2:
+ resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
+
+ react-dom@19.2.7:
+ resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==}
+ peerDependencies:
+ react: ^19.2.7
+
+ react-leaflet@5.0.0:
+ resolution: {integrity: sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==}
+ peerDependencies:
+ leaflet: ^1.9.0
+ react: ^19.0.0
+ react-dom: ^19.0.0
+
+ react@19.2.7:
+ resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==}
+ engines: {node: '>=0.10.0'}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ rolldown@1.1.5:
+ resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+
+ scheduler@0.27.0:
+ resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+
+ semver@7.8.5:
+ resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ serialize-error@8.1.0:
+ resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==}
+ engines: {node: '>=10'}
+
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ split2@4.2.0:
+ resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
+ engines: {node: '>= 10.x'}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@4.2.0:
+ resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==}
+
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ tailwindcss@4.3.3:
+ resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==}
+
+ tapable@2.3.3:
+ resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
+ engines: {node: '>=6'}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@1.2.4:
+ resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ tinyrainbow@3.1.0:
+ resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
+ engines: {node: '>=14.0.0'}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tsx@4.23.1:
+ resolution: {integrity: sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
+ type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+ vite@8.1.5:
+ resolution: {integrity: sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ '@vitejs/devtools': ^0.3.0
+ esbuild: ^0.27.0 || ^0.28.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ '@vitejs/devtools':
+ optional: true
+ esbuild:
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitest@4.1.10:
+ resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==}
+ engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@opentelemetry/api': ^1.9.0
+ '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 4.1.10
+ '@vitest/browser-preview': 4.1.10
+ '@vitest/browser-webdriverio': 4.1.10
+ '@vitest/coverage-istanbul': 4.1.10
+ '@vitest/coverage-v8': 4.1.10
+ '@vitest/ui': 4.1.10
+ happy-dom: '*'
+ jsdom: '*'
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@opentelemetry/api':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/coverage-istanbul':
+ optional: true
+ '@vitest/coverage-v8':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ xtend@4.0.2:
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+ engines: {node: '>=0.4'}
+
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+snapshots:
+
+ '@alloc/quick-lru@5.2.0': {}
+
+ '@emnapi/core@1.11.1':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.2
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.11.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/runtime@1.11.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@emnapi/wasi-threads@1.2.2':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@esbuild/aix-ppc64@0.28.1':
+ optional: true
+
+ '@esbuild/android-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/android-arm@0.28.1':
+ optional: true
+
+ '@esbuild/android-x64@0.28.1':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/darwin-x64@0.28.1':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-arm@0.28.1':
+ optional: true
+
+ '@esbuild/linux-ia32@0.28.1':
+ optional: true
+
+ '@esbuild/linux-loong64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.28.1':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-s390x@0.28.1':
+ optional: true
+
+ '@esbuild/linux-x64@0.28.1':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.28.1':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.28.1':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/sunos-x64@0.28.1':
+ optional: true
+
+ '@esbuild/win32-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/win32-ia32@0.28.1':
+ optional: true
+
+ '@esbuild/win32-x64@0.28.1':
+ optional: true
+
+ '@img/colour@1.1.0':
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.11.2
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)':
+ dependencies:
+ '@emnapi/core': 1.11.1
+ '@emnapi/runtime': 1.11.1
+ '@tybys/wasm-util': 0.10.3
+ optional: true
+
+ '@next/env@16.2.10': {}
+
+ '@next/swc-darwin-arm64@16.2.10':
+ optional: true
+
+ '@next/swc-darwin-x64@16.2.10':
+ optional: true
+
+ '@next/swc-linux-arm64-gnu@16.2.10':
+ optional: true
+
+ '@next/swc-linux-arm64-musl@16.2.10':
+ optional: true
+
+ '@next/swc-linux-x64-gnu@16.2.10':
+ optional: true
+
+ '@next/swc-linux-x64-musl@16.2.10':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@16.2.10':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@16.2.10':
+ optional: true
+
+ '@oxc-project/types@0.139.0': {}
+
+ '@playwright/test@1.61.1':
+ dependencies:
+ playwright: 1.61.1
+
+ '@prisma/client@6.19.3(prisma@6.19.3(typescript@5.9.3))(typescript@5.9.3)':
+ optionalDependencies:
+ prisma: 6.19.3(typescript@5.9.3)
+ typescript: 5.9.3
+
+ '@prisma/config@6.19.3':
+ dependencies:
+ c12: 3.1.0
+ deepmerge-ts: 7.1.5
+ effect: 3.21.0
+ empathic: 2.0.0
+ transitivePeerDependencies:
+ - magicast
+
+ '@prisma/debug@6.19.3': {}
+
+ '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': {}
+
+ '@prisma/engines@6.19.3':
+ dependencies:
+ '@prisma/debug': 6.19.3
+ '@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7
+ '@prisma/fetch-engine': 6.19.3
+ '@prisma/get-platform': 6.19.3
+
+ '@prisma/fetch-engine@6.19.3':
+ dependencies:
+ '@prisma/debug': 6.19.3
+ '@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7
+ '@prisma/get-platform': 6.19.3
+
+ '@prisma/get-platform@6.19.3':
+ dependencies:
+ '@prisma/debug': 6.19.3
+
+ '@react-leaflet/core@3.0.0(leaflet@1.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
+ dependencies:
+ leaflet: 1.9.4
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+
+ '@rolldown/binding-android-arm64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-darwin-arm64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-darwin-x64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-freebsd-x64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-musl@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-ppc64-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-s390x-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-x64-gnu@1.1.5':
+ optional: true
+
+ '@rolldown/binding-linux-x64-musl@1.1.5':
+ optional: true
+
+ '@rolldown/binding-openharmony-arm64@1.1.5':
+ optional: true
+
+ '@rolldown/binding-wasm32-wasi@1.1.5':
+ dependencies:
+ '@emnapi/core': 1.11.1
+ '@emnapi/runtime': 1.11.1
+ '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)
+ optional: true
+
+ '@rolldown/binding-win32-arm64-msvc@1.1.5':
+ optional: true
+
+ '@rolldown/binding-win32-x64-msvc@1.1.5':
+ optional: true
+
+ '@rolldown/pluginutils@1.0.1': {}
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@swc/helpers@0.5.15':
+ dependencies:
+ tslib: 2.8.1
+
+ '@tailwindcss/node@4.3.3':
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ enhanced-resolve: 5.24.3
+ jiti: 2.7.0
+ lightningcss: 1.32.0
+ magic-string: 0.30.21
+ source-map-js: 1.2.1
+ tailwindcss: 4.3.3
+
+ '@tailwindcss/oxide-android-arm64@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-wasm32-wasi@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.3.3':
+ optional: true
+
+ '@tailwindcss/oxide@4.3.3':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.3.3
+ '@tailwindcss/oxide-darwin-arm64': 4.3.3
+ '@tailwindcss/oxide-darwin-x64': 4.3.3
+ '@tailwindcss/oxide-freebsd-x64': 4.3.3
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3
+ '@tailwindcss/oxide-linux-arm64-musl': 4.3.3
+ '@tailwindcss/oxide-linux-x64-gnu': 4.3.3
+ '@tailwindcss/oxide-linux-x64-musl': 4.3.3
+ '@tailwindcss/oxide-wasm32-wasi': 4.3.3
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3
+ '@tailwindcss/oxide-win32-x64-msvc': 4.3.3
+
+ '@tailwindcss/postcss@4.3.3':
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ '@tailwindcss/node': 4.3.3
+ '@tailwindcss/oxide': 4.3.3
+ postcss: 8.5.21
+ tailwindcss: 4.3.3
+
+ '@tybys/wasm-util@0.10.3':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@types/chai@5.2.3':
+ dependencies:
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
+
+ '@types/deep-eql@4.0.2': {}
+
+ '@types/estree@1.0.9': {}
+
+ '@types/geojson@7946.0.16': {}
+
+ '@types/leaflet@1.9.21':
+ dependencies:
+ '@types/geojson': 7946.0.16
+
+ '@types/node@22.20.1':
+ dependencies:
+ undici-types: 6.21.0
+
+ '@types/react-dom@19.2.3(@types/react@19.2.17)':
+ dependencies:
+ '@types/react': 19.2.17
+
+ '@types/react@19.2.17':
+ dependencies:
+ csstype: 3.2.3
+
+ '@vitest/expect@4.1.10':
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ '@types/chai': 5.2.3
+ '@vitest/spy': 4.1.10
+ '@vitest/utils': 4.1.10
+ chai: 6.2.2
+ tinyrainbow: 3.1.0
+
+ '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))':
+ dependencies:
+ '@vitest/spy': 4.1.10
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)
+
+ '@vitest/pretty-format@4.1.10':
+ dependencies:
+ tinyrainbow: 3.1.0
+
+ '@vitest/runner@4.1.10':
+ dependencies:
+ '@vitest/utils': 4.1.10
+ pathe: 2.0.3
+
+ '@vitest/snapshot@4.1.10':
+ dependencies:
+ '@vitest/pretty-format': 4.1.10
+ '@vitest/utils': 4.1.10
+ magic-string: 0.30.21
+ pathe: 2.0.3
+
+ '@vitest/spy@4.1.10': {}
+
+ '@vitest/utils@4.1.10':
+ dependencies:
+ '@vitest/pretty-format': 4.1.10
+ convert-source-map: 2.0.0
+ tinyrainbow: 3.1.0
+
+ assertion-error@2.0.1: {}
+
+ baseline-browser-mapping@2.11.0: {}
+
+ boolbase@1.0.0: {}
+
+ c12@3.1.0:
+ dependencies:
+ chokidar: 4.0.3
+ confbox: 0.2.4
+ defu: 6.1.7
+ dotenv: 16.6.1
+ exsolve: 1.1.0
+ giget: 2.0.0
+ jiti: 2.7.0
+ ohash: 2.0.11
+ pathe: 2.0.3
+ perfect-debounce: 1.0.0
+ pkg-types: 2.3.1
+ rc9: 2.1.2
+
+ caniuse-lite@1.0.30001806: {}
+
+ chai@6.2.2: {}
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
+ citty@0.1.6:
+ dependencies:
+ consola: 3.4.2
+
+ citty@0.2.2: {}
+
+ client-only@0.0.1: {}
+
+ confbox@0.2.4: {}
+
+ consola@3.4.2: {}
+
+ convert-source-map@2.0.0: {}
+
+ cron-parser@4.9.0:
+ dependencies:
+ luxon: 3.7.2
+
+ css-select@5.2.2:
+ dependencies:
+ boolbase: 1.0.0
+ css-what: 6.2.2
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ nth-check: 2.1.1
+
+ css-what@6.2.2: {}
+
+ csstype@3.2.3: {}
+
+ deepmerge-ts@7.1.5: {}
+
+ defu@6.1.7: {}
+
+ destr@2.0.5: {}
+
+ detect-libc@2.1.2: {}
+
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
+ domelementtype@2.3.0: {}
+
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
+ domutils@3.2.2:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
+ dotenv@16.6.1: {}
+
+ effect@3.21.0:
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ fast-check: 3.23.2
+
+ empathic@2.0.0: {}
+
+ enhanced-resolve@5.24.3:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.3.3
+
+ entities@4.5.0: {}
+
+ es-module-lexer@2.3.1: {}
+
+ esbuild@0.28.1:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.28.1
+ '@esbuild/android-arm': 0.28.1
+ '@esbuild/android-arm64': 0.28.1
+ '@esbuild/android-x64': 0.28.1
+ '@esbuild/darwin-arm64': 0.28.1
+ '@esbuild/darwin-x64': 0.28.1
+ '@esbuild/freebsd-arm64': 0.28.1
+ '@esbuild/freebsd-x64': 0.28.1
+ '@esbuild/linux-arm': 0.28.1
+ '@esbuild/linux-arm64': 0.28.1
+ '@esbuild/linux-ia32': 0.28.1
+ '@esbuild/linux-loong64': 0.28.1
+ '@esbuild/linux-mips64el': 0.28.1
+ '@esbuild/linux-ppc64': 0.28.1
+ '@esbuild/linux-riscv64': 0.28.1
+ '@esbuild/linux-s390x': 0.28.1
+ '@esbuild/linux-x64': 0.28.1
+ '@esbuild/netbsd-arm64': 0.28.1
+ '@esbuild/netbsd-x64': 0.28.1
+ '@esbuild/openbsd-arm64': 0.28.1
+ '@esbuild/openbsd-x64': 0.28.1
+ '@esbuild/openharmony-arm64': 0.28.1
+ '@esbuild/sunos-x64': 0.28.1
+ '@esbuild/win32-arm64': 0.28.1
+ '@esbuild/win32-ia32': 0.28.1
+ '@esbuild/win32-x64': 0.28.1
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+
+ expect-type@1.4.0: {}
+
+ exsolve@1.1.0: {}
+
+ fast-check@3.23.2:
+ dependencies:
+ pure-rand: 6.1.0
+
+ fdir@6.5.0(picomatch@4.0.5):
+ optionalDependencies:
+ picomatch: 4.0.5
+
+ fsevents@2.3.2:
+ optional: true
+
+ fsevents@2.3.3:
+ optional: true
+
+ giget@2.0.0:
+ dependencies:
+ citty: 0.1.6
+ consola: 3.4.2
+ defu: 6.1.7
+ node-fetch-native: 1.6.7
+ nypm: 0.6.8
+ pathe: 2.0.3
+
+ graceful-fs@4.2.11: {}
+
+ he@1.2.0: {}
+
+ jiti@2.7.0: {}
+
+ leaflet@1.9.4: {}
+
+ lightningcss-android-arm64@1.32.0:
+ optional: true
+
+ lightningcss-android-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.33.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.32.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.33.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ optional: true
+
+ lightningcss@1.32.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.32.0
+ lightningcss-darwin-arm64: 1.32.0
+ lightningcss-darwin-x64: 1.32.0
+ lightningcss-freebsd-x64: 1.32.0
+ lightningcss-linux-arm-gnueabihf: 1.32.0
+ lightningcss-linux-arm64-gnu: 1.32.0
+ lightningcss-linux-arm64-musl: 1.32.0
+ lightningcss-linux-x64-gnu: 1.32.0
+ lightningcss-linux-x64-musl: 1.32.0
+ lightningcss-win32-arm64-msvc: 1.32.0
+ lightningcss-win32-x64-msvc: 1.32.0
+
+ lightningcss@1.33.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.33.0
+ lightningcss-darwin-arm64: 1.33.0
+ lightningcss-darwin-x64: 1.33.0
+ lightningcss-freebsd-x64: 1.33.0
+ lightningcss-linux-arm-gnueabihf: 1.33.0
+ lightningcss-linux-arm64-gnu: 1.33.0
+ lightningcss-linux-arm64-musl: 1.33.0
+ lightningcss-linux-x64-gnu: 1.33.0
+ lightningcss-linux-x64-musl: 1.33.0
+ lightningcss-win32-arm64-msvc: 1.33.0
+ lightningcss-win32-x64-msvc: 1.33.0
+
+ luxon@3.7.2: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ nanoid@3.3.16: {}
+
+ next@16.2.10(@playwright/test@1.61.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ dependencies:
+ '@next/env': 16.2.10
+ '@swc/helpers': 0.5.15
+ baseline-browser-mapping: 2.11.0
+ caniuse-lite: 1.0.30001806
+ postcss: 8.4.31
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+ styled-jsx: 5.1.6(react@19.2.7)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 16.2.10
+ '@next/swc-darwin-x64': 16.2.10
+ '@next/swc-linux-arm64-gnu': 16.2.10
+ '@next/swc-linux-arm64-musl': 16.2.10
+ '@next/swc-linux-x64-gnu': 16.2.10
+ '@next/swc-linux-x64-musl': 16.2.10
+ '@next/swc-win32-arm64-msvc': 16.2.10
+ '@next/swc-win32-x64-msvc': 16.2.10
+ '@playwright/test': 1.61.1
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
+ node-fetch-native@1.6.7: {}
+
+ node-html-parser@7.1.0:
+ dependencies:
+ css-select: 5.2.2
+ he: 1.2.0
+
+ nth-check@2.1.1:
+ dependencies:
+ boolbase: 1.0.0
+
+ nypm@0.6.8:
+ dependencies:
+ citty: 0.2.2
+ pathe: 2.0.3
+ tinyexec: 1.2.4
+
+ obug@2.1.4: {}
+
+ ohash@2.0.11: {}
+
+ pathe@2.0.3: {}
+
+ perfect-debounce@1.0.0: {}
+
+ pg-boss@10.4.2:
+ dependencies:
+ cron-parser: 4.9.0
+ pg: 8.22.0
+ serialize-error: 8.1.0
+ transitivePeerDependencies:
+ - pg-native
+
+ pg-cloudflare@1.4.0:
+ optional: true
+
+ pg-connection-string@2.14.0: {}
+
+ pg-int8@1.0.1: {}
+
+ pg-pool@3.14.0(pg@8.22.0):
+ dependencies:
+ pg: 8.22.0
+
+ pg-protocol@1.15.0: {}
+
+ pg-types@2.2.0:
+ dependencies:
+ pg-int8: 1.0.1
+ postgres-array: 2.0.0
+ postgres-bytea: 1.0.1
+ postgres-date: 1.0.7
+ postgres-interval: 1.2.0
+
+ pg@8.22.0:
+ dependencies:
+ pg-connection-string: 2.14.0
+ pg-pool: 3.14.0(pg@8.22.0)
+ pg-protocol: 1.15.0
+ pg-types: 2.2.0
+ pgpass: 1.0.5
+ optionalDependencies:
+ pg-cloudflare: 1.4.0
+
+ pgpass@1.0.5:
+ dependencies:
+ split2: 4.2.0
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.5: {}
+
+ pkg-types@2.3.1:
+ dependencies:
+ confbox: 0.2.4
+ exsolve: 1.1.0
+ pathe: 2.0.3
+
+ playwright-core@1.61.1: {}
+
+ playwright@1.61.1:
+ dependencies:
+ playwright-core: 1.61.1
+ optionalDependencies:
+ fsevents: 2.3.2
+
+ postcss@8.4.31:
+ dependencies:
+ nanoid: 3.3.16
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ postcss@8.5.21:
+ dependencies:
+ nanoid: 3.3.16
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ postgres-array@2.0.0: {}
+
+ postgres-bytea@1.0.1: {}
+
+ postgres-date@1.0.7: {}
+
+ postgres-interval@1.2.0:
+ dependencies:
+ xtend: 4.0.2
+
+ prisma@6.19.3(typescript@5.9.3):
+ dependencies:
+ '@prisma/config': 6.19.3
+ '@prisma/engines': 6.19.3
+ optionalDependencies:
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - magicast
+
+ pure-rand@6.1.0: {}
+
+ rc9@2.1.2:
+ dependencies:
+ defu: 6.1.7
+ destr: 2.0.5
+
+ react-dom@19.2.7(react@19.2.7):
+ dependencies:
+ react: 19.2.7
+ scheduler: 0.27.0
+
+ react-leaflet@5.0.0(leaflet@1.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ dependencies:
+ '@react-leaflet/core': 3.0.0(leaflet@1.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ leaflet: 1.9.4
+ react: 19.2.7
+ react-dom: 19.2.7(react@19.2.7)
+
+ react@19.2.7: {}
+
+ readdirp@4.1.2: {}
+
+ rolldown@1.1.5:
+ dependencies:
+ '@oxc-project/types': 0.139.0
+ '@rolldown/pluginutils': 1.0.1
+ optionalDependencies:
+ '@rolldown/binding-android-arm64': 1.1.5
+ '@rolldown/binding-darwin-arm64': 1.1.5
+ '@rolldown/binding-darwin-x64': 1.1.5
+ '@rolldown/binding-freebsd-x64': 1.1.5
+ '@rolldown/binding-linux-arm-gnueabihf': 1.1.5
+ '@rolldown/binding-linux-arm64-gnu': 1.1.5
+ '@rolldown/binding-linux-arm64-musl': 1.1.5
+ '@rolldown/binding-linux-ppc64-gnu': 1.1.5
+ '@rolldown/binding-linux-s390x-gnu': 1.1.5
+ '@rolldown/binding-linux-x64-gnu': 1.1.5
+ '@rolldown/binding-linux-x64-musl': 1.1.5
+ '@rolldown/binding-openharmony-arm64': 1.1.5
+ '@rolldown/binding-wasm32-wasi': 1.1.5
+ '@rolldown/binding-win32-arm64-msvc': 1.1.5
+ '@rolldown/binding-win32-x64-msvc': 1.1.5
+
+ scheduler@0.27.0: {}
+
+ semver@7.8.5:
+ optional: true
+
+ serialize-error@8.1.0:
+ dependencies:
+ type-fest: 0.20.2
+
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.5
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+ optional: true
+
+ siginfo@2.0.0: {}
+
+ source-map-js@1.2.1: {}
+
+ split2@4.2.0: {}
+
+ stackback@0.0.2: {}
+
+ std-env@4.2.0: {}
+
+ styled-jsx@5.1.6(react@19.2.7):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.2.7
+
+ tailwindcss@4.3.3: {}
+
+ tapable@2.3.3: {}
+
+ tinybench@2.9.0: {}
+
+ tinyexec@1.2.4: {}
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.5)
+ picomatch: 4.0.5
+
+ tinyrainbow@3.1.0: {}
+
+ tslib@2.8.1: {}
+
+ tsx@4.23.1:
+ dependencies:
+ esbuild: 0.28.1
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ type-fest@0.20.2: {}
+
+ typescript@5.9.3: {}
+
+ undici-types@6.21.0: {}
+
+ vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1):
+ dependencies:
+ lightningcss: 1.33.0
+ picomatch: 4.0.5
+ postcss: 8.5.21
+ rolldown: 1.1.5
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 22.20.1
+ esbuild: 0.28.1
+ fsevents: 2.3.3
+ jiti: 2.7.0
+ tsx: 4.23.1
+
+ vitest@4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)):
+ dependencies:
+ '@vitest/expect': 4.1.10
+ '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+ '@vitest/pretty-format': 4.1.10
+ '@vitest/runner': 4.1.10
+ '@vitest/snapshot': 4.1.10
+ '@vitest/spy': 4.1.10
+ '@vitest/utils': 4.1.10
+ es-module-lexer: 2.3.1
+ expect-type: 1.4.0
+ magic-string: 0.30.21
+ obug: 2.1.4
+ pathe: 2.0.3
+ picomatch: 4.0.5
+ std-env: 4.2.0
+ tinybench: 2.9.0
+ tinyexec: 1.2.4
+ tinyglobby: 0.2.17
+ tinyrainbow: 3.1.0
+ vite: 8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 22.20.1
+ transitivePeerDependencies:
+ - msw
+
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+
+ xtend@4.0.2: {}
+
+ zod@3.25.76: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..a1792e0
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,10 @@
+packages:
+ - "apps/*"
+ - "packages/*"
+ - "collectors/*"
+allowBuilds:
+ '@prisma/client': true
+ '@prisma/engines': true
+ esbuild: true
+ prisma: true
+ sharp: true
diff --git a/tsconfig.base.json b/tsconfig.base.json
new file mode 100644
index 0000000..0ce2d55
--- /dev/null
+++ b/tsconfig.base.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "strict": true,
+ "noUncheckedIndexedAccess": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "baseUrl": ".",
+ "paths": {
+ "@spechomes/database": ["packages/database/src/index.ts"],
+ "@spechomes/schemas": ["packages/schemas/src/index.ts"],
+ "@spechomes/validation": ["packages/validation/src/index.ts"],
+ "@spechomes/search": ["packages/search/src/index.ts"],
+ "@spechomes/source-registry": ["packages/source-registry/src/index.ts"],
+ "@spechomes/shared": ["packages/shared/src/index.ts"],
+ "@spechomes/shared-ui": ["packages/shared-ui/src/index.ts"],
+ "@spechomes/collectors-common": ["collectors/common/src/index.ts"]
+ }
+ }
+}
(oldest)
·
back to Homesonspec
·
shared utilities (canonicalKey/geo/queue) + zod schemas + va d635803 →