@hasna/contacts 0.6.35 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +53 -60
  2. package/dist/cli/commands/advanced.d.ts.map +1 -1
  3. package/dist/cli/commands/core.d.ts +1 -1
  4. package/dist/cli/commands/core.d.ts.map +1 -1
  5. package/dist/cli/commands/crm.d.ts.map +1 -1
  6. package/dist/cli/index.js +9137 -38536
  7. package/dist/cli/legacy.d.ts +18 -0
  8. package/dist/cli/legacy.d.ts.map +1 -0
  9. package/dist/cli/status-domain.preload.d.ts +2 -0
  10. package/dist/cli/status-domain.preload.d.ts.map +1 -0
  11. package/dist/cli/storage.d.ts.map +1 -1
  12. package/dist/cloud/client-config.d.ts +6 -0
  13. package/dist/cloud/client-config.d.ts.map +1 -0
  14. package/dist/cloud/http-storage.d.ts +40 -69
  15. package/dist/cloud/http-storage.d.ts.map +1 -1
  16. package/dist/db/database.d.ts +1 -1
  17. package/dist/db/database.d.ts.map +1 -1
  18. package/dist/db/paths.d.ts +18 -0
  19. package/dist/db/paths.d.ts.map +1 -1
  20. package/dist/generated/storage-kit/index.d.ts +0 -1
  21. package/dist/generated/storage-kit/index.d.ts.map +1 -1
  22. package/dist/generated/storage-kit/pool.d.ts +13 -3
  23. package/dist/generated/storage-kit/pool.d.ts.map +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +373 -5573
  26. package/dist/lib/images.d.ts.map +1 -1
  27. package/dist/lib/vault.d.ts +5 -1
  28. package/dist/lib/vault.d.ts.map +1 -1
  29. package/dist/mcp/handlers/advanced.d.ts.map +1 -1
  30. package/dist/mcp/handlers/core.d.ts +1 -1
  31. package/dist/mcp/index.js +816 -5805
  32. package/dist/mcp/storage-tools.d.ts.map +1 -1
  33. package/dist/mcp/tools.d.ts +3 -3
  34. package/dist/sdk/index.d.ts +15 -13
  35. package/dist/sdk/index.d.ts.map +1 -1
  36. package/dist/sdk/index.js +44 -1
  37. package/dist/server/cloud.d.ts +6 -7
  38. package/dist/server/cloud.d.ts.map +1 -1
  39. package/dist/server/index.d.ts +2 -1
  40. package/dist/server/index.d.ts.map +1 -1
  41. package/dist/server/index.js +3744 -34863
  42. package/dist/server/security.d.ts +1 -1
  43. package/dist/server/security.d.ts.map +1 -1
  44. package/dist/server/serve.d.ts.map +1 -1
  45. package/dist/store/index.d.ts +66 -93
  46. package/dist/store/index.d.ts.map +1 -1
  47. package/dist/types/store-dto.d.ts +273 -0
  48. package/dist/types/store-dto.d.ts.map +1 -0
  49. package/hasna.contract.json +63 -10
  50. package/package.json +22 -11
  51. package/dashboard/dist/assets/index-0l6aQb1t.css +0 -1
  52. package/dashboard/dist/assets/index-opnZdkVD.js +0 -229
  53. package/dashboard/dist/index.html +0 -13
  54. package/dist/generated/storage-kit/mode.d.ts +0 -48
  55. package/dist/generated/storage-kit/mode.d.ts.map +0 -1
