@honestdigital/vehicle-service-types 1.0.2 → 1.0.3
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.
Potentially problematic release.
This version of @honestdigital/vehicle-service-types might be problematic. Click here for more details.
- package/dist/config/constants.d.ts +1 -48
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/database.d.ts +3 -26
- package/dist/config/database.d.ts.map +1 -1
- package/dist/config/fieldMappings.d.ts +98 -0
- package/dist/config/fieldMappings.d.ts.map +1 -0
- package/dist/db/index.d.ts +12 -26
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/schema.d.ts +6 -6
- package/dist/repositories/vehicleInventory.d.ts +7 -3
- package/dist/repositories/vehicleInventory.d.ts.map +1 -1
- package/dist/routers/index.d.ts +64 -29
- package/dist/routers/index.d.ts.map +1 -1
- package/dist/routers/inventory.d.ts +70 -29
- package/dist/routers/inventory.d.ts.map +1 -1
- package/dist/schemas/vehicle.schema.d.ts +12 -12
- package/dist/services/mmt.d.ts +6 -4
- package/dist/services/mmt.d.ts.map +1 -1
- package/dist/services/vehicleSqlBuilder.d.ts.map +1 -1
- package/dist/services/vehicleTransformService.d.ts.map +1 -1
- package/dist/trpc.d.ts +1 -1
- package/dist/types/search.d.ts +62 -62
- package/package.json +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/migrations/run-manual.d.ts +0 -2
- package/dist/migrations/run-manual.d.ts.map +0 -1
- package/dist/migrations/runner.d.ts +0 -2
- package/dist/migrations/runner.d.ts.map +0 -1
- package/dist/scripts/backfillVehicleColorCodes.d.ts +0 -2
- package/dist/scripts/backfillVehicleColorCodes.d.ts.map +0 -1
- package/dist/scripts/db-helper.d.ts +0 -4
- package/dist/scripts/db-helper.d.ts.map +0 -1
- package/dist/scripts/fetchAllChromeImages.d.ts +0 -2
- package/dist/scripts/fetchAllChromeImages.d.ts.map +0 -1
- package/dist/scripts/fetchChromeImage.d.ts +0 -2
- package/dist/scripts/fetchChromeImage.d.ts.map +0 -1
- package/dist/scripts/fetchChromeImageDirect.d.ts +0 -2
- package/dist/scripts/fetchChromeImageDirect.d.ts.map +0 -1
- package/dist/scripts/importUsedVehicles.d.ts +0 -1
- package/dist/scripts/importUsedVehicles.d.ts.map +0 -1
- package/dist/scripts/mock-color-data.d.ts +0 -7
- package/dist/scripts/mock-color-data.d.ts.map +0 -1
- package/dist/scripts/populateColorCodes.d.ts +0 -2
- package/dist/scripts/populateColorCodes.d.ts.map +0 -1
- package/dist/services/VehicleSearchService.d.ts +0 -40
- package/dist/services/VehicleSearchService.d.ts.map +0 -1
- package/dist/services/pricing.d.ts +0 -81
- package/dist/services/pricing.d.ts.map +0 -1
|
@@ -34,54 +34,7 @@ export declare const API_CONFIG: {
|
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
|
-
export
|
|
38
|
-
API_TO_DB: {
|
|
39
|
-
brand: string;
|
|
40
|
-
model: string;
|
|
41
|
-
year: string;
|
|
42
|
-
vin: string;
|
|
43
|
-
stockNumber: string;
|
|
44
|
-
trim: string;
|
|
45
|
-
status: string;
|
|
46
|
-
fuelType: string;
|
|
47
|
-
bodyStyle: string;
|
|
48
|
-
exteriorColor: string;
|
|
49
|
-
interiorColor: string;
|
|
50
|
-
transmission: string;
|
|
51
|
-
drivetrain: string;
|
|
52
|
-
doors: string;
|
|
53
|
-
location: string;
|
|
54
|
-
price: string;
|
|
55
|
-
mileage: string;
|
|
56
|
-
id: string;
|
|
57
|
-
createdAt: string;
|
|
58
|
-
updatedAt: string;
|
|
59
|
-
tenantId: string;
|
|
60
|
-
};
|
|
61
|
-
DB_TO_API: {
|
|
62
|
-
brand: string;
|
|
63
|
-
model: string;
|
|
64
|
-
year: string;
|
|
65
|
-
vin: string;
|
|
66
|
-
stock_number: string;
|
|
67
|
-
trim: string;
|
|
68
|
-
status: string;
|
|
69
|
-
fuel_type: string;
|
|
70
|
-
body_style: string;
|
|
71
|
-
exterior_color: string;
|
|
72
|
-
interior_color: string;
|
|
73
|
-
transmission: string;
|
|
74
|
-
drivetrain: string;
|
|
75
|
-
doors: string;
|
|
76
|
-
location: string;
|
|
77
|
-
price: string;
|
|
78
|
-
mileage: string;
|
|
79
|
-
id: string;
|
|
80
|
-
created_at: string;
|
|
81
|
-
updated_at: string;
|
|
82
|
-
tenant_id: string;
|
|
83
|
-
};
|
|
84
|
-
};
|
|
37
|
+
export { FIELD_MAPPINGS as DB_FIELD_MAPPINGS } from './fieldMappings';
|
|
85
38
|
export declare const FILTER_CONFIG: {
|
|
86
39
|
FILTER_PARAMS: readonly ["brand", "model", "trim", "year", "status", "location", "drivetrain", "doors", "fuelType", "bodyStyle", "exteriorColor", "interiorColor"];
|
|
87
40
|
RANGE_PARAMS: readonly ["price", "mileage"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/config/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;CAoBxB,CAAA;AAGD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;CAsBtB,CAAA;AAGD,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/config/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;CAoBxB,CAAA;AAGD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;CAsBtB,CAAA;AAGD,OAAO,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAGrE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;CAgCzB,CAAA;AAGD,eAAO,MAAM,QAAQ;;;;;;;CAOpB,CAAA;AAGD,eAAO,MAAM,UAAU;;;CAGtB,CAAA;AAGD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;CAiBvB,CAAA"}
|
|
@@ -3,33 +3,10 @@
|
|
|
3
3
|
* Migrated to Neon serverless driver for Cloudflare Workers compatibility
|
|
4
4
|
* Re-exports from @/db for backward compatibility
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
import type { SimplifiedPool } from '@/db';
|
|
7
|
+
export { closeDb as closeDrizzleDb, getDb, getDbPoolStats, getPool, type SimplifiedPool } from '@/db';
|
|
7
8
|
export * from '@/db/schema';
|
|
8
|
-
export declare function getDbPool():
|
|
9
|
-
query: <_T = any>(text: string, params?: unknown[]) => Promise<any>;
|
|
10
|
-
Promise: typeof Promise;
|
|
11
|
-
connect(): Promise<import("@neondatabase/serverless").PoolClient>;
|
|
12
|
-
connect(callback: (err: Error | undefined, client: import("@neondatabase/serverless").PoolClient | undefined, done: (release?: any) => void) => void): void;
|
|
13
|
-
Client: typeof import("@neondatabase/serverless").Client;
|
|
14
|
-
hasFetchUnsupportedListeners: boolean;
|
|
15
|
-
addListener: (event: "error" | "connect" | "acquire" | "release" | "remove", listener: any) => import("@neondatabase/serverless").Pool;
|
|
16
|
-
totalCount: number;
|
|
17
|
-
idleCount: number;
|
|
18
|
-
waitingCount: number;
|
|
19
|
-
once<K>(eventName: string | symbol, listener: (...args: any[]) => void): import("@neondatabase/serverless").Pool;
|
|
20
|
-
removeListener<K>(eventName: string | symbol, listener: (...args: any[]) => void): import("@neondatabase/serverless").Pool;
|
|
21
|
-
off<K>(eventName: string | symbol, listener: (...args: any[]) => void): import("@neondatabase/serverless").Pool;
|
|
22
|
-
removeAllListeners(eventName?: string | symbol | undefined): import("@neondatabase/serverless").Pool;
|
|
23
|
-
setMaxListeners(n: number): import("@neondatabase/serverless").Pool;
|
|
24
|
-
getMaxListeners(): number;
|
|
25
|
-
listeners<K>(eventName: string | symbol): Function[];
|
|
26
|
-
rawListeners<K>(eventName: string | symbol): Function[];
|
|
27
|
-
emit<K>(eventName: string | symbol, ...args: any[]): boolean;
|
|
28
|
-
listenerCount<K>(eventName: string | symbol, listener?: Function | undefined): number;
|
|
29
|
-
prependListener<K>(eventName: string | symbol, listener: (...args: any[]) => void): import("@neondatabase/serverless").Pool;
|
|
30
|
-
prependOnceListener<K>(eventName: string | symbol, listener: (...args: any[]) => void): import("@neondatabase/serverless").Pool;
|
|
31
|
-
eventNames(): (string | symbol)[];
|
|
32
|
-
};
|
|
9
|
+
export declare function getDbPool(): SimplifiedPool;
|
|
33
10
|
export declare function closeDbPool(): Promise<void>;
|
|
34
11
|
export declare function getPoolStats(): null;
|
|
35
12
|
//# sourceMappingURL=database.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/config/database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/config/database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAI1C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,MAAM,CAAA;AACrG,cAAc,aAAa,CAAA;AAG3B,wBAAgB,SAAS,IAAI,cAAc,CAG1C;AAGD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAGjD;AAGD,wBAAgB,YAAY,SAG3B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized field mappings and column definitions
|
|
3
|
+
* Single source of truth for API ↔ Database field name mappings
|
|
4
|
+
*/
|
|
5
|
+
export declare const FIELD_MAPPINGS: {
|
|
6
|
+
API_TO_DB: {
|
|
7
|
+
readonly brand: "brand";
|
|
8
|
+
readonly model: "model";
|
|
9
|
+
readonly year: "year";
|
|
10
|
+
readonly vin: "vin";
|
|
11
|
+
readonly stockNumber: "stock_number";
|
|
12
|
+
readonly trim: "trim";
|
|
13
|
+
readonly status: "status";
|
|
14
|
+
readonly fuelType: "fuel_type";
|
|
15
|
+
readonly bodyStyle: "body_style";
|
|
16
|
+
readonly exteriorColor: "exterior_color";
|
|
17
|
+
readonly interiorColor: "interior_color";
|
|
18
|
+
readonly transmission: "transmission";
|
|
19
|
+
readonly drivetrain: "drivetrain";
|
|
20
|
+
readonly doors: "doors";
|
|
21
|
+
readonly location: "location";
|
|
22
|
+
readonly price: "price";
|
|
23
|
+
readonly mileage: "mileage";
|
|
24
|
+
readonly id: "id";
|
|
25
|
+
readonly createdAt: "created_at";
|
|
26
|
+
readonly updatedAt: "updated_at";
|
|
27
|
+
readonly tenantId: "tenant_id";
|
|
28
|
+
readonly imageUrl: "image_url";
|
|
29
|
+
};
|
|
30
|
+
DB_TO_API: {
|
|
31
|
+
readonly brand: "brand";
|
|
32
|
+
readonly model: "model";
|
|
33
|
+
readonly year: "year";
|
|
34
|
+
readonly vin: "vin";
|
|
35
|
+
readonly stock_number: "stockNumber";
|
|
36
|
+
readonly trim: "trim";
|
|
37
|
+
readonly status: "status";
|
|
38
|
+
readonly fuel_type: "fuelType";
|
|
39
|
+
readonly body_style: "bodyStyle";
|
|
40
|
+
readonly exterior_color: "exteriorColor";
|
|
41
|
+
readonly interior_color: "interiorColor";
|
|
42
|
+
readonly transmission: "transmission";
|
|
43
|
+
readonly drivetrain: "drivetrain";
|
|
44
|
+
readonly doors: "doors";
|
|
45
|
+
readonly location: "location";
|
|
46
|
+
readonly price: "price";
|
|
47
|
+
readonly mileage: "mileage";
|
|
48
|
+
readonly id: "id";
|
|
49
|
+
readonly created_at: "createdAt";
|
|
50
|
+
readonly updated_at: "updatedAt";
|
|
51
|
+
readonly tenant_id: "tenantId";
|
|
52
|
+
readonly image_url: "imageUrl";
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export declare const VALID_FILTER_COLUMNS: Set<string>;
|
|
56
|
+
export declare const VALID_DATABASE_COLUMNS: Set<string>;
|
|
57
|
+
export declare const VALID_STATUS_VALUES: Set<string>;
|
|
58
|
+
/**
|
|
59
|
+
* Convert API field name (camelCase) to database field name (snake_case)
|
|
60
|
+
* @param apiFieldName - API field name in camelCase
|
|
61
|
+
* @returns Database field name in snake_case, or original if no mapping found
|
|
62
|
+
*/
|
|
63
|
+
export declare function getDbFieldName(apiFieldName: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Convert database field name (snake_case) to API field name (camelCase)
|
|
66
|
+
* @param dbFieldName - Database field name in snake_case
|
|
67
|
+
* @returns API field name in camelCase, or original if no mapping found
|
|
68
|
+
*/
|
|
69
|
+
export declare function getApiFieldName(dbFieldName: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Check if a database field name is valid for filtering
|
|
72
|
+
* @param dbFieldName - Database field name to check
|
|
73
|
+
* @returns True if the field can be used for filtering
|
|
74
|
+
*/
|
|
75
|
+
export declare function isValidFilterColumn(dbFieldName: string): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Check if a database field name is a valid column
|
|
78
|
+
* @param dbFieldName - Database field name to check
|
|
79
|
+
* @returns True if the field exists in the database
|
|
80
|
+
*/
|
|
81
|
+
export declare function isValidDatabaseColumn(dbFieldName: string): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Normalize status value to uppercase database enum format
|
|
84
|
+
* @param status - Status value (case insensitive)
|
|
85
|
+
* @returns Uppercase status ('NEW' or 'USED') or null if invalid
|
|
86
|
+
*/
|
|
87
|
+
export declare function normalizeStatusValue(status: string): 'NEW' | 'USED' | null;
|
|
88
|
+
/**
|
|
89
|
+
* Build WHERE clause conditions from filters
|
|
90
|
+
* Converts API field names to database field names and builds SQL conditions
|
|
91
|
+
* @param filters - Filter object with API field names
|
|
92
|
+
* @returns Object with SQL text and parameter values
|
|
93
|
+
*/
|
|
94
|
+
export declare function buildFilterConditions(filters: Record<string, any>): {
|
|
95
|
+
conditions: string[];
|
|
96
|
+
values: any[];
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=fieldMappings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldMappings.d.ts","sourceRoot":"","sources":["../../src/config/fieldMappings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsE1B,CAAA;AAID,eAAO,MAAM,oBAAoB,aAa/B,CAAA;AAIF,eAAO,MAAM,sBAAsB,aAuBjC,CAAA;AAGF,eAAO,MAAM,mBAAmB,aAA2B,CAAA;AAE3D;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAK1E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAA;CAAE,CAgDzC"}
|
package/dist/db/index.d.ts
CHANGED
|
@@ -3,7 +3,17 @@
|
|
|
3
3
|
* Uses Neon serverless driver compatible with edge runtime
|
|
4
4
|
*/
|
|
5
5
|
import { Pool as NeonPool } from '@neondatabase/serverless';
|
|
6
|
+
import type { QueryResult, QueryResultRow } from '@neondatabase/serverless';
|
|
6
7
|
import * as schema from './schema';
|
|
8
|
+
/**
|
|
9
|
+
* Simplified pool interface for our wrapped pool
|
|
10
|
+
* This represents the actual interface we're providing
|
|
11
|
+
*/
|
|
12
|
+
export interface SimplifiedPool {
|
|
13
|
+
query<T extends QueryResultRow = any>(text: string, params?: unknown[]): Promise<QueryResult<T>>;
|
|
14
|
+
end(): Promise<void>;
|
|
15
|
+
connect(): Promise<any>;
|
|
16
|
+
}
|
|
7
17
|
/**
|
|
8
18
|
* Get or create Drizzle database client for Workers
|
|
9
19
|
* Uses Neon serverless Pool driver compatible with Cloudflare Workers
|
|
@@ -18,37 +28,13 @@ export declare function getDb(env?: {
|
|
|
18
28
|
/**
|
|
19
29
|
* Get Pool interface for raw queries
|
|
20
30
|
* Maintains backward compatibility with existing repositories
|
|
21
|
-
* Returns
|
|
31
|
+
* Returns a simplified pool interface with query, end, and connect methods
|
|
22
32
|
* Creates a new pool for each call to avoid Cloudflare Workers cross-request I/O errors
|
|
23
33
|
* @param env Optional environment bindings from Cloudflare Workers context
|
|
24
34
|
*/
|
|
25
35
|
export declare function getPool(env?: {
|
|
26
36
|
POSTGRES_URL?: string;
|
|
27
|
-
}):
|
|
28
|
-
query: <_T = any>(text: string, params?: unknown[]) => Promise<any>;
|
|
29
|
-
Promise: typeof Promise;
|
|
30
|
-
connect(): Promise<import("@neondatabase/serverless").PoolClient>;
|
|
31
|
-
connect(callback: (err: Error | undefined, client: import("@neondatabase/serverless").PoolClient | undefined, done: (release?: any) => void) => void): void;
|
|
32
|
-
Client: typeof import("@neondatabase/serverless").Client;
|
|
33
|
-
hasFetchUnsupportedListeners: boolean;
|
|
34
|
-
addListener: (event: "error" | "connect" | "acquire" | "release" | "remove", listener: any) => NeonPool;
|
|
35
|
-
totalCount: number;
|
|
36
|
-
idleCount: number;
|
|
37
|
-
waitingCount: number;
|
|
38
|
-
once<K>(eventName: string | symbol, listener: (...args: any[]) => void): NeonPool;
|
|
39
|
-
removeListener<K>(eventName: string | symbol, listener: (...args: any[]) => void): NeonPool;
|
|
40
|
-
off<K>(eventName: string | symbol, listener: (...args: any[]) => void): NeonPool;
|
|
41
|
-
removeAllListeners(eventName?: string | symbol | undefined): NeonPool;
|
|
42
|
-
setMaxListeners(n: number): NeonPool;
|
|
43
|
-
getMaxListeners(): number;
|
|
44
|
-
listeners<K>(eventName: string | symbol): Function[];
|
|
45
|
-
rawListeners<K>(eventName: string | symbol): Function[];
|
|
46
|
-
emit<K>(eventName: string | symbol, ...args: any[]): boolean;
|
|
47
|
-
listenerCount<K>(eventName: string | symbol, listener?: Function | undefined): number;
|
|
48
|
-
prependListener<K>(eventName: string | symbol, listener: (...args: any[]) => void): NeonPool;
|
|
49
|
-
prependOnceListener<K>(eventName: string | symbol, listener: (...args: any[]) => void): NeonPool;
|
|
50
|
-
eventNames(): (string | symbol)[];
|
|
51
|
-
};
|
|
37
|
+
}): SimplifiedPool;
|
|
52
38
|
/**
|
|
53
39
|
* Close database connection gracefully
|
|
54
40
|
* No-op in Workers since connections are created per-request
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAc,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAc,MAAM,0BAA0B,CAAA;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAG3E,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAElC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;IAChG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAA;CACxB;AASD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE;;EAgBpD;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAkCvE;AAED;;;GAGG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7C;AAED;;;GAGG;AACH,wBAAgB,cAAc,SAE7B"}
|
package/dist/db/schema.d.ts
CHANGED
|
@@ -476,6 +476,7 @@ export declare const vehicles: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
476
476
|
data: {
|
|
477
477
|
lowestMonthlyPayment?: number | undefined;
|
|
478
478
|
lease?: {
|
|
479
|
+
expirationDate: string;
|
|
479
480
|
monthlyPayment: number;
|
|
480
481
|
term: number;
|
|
481
482
|
leasePrice: number;
|
|
@@ -486,16 +487,15 @@ export declare const vehicles: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
486
487
|
perMileCharge: number;
|
|
487
488
|
lender: string;
|
|
488
489
|
disclaimer: string;
|
|
489
|
-
expirationDate: string;
|
|
490
490
|
} | undefined;
|
|
491
491
|
finance?: {
|
|
492
|
+
expirationDate: string;
|
|
492
493
|
monthlyPayment: number;
|
|
493
494
|
term: number;
|
|
494
495
|
downPayment: number;
|
|
495
496
|
interestRate: number;
|
|
496
497
|
lender: string;
|
|
497
498
|
disclaimer: string;
|
|
498
|
-
expirationDate: string;
|
|
499
499
|
financeAmount: number;
|
|
500
500
|
} | undefined;
|
|
501
501
|
cash?: {
|
|
@@ -520,6 +520,7 @@ export declare const vehicles: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
520
520
|
$type: {
|
|
521
521
|
lowestMonthlyPayment?: number | undefined;
|
|
522
522
|
lease?: {
|
|
523
|
+
expirationDate: string;
|
|
523
524
|
monthlyPayment: number;
|
|
524
525
|
term: number;
|
|
525
526
|
leasePrice: number;
|
|
@@ -530,16 +531,15 @@ export declare const vehicles: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
530
531
|
perMileCharge: number;
|
|
531
532
|
lender: string;
|
|
532
533
|
disclaimer: string;
|
|
533
|
-
expirationDate: string;
|
|
534
534
|
} | undefined;
|
|
535
535
|
finance?: {
|
|
536
|
+
expirationDate: string;
|
|
536
537
|
monthlyPayment: number;
|
|
537
538
|
term: number;
|
|
538
539
|
downPayment: number;
|
|
539
540
|
interestRate: number;
|
|
540
541
|
lender: string;
|
|
541
542
|
disclaimer: string;
|
|
542
|
-
expirationDate: string;
|
|
543
543
|
financeAmount: number;
|
|
544
544
|
} | undefined;
|
|
545
545
|
cash?: {
|
|
@@ -564,8 +564,8 @@ export declare const vehicles: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
564
564
|
programId: string;
|
|
565
565
|
dsType: string;
|
|
566
566
|
type?: string | undefined;
|
|
567
|
-
expirationDate?: string | undefined;
|
|
568
567
|
requirements?: string | undefined;
|
|
568
|
+
expirationDate?: string | undefined;
|
|
569
569
|
}[];
|
|
570
570
|
driverParam: unknown;
|
|
571
571
|
notNull: false;
|
|
@@ -586,8 +586,8 @@ export declare const vehicles: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
586
586
|
programId: string;
|
|
587
587
|
dsType: string;
|
|
588
588
|
type?: string | undefined;
|
|
589
|
-
expirationDate?: string | undefined;
|
|
590
589
|
requirements?: string | undefined;
|
|
590
|
+
expirationDate?: string | undefined;
|
|
591
591
|
}[];
|
|
592
592
|
}>;
|
|
593
593
|
mileage: import("drizzle-orm/pg-core").PgColumn<{
|
|
@@ -46,13 +46,17 @@ export declare class VehicleInventoryRepository {
|
|
|
46
46
|
*/
|
|
47
47
|
getFacets(filters?: BaseTransformedFilters, tenantId?: number | null, env?: EnvBindings): Promise<FilterState>;
|
|
48
48
|
/**
|
|
49
|
-
* Generates facets directly from database
|
|
49
|
+
* Generates facets directly from database
|
|
50
|
+
* Performance optimized: Gets distinct values without counts
|
|
51
|
+
* ~10-20x faster than the previous implementation with counts
|
|
50
52
|
*/
|
|
51
53
|
private generateFacetsFromDatabase;
|
|
52
54
|
/**
|
|
53
|
-
* Gets facet counts
|
|
55
|
+
* Gets distinct facet values without counts for optimal performance
|
|
56
|
+
* Uses a single table scan with array aggregation
|
|
57
|
+
* Performance: ~50ms vs ~1000ms with COUNT(*) aggregations
|
|
54
58
|
*/
|
|
55
|
-
private
|
|
59
|
+
private getDistinctFacetValues;
|
|
56
60
|
/**
|
|
57
61
|
* Unified inventory method - optimized with parallel processing
|
|
58
62
|
* Supports optional text search via searchQuery parameter
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vehicleInventory.d.ts","sourceRoot":"","sources":["../../src/repositories/vehicleInventory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EACV,kBAAkB,IAAI,sBAAsB,EAC5C,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACX,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAO9C,KAAK,WAAW,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtF,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAA;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,EAAE;QACV,SAAS,EAAE,MAAM,CAAA;QACjB,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;QAClB,WAAW,EAAE,OAAO,CAAA;QACpB,WAAW,EAAE,OAAO,CAAA;KACrB,CAAA;IACD,UAAU,EAAE,UAAU,EAAE,CAAA;IACxB,UAAU,EAAE,UAAU,EAAE,CAAA;CACzB;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAEhD,OAAO;WAMO,WAAW,IAAI,0BAA0B;IAKvD;;OAEG;YACW,kBAAkB;IAehC;;OAEG;IACU,eAAe,CAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC;QACT,KAAK,EAAE,UAAU,CAAA;QACjB,OAAO,EAAE,UAAU,CAAA;KACpB,CAAC;IA6CF;;;OAGG;IACU,SAAS,CACpB,OAAO,GAAE,sBAA2B,EACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,WAAW,CAAC;IA0BvB
|
|
1
|
+
{"version":3,"file":"vehicleInventory.d.ts","sourceRoot":"","sources":["../../src/repositories/vehicleInventory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EACV,kBAAkB,IAAI,sBAAsB,EAC5C,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACX,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAO9C,KAAK,WAAW,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtF,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAA;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,EAAE;QACV,SAAS,EAAE,MAAM,CAAA;QACjB,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;QAClB,WAAW,EAAE,OAAO,CAAA;QACpB,WAAW,EAAE,OAAO,CAAA;KACrB,CAAA;IACD,UAAU,EAAE,UAAU,EAAE,CAAA;IACxB,UAAU,EAAE,UAAU,EAAE,CAAA;CACzB;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAEhD,OAAO;WAMO,WAAW,IAAI,0BAA0B;IAKvD;;OAEG;YACW,kBAAkB;IAehC;;OAEG;IACU,eAAe,CAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC;QACT,KAAK,EAAE,UAAU,CAAA;QACjB,OAAO,EAAE,UAAU,CAAA;KACpB,CAAC;IA6CF;;;OAGG;IACU,SAAS,CACpB,OAAO,GAAE,sBAA2B,EACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,WAAW,CAAC;IA0BvB;;;;OAIG;YACW,0BAA0B;IAmBxC;;;;OAIG;YACW,sBAAsB;IAmFpC;;;OAGG;IACU,YAAY,CACvB,OAAO,GAAE,sBAAsB,GAAG,mBAAwB,EAC1D,KAAK,SAAsC,EAC3C,MAAM,CAAC,EAAE,UAAU,EACnB,IAAI,SAAqC,EACzC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,YAAY,UAAQ,EACpB,GAAG,CAAC,EAAE,WAAW,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,iBAAiB,CAAC;IAmE7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;YACW,wBAAwB;IA+DtC;;;OAGG;IACU,+BAA+B,CAC1C,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAC5C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC;QAAE,UAAU,EAAE,UAAU,EAAE,CAAC;QAAC,UAAU,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;CAgBnE"}
|
package/dist/routers/index.d.ts
CHANGED
|
@@ -36,26 +36,26 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
36
36
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
37
37
|
getFacets: import("@trpc/server").TRPCQueryProcedure<{
|
|
38
38
|
input: {
|
|
39
|
+
trim?: string | string[] | undefined;
|
|
39
40
|
brand?: string | string[] | undefined;
|
|
40
41
|
model?: string | string[] | undefined;
|
|
41
|
-
trim?: string | string[] | undefined;
|
|
42
42
|
year?: string | string[] | undefined;
|
|
43
43
|
status?: string | string[] | undefined;
|
|
44
|
+
drivetrain?: string | string[] | undefined;
|
|
45
|
+
doors?: string | string[] | undefined;
|
|
46
|
+
location?: string | string[] | undefined;
|
|
44
47
|
price?: {
|
|
45
|
-
max: string;
|
|
46
48
|
min: string;
|
|
49
|
+
max: string;
|
|
47
50
|
} | undefined;
|
|
48
51
|
mileage?: {
|
|
49
|
-
max: string;
|
|
50
52
|
min: string;
|
|
53
|
+
max: string;
|
|
51
54
|
} | undefined;
|
|
52
|
-
location?: string | string[] | undefined;
|
|
53
55
|
fuelType?: string | string[] | undefined;
|
|
54
56
|
bodyStyle?: string | string[] | undefined;
|
|
55
57
|
exteriorColor?: string | string[] | undefined;
|
|
56
58
|
interiorColor?: string | string[] | undefined;
|
|
57
|
-
drivetrain?: string | string[] | undefined;
|
|
58
|
-
doors?: string | string[] | undefined;
|
|
59
59
|
} | undefined;
|
|
60
60
|
output: import("../types").FilterState;
|
|
61
61
|
meta: object;
|
|
@@ -73,27 +73,28 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
73
73
|
getInventory: import("@trpc/server").TRPCQueryProcedure<{
|
|
74
74
|
input: {
|
|
75
75
|
filters: {
|
|
76
|
+
trim?: string | string[] | undefined;
|
|
76
77
|
brand?: string | string[] | undefined;
|
|
77
78
|
model?: string | string[] | undefined;
|
|
78
|
-
trim?: string | string[] | undefined;
|
|
79
79
|
year?: string | string[] | undefined;
|
|
80
80
|
status?: string | string[] | undefined;
|
|
81
|
+
drivetrain?: string | string[] | undefined;
|
|
82
|
+
doors?: string | string[] | undefined;
|
|
83
|
+
location?: string | string[] | undefined;
|
|
81
84
|
price?: {
|
|
82
|
-
max: string;
|
|
83
85
|
min: string;
|
|
86
|
+
max: string;
|
|
84
87
|
} | undefined;
|
|
85
88
|
mileage?: {
|
|
86
|
-
max: string;
|
|
87
89
|
min: string;
|
|
90
|
+
max: string;
|
|
88
91
|
} | undefined;
|
|
89
|
-
location?: string | string[] | undefined;
|
|
90
92
|
fuelType?: string | string[] | undefined;
|
|
91
93
|
bodyStyle?: string | string[] | undefined;
|
|
92
94
|
exteriorColor?: string | string[] | undefined;
|
|
93
95
|
interiorColor?: string | string[] | undefined;
|
|
94
|
-
drivetrain?: string | string[] | undefined;
|
|
95
|
-
doors?: string | string[] | undefined;
|
|
96
96
|
};
|
|
97
|
+
limit?: number | undefined;
|
|
97
98
|
selectedMakeModelTrims?: {
|
|
98
99
|
make: string;
|
|
99
100
|
models: {
|
|
@@ -101,11 +102,10 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
101
102
|
trims: string[];
|
|
102
103
|
}[];
|
|
103
104
|
}[] | undefined;
|
|
104
|
-
|
|
105
|
-
sortBy?: "year_desc" | "year_asc" | "price_desc" | "price_asc" | "mileage_desc" | "mileage_asc" | undefined;
|
|
105
|
+
searchQuery?: string | undefined;
|
|
106
106
|
page?: number | undefined;
|
|
107
|
+
sortBy?: "year_desc" | "year_asc" | "price_desc" | "price_asc" | "mileage_desc" | "mileage_asc" | undefined;
|
|
107
108
|
groupByModel?: boolean | undefined;
|
|
108
|
-
searchQuery?: string | undefined;
|
|
109
109
|
};
|
|
110
110
|
output: {
|
|
111
111
|
filters: {
|
|
@@ -152,9 +152,9 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
152
152
|
}>;
|
|
153
153
|
getVehicleByConfiguration: import("@trpc/server").TRPCQueryProcedure<{
|
|
154
154
|
input: {
|
|
155
|
+
trim: string | null;
|
|
155
156
|
brand: string;
|
|
156
157
|
model: string;
|
|
157
|
-
trim: string | null;
|
|
158
158
|
exteriorColorCode: string | null;
|
|
159
159
|
interiorColorCode: string | null;
|
|
160
160
|
priorityField?: "trim" | "exteriorColor" | "interiorColor" | undefined;
|
|
@@ -188,12 +188,12 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
188
188
|
preferredFuelTypes?: [string, number][] | undefined;
|
|
189
189
|
preferredDrivetrains?: [string, number][] | undefined;
|
|
190
190
|
priceRangePreference?: {
|
|
191
|
-
max: number;
|
|
192
191
|
min: number;
|
|
192
|
+
max: number;
|
|
193
193
|
} | undefined;
|
|
194
194
|
mileageRangePreference?: {
|
|
195
|
-
max: number;
|
|
196
195
|
min: number;
|
|
196
|
+
max: number;
|
|
197
197
|
} | undefined;
|
|
198
198
|
};
|
|
199
199
|
output: {
|
|
@@ -202,37 +202,72 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
202
202
|
};
|
|
203
203
|
meta: object;
|
|
204
204
|
}>;
|
|
205
|
+
getCombinedFilters: import("@trpc/server").TRPCQueryProcedure<{
|
|
206
|
+
input: {
|
|
207
|
+
trim?: string | string[] | undefined;
|
|
208
|
+
brand?: string | string[] | undefined;
|
|
209
|
+
model?: string | string[] | undefined;
|
|
210
|
+
year?: string | string[] | undefined;
|
|
211
|
+
status?: string | string[] | undefined;
|
|
212
|
+
drivetrain?: string | string[] | undefined;
|
|
213
|
+
doors?: string | string[] | undefined;
|
|
214
|
+
location?: string | string[] | undefined;
|
|
215
|
+
price?: {
|
|
216
|
+
min: string;
|
|
217
|
+
max: string;
|
|
218
|
+
} | undefined;
|
|
219
|
+
mileage?: {
|
|
220
|
+
min: string;
|
|
221
|
+
max: string;
|
|
222
|
+
} | undefined;
|
|
223
|
+
fuelType?: string | string[] | undefined;
|
|
224
|
+
bodyStyle?: string | string[] | undefined;
|
|
225
|
+
exteriorColor?: string | string[] | undefined;
|
|
226
|
+
interiorColor?: string | string[] | undefined;
|
|
227
|
+
} | undefined;
|
|
228
|
+
output: {
|
|
229
|
+
new: {
|
|
230
|
+
filters: import("../types").FilterState;
|
|
231
|
+
mmtFilters: import("../types").ConsolidatedMMT[];
|
|
232
|
+
};
|
|
233
|
+
used: {
|
|
234
|
+
filters: import("../types").FilterState;
|
|
235
|
+
mmtFilters: import("../types").ConsolidatedMMT[];
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
meta: object;
|
|
239
|
+
}>;
|
|
205
240
|
searchInventory: import("@trpc/server").TRPCQueryProcedure<{
|
|
206
241
|
input: {
|
|
242
|
+
searchQuery?: string | undefined;
|
|
243
|
+
pagination?: {
|
|
244
|
+
limit?: number | undefined;
|
|
245
|
+
offset?: number | undefined;
|
|
246
|
+
} | undefined;
|
|
207
247
|
filters?: {
|
|
248
|
+
trim?: string[] | undefined;
|
|
208
249
|
brand?: string[] | undefined;
|
|
209
250
|
model?: string[] | undefined;
|
|
210
|
-
trim?: string[] | undefined;
|
|
211
251
|
year?: string[] | undefined;
|
|
212
252
|
status?: string[] | undefined;
|
|
253
|
+
drivetrain?: string[] | undefined;
|
|
254
|
+
doors?: string[] | undefined;
|
|
255
|
+
location?: string[] | undefined;
|
|
213
256
|
price?: {
|
|
214
|
-
max: string;
|
|
215
257
|
min: string;
|
|
258
|
+
max: string;
|
|
216
259
|
} | undefined;
|
|
217
260
|
mileage?: {
|
|
218
|
-
max: string;
|
|
219
261
|
min: string;
|
|
262
|
+
max: string;
|
|
220
263
|
} | undefined;
|
|
221
|
-
location?: string[] | undefined;
|
|
222
264
|
fuelType?: string[] | undefined;
|
|
223
265
|
bodyStyle?: string[] | undefined;
|
|
224
266
|
exteriorColor?: string[] | undefined;
|
|
225
267
|
interiorColor?: string[] | undefined;
|
|
226
|
-
drivetrain?: string[] | undefined;
|
|
227
|
-
doors?: string[] | undefined;
|
|
228
268
|
} | undefined;
|
|
229
269
|
sortBy?: "year_desc" | "year_asc" | "price_desc" | "price_asc" | "mileage_desc" | "mileage_asc" | undefined;
|
|
230
270
|
groupByModel?: boolean | undefined;
|
|
231
|
-
searchQuery?: string | undefined;
|
|
232
|
-
pagination?: {
|
|
233
|
-
limit?: number | undefined;
|
|
234
|
-
offset?: number | undefined;
|
|
235
|
-
} | undefined;
|
|
236
271
|
};
|
|
237
272
|
output: {
|
|
238
273
|
vehicles: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routers/index.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,eAAO,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routers/index.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGpB,CAAA;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAA"}
|