@@ -0,0 +1,273 @@
1
+ /** Pure public client DTOs. Exact legacy signature equivalence is tested; no database handles. */
2
+ import type * as Domain from "./index.js";
3
+ export interface ListRelationshipsOptions {
4
+ contact_id?: string;
5
+ relationship_type?: Domain.ContactRelationship["relationship_type"];
6
+ }
7
+ export interface ListCompanyRelationshipsOptions {
8
+ contact_id?: string;
9
+ company_id?: string;
10
+ relationship_type?: Domain.CompanyRelationship["relationship_type"];
11
+ }
12
+ export interface ListActivityOptions {
13
+ contact_id?: string;
14
+ company_id?: string;
15
+ limit?: number;
16
+ offset?: number;
17
+ }
18
+ export interface ListVendorCommsOptions {
19
+ type?: Domain.VendorCommType;
20
+ status?: Domain.VendorCommStatus;
21
+ direction?: Domain.VendorCommDirection;
22
+ }
23
+ export interface ListContactTasksOptions {
24
+ contact_id?: string;
25
+ entity_id?: string;
26
+ status?: Domain.ContactTask["status"];
27
+ priority?: Domain.ContactTask["priority"];
28
+ }
29
+ export interface ListDealsOptions {
30
+ stage?: Domain.DealStage;
31
+ contact_id?: string;
32
+ company_id?: string;
33
+ }
34
+ export interface ListEventsOptions {
35
+ contact_id?: string;
36
+ company_id?: string;
37
+ type?: Domain.EventType;
38
+ date_from?: string;
39
+ date_to?: string;
40
+ }
41
+ export interface CreateJobEntryInput {
42
+ company_name: string;
43
+ title?: string;
44
+ company_id?: string;
45
+ start_date?: string;
46
+ end_date?: string;
47
+ is_current?: boolean;
48
+ inferred?: boolean;
49
+ source?: string;
50
+ }
51
+ export interface CreateLearningInput {
52
+ content: string;
53
+ type?: ContactLearning["type"];
54
+ confidence?: number;
55
+ importance?: number;
56
+ learned_by?: string;
57
+ session_id?: string;
58
+ visibility?: ContactLearning["visibility"];
59
+ tags?: string[];
60
+ }
61
+ export interface ContactLearning {
62
+ id: string;
63
+ contact_id: string;
64
+ content: string;
65
+ type: "preference" | "fact" | "inference" | "warning" | "signal";
66
+ confidence: number;
67
+ importance: number;
68
+ learned_by?: string | null;
69
+ session_id?: string | null;
70
+ visibility: "private" | "shared" | "human";
71
+ tags: string[];
72
+ confirmed_count: number;
73
+ contradicts_id?: string | null;
74
+ created_at: string;
75
+ updated_at: string;
76
+ }
77
+ export interface FreshnessScore {
78
+ contact_id: string;
79
+ overall_score: number;
80
+ fields: FieldFreshness[];
81
+ stale_fields: string[];
82
+ verified_fields: string[];
83
+ }
84
+ export interface FieldFreshness {
85
+ field_name: string;
86
+ value: string | null;
87
+ last_verified_at: string | null;
88
+ source: string | null;
89
+ confidence: "verified" | "inferred" | "imported" | "stale" | "unknown";
90
+ days_old: number | null;
91
+ }
92
+ export type OrgEdgeType = "reports_to" | "manages" | "collaborates_with" | "peer";
93
+ export type AccountRole = "economic_buyer" | "technical_evaluator" | "champion" | "blocker" | "influencer" | "user" | "sponsor" | "other";
94
+ export interface CreateDocumentInput {
95
+ contact_id: string;
96
+ doc_type: DocumentType;
97
+ label?: string;
98
+ value: string;
99
+ file_path?: string;
100
+ metadata?: Record<string, unknown>;
101
+ expires_at?: string;
102
+ }
103
+ export type DocumentType = "other" | "passport" | "national_id" | "tax_id" | "ssn" | "drivers_license" | "bank_account" | "visa" | "insurance" | "contract" | "certificate" | "medical_record" | "prescription" | "allergy_list" | "vaccination" | "blood_type" | "health_insurance" | "medical_condition" | "emergency_contact_medical";
104
+ export interface SetHealthInput {
105
+ blood_type?: string;
106
+ allergies?: string[];
107
+ medical_conditions?: string[];
108
+ medications?: string[];
109
+ emergency_contacts?: EmergencyContact[];
110
+ health_insurance_provider?: string;
111
+ health_insurance_id?: string;
112
+ primary_physician?: string;
113
+ primary_physician_phone?: string;
114
+ organ_donor?: boolean;
115
+ notes?: string;
116
+ }
117
+ export interface EmergencyContact {
118
+ name: string;
119
+ phone: string;
120
+ relationship: string;
121
+ }
122
+ export interface ContactHealth {
123
+ id: string;
124
+ contact_id: string;
125
+ blood_type: string | null;
126
+ allergies: string[];
127
+ medical_conditions: string[];
128
+ medications: string[];
129
+ emergency_contacts: EmergencyContact[];
130
+ health_insurance_provider: string | null;
131
+ health_insurance_id: string | null;
132
+ primary_physician: string | null;
133
+ primary_physician_phone: string | null;
134
+ organ_donor: boolean;
135
+ notes: string | null;
136
+ created_at: string;
137
+ updated_at: string;
138
+ }
139
+ export interface SuppressInput {
140
+ channel: Domain.AudienceChannel;
141
+ address: string;
142
+ contact_id?: string;
143
+ reason?: string;
144
+ }
145
+ export interface SuppressionSyncResult {
146
+ adapter: string;
147
+ dry_run: boolean;
148
+ pending: number;
149
+ pushed: number;
150
+ failed: {
151
+ address: string;
152
+ error: string;
153
+ }[];
154
+ synced_at: string | null;
155
+ }
156
+ export interface NetworkStats {
157
+ total_contacts: number;
158
+ total_companies: number;
159
+ owned_entities: number;
160
+ total_tags: number;
161
+ total_groups: number;
162
+ total_deals: number;
163
+ total_events: number;
164
+ cold_30d: number;
165
+ cold_60d: number;
166
+ cold_never: number;
167
+ contacts_with_email: number;
168
+ contacts_with_phone: number;
169
+ contacts_no_company: number;
170
+ overdue_tasks: number;
171
+ pending_applications: number;
172
+ missing_invoices: number;
173
+ upcoming_7d: number;
174
+ notes_count: number;
175
+ active_deals_value: number;
176
+ }
177
+ export type contactsCreateContactInput0 = Domain.CreateContactInput;
178
+ export type contactsUpdateContactInput1 = Domain.UpdateContactInput;
179
+ export type contactsListContactsInput0 = Domain.ContactListOptions | undefined;
180
+ export type contactsListContactsResult = {
181
+ contacts: Domain.ContactWithDetails[];
182
+ total: number;
183
+ };
184
+ export type contactsGetContactResult = Domain.ContactWithDetails;
185
+ export type contactsAddEmailToContactInput1 = Domain.CreateEmailInput;
186
+ export type contactsAddPhoneToContactInput1 = Domain.CreatePhoneInput;
187
+ export type companiesCreateCompanyInput0 = Domain.CreateCompanyInput;
188
+ export type companiesUpdateCompanyInput1 = Domain.UpdateCompanyInput;
189
+ export type companiesListCompaniesInput0 = Domain.CompanyListOptions | undefined;
190
+ export type companiesListCompaniesResult = {
191
+ companies: Domain.CompanyWithDetails[];
192
+ total: number;
193
+ };
194
+ export type tagsCreateTagInput0 = Domain.CreateTagInput;
195
+ export type groupsCreateGroupInput1 = Domain.CreateGroupInput;
196
+ export type groupsUpdateGroupInput2 = Domain.UpdateGroupInput;
197
+ export type relationshipsCreateRelationshipInput0 = Domain.CreateRelationshipInput;
198
+ export type relationshipsListRelationshipsInput0 = ListRelationshipsOptions | undefined;
199
+ export type relationshipsCreateCompanyRelationshipInput0 = Domain.CreateCompanyRelationshipInput;
200
+ export type relationshipsListCompanyRelationshipsInput0 = ListCompanyRelationshipsOptions | undefined;
201
+ export type activityListActivityInput0 = ListActivityOptions | undefined;
202
+ export type vendorCommsLogVendorCommunicationInput0 = Domain.CreateVendorCommunicationInput;
203
+ export type vendorCommsListVendorCommunicationsInput1 = ListVendorCommsOptions | undefined;
204
+ export type contactTasksCreateContactTaskInput0 = Domain.CreateContactTaskInput;
205
+ export type contactTasksListContactTasksInput0 = ListContactTasksOptions | undefined;
206
+ export type contactTasksUpdateContactTaskInput1 = Domain.UpdateContactTaskInput;
207
+ export type applicationsCreateApplicationInput0 = Domain.CreateApplicationInput;
208
+ export type applicationsListApplicationsInput0 = Domain.ListApplicationsOptions | undefined;
209
+ export type applicationsUpdateApplicationInput1 = Domain.UpdateApplicationInput;
210
+ export type orgMembersAddOrgMemberInput0 = Domain.CreateOrgMemberInput;
211
+ export type orgMembersUpdateOrgMemberInput1 = Domain.UpdateOrgMemberInput;
212
+ export type dealsCreateDealInput0 = Domain.CreateDealInput;
213
+ export type dealsListDealsInput0 = ListDealsOptions | undefined;
214
+ export type dealsUpdateDealInput1 = Domain.UpdateDealInput;
215
+ export type eventsLogEventInput0 = Domain.CreateEventInput;
216
+ export type eventsListEventsInput0 = ListEventsOptions | undefined;
217
+ export type jobHistoryAddJobEntryInput1 = CreateJobEntryInput;
218
+ export type learningsSaveLearningInput1 = CreateLearningInput;
219
+ export type learningsGetLearningsInput1 = {
220
+ type?: string;
221
+ min_importance?: number;
222
+ visibility?: string;
223
+ } | undefined;
224
+ export type learningsSearchLearningsInput1 = {
225
+ type?: string;
226
+ contact_id?: string;
227
+ } | undefined;
228
+ export type identityResolveByPartialInput0 = {
229
+ name?: string;
230
+ email?: string;
231
+ phone?: string;
232
+ linkedin_url?: string;
233
+ };
234
+ export type freshnessGetFreshnessScoreResult = FreshnessScore;
235
+ export type orgChartAddOrgChartEdgeInput3 = OrgEdgeType;
236
+ export type orgChartSetDealContactRoleInput2 = AccountRole;
237
+ export type documentsAddDocumentInput0 = CreateDocumentInput;
238
+ export type healthSetHealthDataInput1 = SetHealthInput;
239
+ export type healthGetHealthDataResult = ContactHealth | null;
240
+ export type audiencesCreateAudienceInput0 = Domain.CreateAudienceInput;
241
+ export type audiencesGetAudienceResult = Domain.Audience;
242
+ export type audiencesUpdateAudienceInput1 = Domain.UpdateAudienceInput;
243
+ export type audiencesResolveAudienceInput1 = "email" | "telegram" | "sms";
244
+ export type audiencesResolveAudienceResult = Domain.AudienceResolution;
245
+ export type audiencesSetContactConsentInput1 = "email" | "telegram" | "sms";
246
+ export type audiencesSetContactConsentInput2 = "opt_in" | "opt_out" | "unknown";
247
+ export type audiencesSuppressAddressInput0 = SuppressInput;
248
+ export type audiencesUnsuppressAddressInput0 = "email" | "telegram" | "sms";
249
+ export type audiencesListSuppressionsInput0 = {
250
+ channel?: Domain.AudienceChannel;
251
+ unsyncedOnly?: boolean;
252
+ } | undefined;
253
+ export type mailerySyncSyncSuppressionsResult = Promise<SuppressionSyncResult>;
254
+ export type contextAssembleContextInput1 = "meeting_prep" | "deal_review" | "outreach" | "research" | undefined;
255
+ export type statsGetNetworkStatsResult = NetworkStats;
256
+ export type meetingCaptureIngestMeetingParticipantsInput0 = {
257
+ title: string;
258
+ event_date: string;
259
+ attendees: Array<{
260
+ name: string;
261
+ email: string;
262
+ }>;
263
+ context?: string;
264
+ };
265
+ /** The HTTPS client has no local storage diagnostics endpoint. */
266
+ export type ContactsStorageStatus = null;
267
+ export interface StorageTableStatus {
268
+ table: string;
269
+ ok: boolean;
270
+ rows: number | null;
271
+ error?: string;
272
+ }
273
+ //# sourceMappingURL=store-dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-dto.d.ts","sourceRoot":"","sources":["../../src/types/store-dto.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,73 @@
1
1
  {
2
+ "$schema": "./node_modules/@hasna/contracts/dist/hasna.contract.schema.json",
2
3
  "schema": "hasna.service_contract.v1",
3
4
  "name": "contacts",
4
5
  "class": "service",
5
6
  "contractVersion": "v1",
6
- "kitVersion": "0.4.2",
7
- "description": "Contact & company management for AI coding agents. CLI + MCP + HTTP API (contacts-serve) + generated SDK. Cloud mode (HASNA_CONTACTS_STORAGE_MODE=cloud / HASNA_CONTACTS_DATABASE_URL set) is PURE REMOTE per Amendment A1: the serve process reads/writes the shared cloud Postgres directly with API-key auth via @hasna/contracts. PRIVATE repo — synthetic seeds only, never real PII.",
8
- "bins": ["contacts", "contacts-mcp", "contacts-serve"],
7
+ "kitVersion": "0.14.2",
8
+ "description": "Contact and company management for AI coding agents. Public CLI, MCP, and SDK clients use one explicitly configured authenticated HTTPS /v1 authority and never open SQLite or PostgreSQL. contacts-serve is the server-only PostgreSQL/API-key boundary.",
9
+ "bins": [
10
+ "contacts",
11
+ "contacts-mcp",
12
+ "contacts-serve"
13
+ ],
14
+ "hosting": [
15
+ "user-hosted",
16
+ "hasna-saas"
17
+ ],
18
+ "serviceSurfaces": [
19
+ {
20
+ "name": "http-api",
21
+ "kind": "api",
22
+ "status": "supported",
23
+ "bin": "contacts-serve",
24
+ "authMode": "api-key",
25
+ "health": { "method": "GET", "path": "/health", "public": true },
26
+ "readiness": { "method": "GET", "path": "/ready", "public": true },
27
+ "version": { "method": "GET", "path": "/version", "public": true },
28
+ "apiBasePath": "/v1",
29
+ "openApiPath": "/openapi.json"
30
+ },
31
+ {
32
+ "name": "typescript-sdk",
33
+ "kind": "sdk",
34
+ "status": "supported",
35
+ "authMode": "api-key",
36
+ "exportSubpath": "./sdk",
37
+ "clientClassName": "ContactsV1Client",
38
+ "generatedFrom": "/openapi.json"
39
+ },
40
+ {
41
+ "name": "mcp",
42
+ "kind": "mcp",
43
+ "status": "supported",
44
+ "mcpBin": "contacts-mcp",
45
+ "authMode": "api-key"
46
+ },
47
+ {
48
+ "name": "cli",
49
+ "kind": "cli",
50
+ "status": "supported",
51
+ "bin": "contacts",
52
+ "authMode": "api-key"
53
+ }
54
+ ],
9
55
  "storage": {
10
- "mode": "local",
56
+ "backend": "postgresql",
57
+ "engines": ["postgresql"],
11
58
  "envPrefix": "HASNA_CONTACTS_",
12
59
  "aliasEnvPrefix": "CONTACTS_",
13
- "databaseUrlSecretRef": "hasna/oss/contacts/database-url",
14
- "sqlitePath": "~/.hasna/contacts/contacts.db"
60
+ "pgTestGate": {
61
+ "envVar": "HASNA_CONTACTS_TEST_DATABASE_URL",
62
+ "command": "HASNA_CONTACTS_TEST_DATABASE_URL=\"${HASNA_CONTACTS_TEST_DATABASE_URL:?point it at a throwaway Postgres; the live-PG gate must not pass without one}\" CONTACTS_REQUIRE_LIVE_POSTGRES=1 bun test src/server/postgres-live.test.ts"
63
+ }
15
64
  },
16
65
  "metadata": {
66
+ "release": {
67
+ "artifactScan": {
68
+ "script": "scan:artifact"
69
+ }
70
+ },
17
71
  "service": {
18
72
  "port": 19428,
19
73
  "healthPath": "/health",
@@ -21,12 +75,11 @@
21
75
  "versionPath": "/version",
22
76
  "openapiPath": "/openapi.json",
23
77
  "apiVersion": "v1",
24
- "auth": "api-key",
25
- "signingSecretSecretRef": "hasna/oss/contacts/api-key-signing-secret"
78
+ "auth": "api-key"
26
79
  },
27
80
  "client": {
28
- "apiUrlEnv": "CONTACTS_API_URL",
29
- "apiKeyEnv": "CONTACTS_API_KEY"
81
+ "apiUrlEnv": "HASNA_CONTACTS_API_URL",
82
+ "apiKeyEnv": "HASNA_CONTACTS_API_KEY"
30
83
  }
31
84
  }
32
85
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hasna/contacts",
3
- "version": "0.6.35",
4
- "description": "Contact management for AI coding agents CLI + MCP + Web",
3
+ "version": "0.7.0",
4
+ "description": "Contact management for AI coding agents \u2014 CLI + MCP + Web",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -22,7 +22,6 @@
22
22
  },
23
23
  "files": [
24
24
  "dist",
25
- "dashboard/dist",
26
25
  "migrations",
27
26
  "hasna.contract.json",
28
27
  "LICENSE",
@@ -31,21 +30,22 @@
31
30
  "README.md"
32
31
  ],
33
32
  "scripts": {
34
- "clean": "rm -rf dist dashboard/dist",
33
+ "clean": "rm -rf dist",
35
34
  "clean:core": "rm -rf dist",
36
- "build": "bun run clean && cd dashboard && bun run build && cd .. && bun run build:bundles && tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
35
+ "build": "bun run clean && bun run build:bundles && tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
37
36
  "build:core": "bun run clean:core && bun run build:bundles && tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
38
37
  "build:bundles": "bun run scripts/build-bundles.ts",
39
38
  "build:server": "rm -rf dist/server dist/sdk && bun run scripts/build-bundles.ts --server-only",
40
39
  "generate:sdk": "bun run scripts/generate-sdk.ts",
41
40
  "migrate": "bun run scripts/migrate.ts",
41
+ "scan:artifact": "bun scripts/scan-artifact.ts",
42
42
  "typecheck": "tsc --noEmit",
43
43
  "test": "bun test",
44
44
  "dev:cli": "bun run src/cli/index.tsx",
45
45
  "dev:mcp": "bun run src/mcp/index.ts",
46
46
  "dev:serve": "bun run src/server/index.ts",
47
- "prepublishOnly": "bun run typecheck && bun test && bun run build",
48
- "postinstall": "install -d -m 700 \"$HOME/.hasna/contacts\" \"$HOME/.hasna/contacts/backups\" \"$HOME/.hasna/contacts/images\" \"$HOME/.hasna/contacts/documents\" 2>/dev/null || mkdir -p $HOME/.hasna/contacts/{backups,images,documents} 2>/dev/null || true"
47
+ "prepack": "bun run scan:artifact",
48
+ "prepublishOnly": "bun run typecheck && bun test && bun run build && bun run scan:artifact"
49
49
  },
50
50
  "keywords": [
51
51
  "contacts",
@@ -75,7 +75,7 @@
75
75
  "author": "Andrei Hasna <andrei@hasna.com>",
76
76
  "license": "Apache-2.0",
77
77
  "dependencies": {
78
- "@hasna/contracts": "^0.5.1",
78
+ "@hasna/contracts": "0.14.2",
79
79
  "@hasna/events": "^0.1.6",
80
80
  "chalk": "^5.4.1",
81
81
  "commander": "^13.1.0",
@@ -85,11 +85,22 @@
85
85
  "zod": "^3.24.2"
86
86
  },
87
87
  "devDependencies": {
88
- "@types/bun": "^1.2.4",
88
+ "@modelcontextprotocol/sdk": "^1.12.1",
89
+ "@tailwindcss/vite": "^4.1.4",
90
+ "@tanstack/react-table": "^8.21.2",
91
+ "@types/bun": "1.3.14",
89
92
  "@types/pg": "^8.11.11",
90
93
  "@types/react": "^18.3.18",
91
- "@modelcontextprotocol/sdk": "^1.12.1",
92
- "typescript": "^5.7.3"
94
+ "@vitejs/plugin-react": "^4.4.1",
95
+ "class-variance-authority": "^0.7.1",
96
+ "clsx": "^2.1.1",
97
+ "lucide-react": "^0.468.0",
98
+ "radix-ui": "^1.4.2",
99
+ "react-dom": "^18.3.1",
100
+ "tailwind-merge": "^3.0.2",
101
+ "tailwindcss": "^4.1.4",
102
+ "typescript": "^5.7.3",
103
+ "vite": "^6.3.0"
93
104
  },
94
105
  "overrides": {
95
106
  "fast-uri": "3.1.3"
@@ -1 +0,0 @@
1
- /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-duration:initial;--tw-space-x-reverse:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-800:oklch(47.6% .114 61.907);--color-yellow-950:oklch(28.6% .066 53.813);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-green-950:oklch(26.6% .065 152.934);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:221.2 83.2% 53.3%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:221.2 83.2% 53.3%;--radius:.5rem}.dark{--background:222.2 84% 4.9%;--foreground:210 40% 98%;--card:222.2 84% 4.9%;--card-foreground:210 40% 98%;--popover:222.2 84% 4.9%;--popover-foreground:210 40% 98%;--primary:217.2 91.2% 59.8%;--primary-foreground:222.2 47.4% 11.2%;--secondary:217.2 32.6% 17.5%;--secondary-foreground:210 40% 98%;--muted:217.2 32.6% 17.5%;--muted-foreground:215 20.2% 65.1%;--accent:217.2 32.6% 17.5%;--accent-foreground:210 40% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:210 40% 98%;--border:217.2 32.6% 17.5%;--input:217.2 32.6% 17.5%;--ring:224.3 76.3% 48%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));min-height:100vh;margin:0;font-family:system-ui,-apple-system,sans-serif}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.end{inset-inline-end:var(--spacing)}.top-4{top:calc(var(--spacing) * 4)}.top-\[50\%\]{top:50%}.right-1{right:calc(var(--spacing) * 1)}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.right-6{right:calc(var(--spacing) * 6)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-2{left:calc(var(--spacing) * 2)}.left-3{left:calc(var(--spacing) * 3)}.left-\[50\%\]{left:50%}.z-50{z-index:50}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.h-\[calc\(100vh-56px\)\]{height:calc(100vh - 56px)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-full{height:100%}.h-px{height:1px}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-9{width:calc(var(--spacing) * 9)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.max-w-7xl{max-width:var(--container-7xl)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-1{--tw-translate-y:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.rotate-0{rotate:0deg}.rotate-90{rotate:90deg}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-green-200{border-color:var(--color-green-200)}.border-red-200{border-color:var(--color-red-200)}.border-transparent{border-color:#0000}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-green-50{background-color:var(--color-green-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-yellow-50{background-color:var(--color-yellow-50)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pr-9{padding-right:calc(var(--spacing) * 9)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-8{padding-left:calc(var(--spacing) * 8)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-green-800{color:var(--color-green-800)}.text-red-800{color:var(--color-red-800)}.text-white{color:var(--color-white)}.text-yellow-800{color:var(--color-yellow-800)}.capitalize{text-transform:capitalize}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}@media(hover:hover){.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-100:hover{opacity:1}}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}@media(min-width:40rem){.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}:where(.sm\:space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius-lg)}.sm\:text-left{text-align:left}}@media(min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media(prefers-color-scheme:dark){.dark\:scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:-rotate-90{rotate:-90deg}.dark\:rotate-0{rotate:0deg}.dark\:border-green-900{border-color:var(--color-green-900)}.dark\:border-red-900{border-color:var(--color-red-900)}.dark\:bg-green-950{background-color:var(--color-green-950)}.dark\:bg-red-950{background-color:var(--color-red-950)}.dark\:bg-yellow-950{background-color:var(--color-yellow-950)}.dark\:text-green-200{color:var(--color-green-200)}.dark\:text-red-200{color:var(--color-red-200)}.dark\:text-yellow-200{color:var(--color-yellow-200)}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing) * 0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-duration{syntax:"*";inherits:false}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}