@deck.gl/carto 8.8.5 → 8.8.8
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.
- package/dist/dist.dev.js +35806 -27510
- package/dist/es5/api/index.js.map +1 -1
- package/dist/es5/api/maps-api-common.js.map +1 -1
- package/dist/es5/api/maps-v3-client.js +47 -30
- package/dist/es5/api/maps-v3-client.js.map +1 -1
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/layers/carto-layer.js +11 -6
- package/dist/es5/layers/carto-layer.js.map +1 -1
- package/dist/es5/layers/carto-tile-layer.js +1 -1
- package/dist/es5/layers/carto-tile-layer.js.map +1 -1
- package/dist/es5/layers/quadbin-utils.js +2 -0
- package/dist/es5/layers/quadbin-utils.js.map +1 -1
- package/dist/es5/layers/schema/carto-spatial-tile-loader.js +99 -0
- package/dist/es5/layers/schema/carto-spatial-tile-loader.js.map +1 -0
- package/dist/es5/layers/schema/carto-spatial-tile.js +117 -0
- package/dist/es5/layers/schema/carto-spatial-tile.js.map +1 -0
- package/dist/es5/layers/schema/carto-tile.js +5 -1
- package/dist/es5/layers/schema/carto-tile.js.map +1 -1
- package/dist/es5/layers/schema/spatialjson-utils.js +41 -0
- package/dist/es5/layers/schema/spatialjson-utils.js.map +1 -0
- package/dist/es5/layers/spatial-index-tile-layer.js +6 -0
- package/dist/es5/layers/spatial-index-tile-layer.js.map +1 -1
- package/dist/esm/api/index.js.map +1 -1
- package/dist/esm/api/maps-api-common.js.map +1 -1
- package/dist/esm/api/maps-v3-client.js +41 -15
- package/dist/esm/api/maps-v3-client.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/layers/carto-layer.js +8 -4
- package/dist/esm/layers/carto-layer.js.map +1 -1
- package/dist/esm/layers/carto-tile-layer.js +1 -1
- package/dist/esm/layers/carto-tile-layer.js.map +1 -1
- package/dist/esm/layers/quadbin-utils.js +2 -5
- package/dist/esm/layers/quadbin-utils.js.map +1 -1
- package/dist/esm/layers/schema/carto-spatial-tile-loader.js +56 -0
- package/dist/esm/layers/schema/carto-spatial-tile-loader.js.map +1 -0
- package/dist/esm/layers/schema/carto-spatial-tile.js +72 -0
- package/dist/esm/layers/schema/carto-spatial-tile.js.map +1 -0
- package/dist/esm/layers/schema/carto-tile.js +2 -2
- package/dist/esm/layers/schema/carto-tile.js.map +1 -1
- package/dist/esm/layers/schema/spatialjson-utils.js +26 -0
- package/dist/esm/layers/schema/spatialjson-utils.js.map +1 -0
- package/dist/esm/layers/spatial-index-tile-layer.js +3 -0
- package/dist/esm/layers/spatial-index-tile-layer.js.map +1 -1
- package/dist.min.js +4 -4
- package/package.json +2 -2
- package/src/api/index.ts +1 -0
- package/src/api/maps-api-common.ts +8 -0
- package/src/api/maps-v3-client.ts +59 -20
- package/src/index.ts +1 -1
- package/src/layers/carto-layer.ts +19 -6
- package/src/layers/carto-tile-layer.ts +6 -3
- package/src/layers/quadbin-utils.ts +2 -2
- package/src/layers/schema/carto-spatial-tile-loader.ts +59 -0
- package/src/layers/schema/carto-spatial-tile.ts +83 -0
- package/src/layers/schema/carto-tile.ts +6 -6
- package/src/layers/schema/spatialjson-utils.ts +35 -0
- package/src/layers/spatial-index-tile-layer.ts +4 -0
- package/typed/api/index.d.ts +1 -0
- package/typed/api/index.d.ts.map +1 -1
- package/typed/api/maps-api-common.d.ts +4 -0
- package/typed/api/maps-api-common.d.ts.map +1 -1
- package/typed/api/maps-v3-client.d.ts +8 -4
- package/typed/api/maps-v3-client.d.ts.map +1 -1
- package/typed/index.d.ts +1 -0
- package/typed/index.d.ts.map +1 -1
- package/typed/layers/carto-layer.d.ts +6 -1
- package/typed/layers/carto-layer.d.ts.map +1 -1
- package/typed/layers/carto-tile-layer.d.ts.map +1 -1
- package/typed/layers/quadbin-utils.d.ts +2 -0
- package/typed/layers/quadbin-utils.d.ts.map +1 -1
- package/typed/layers/schema/carto-spatial-tile-loader.d.ts +4 -0
- package/typed/layers/schema/carto-spatial-tile-loader.d.ts.map +1 -0
- package/typed/layers/schema/carto-spatial-tile.d.ts +21 -0
- package/typed/layers/schema/carto-spatial-tile.d.ts.map +1 -0
- package/typed/layers/schema/carto-tile.d.ts +15 -3
- package/typed/layers/schema/carto-tile.d.ts.map +1 -1
- package/typed/layers/schema/spatialjson-utils.d.ts +25 -0
- package/typed/layers/schema/spatialjson-utils.d.ts.map +1 -0
- package/typed/layers/spatial-index-tile-layer.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@deck.gl/carto",
|
|
3
3
|
"description": "CARTO official integration with Deck.gl. Build geospatial applications using CARTO and Deck.gl.",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "8.8.
|
|
5
|
+
"version": "8.8.8",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"@deck.gl/layers": "^8.0.0",
|
|
62
62
|
"@loaders.gl/core": "^3.0.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "20b9dc5ce2eaaec72d0c262622a4afeb4bcc6e96"
|
|
65
65
|
}
|
package/src/api/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export {FORMATS, TILE_FORMATS, MAP_TYPES, API_VERSIONS} from './maps-api-common';
|
|
2
|
+
export type {QueryParameters} from './maps-api-common';
|
|
2
3
|
export {getDataV2, CONNECTIONS} from './maps-client';
|
|
3
4
|
export {fetchLayerData, fetchMap, mapInstantiation} from './maps-v3-client';
|
|
@@ -77,3 +77,11 @@ type MapInstantiationFormats = Record<
|
|
|
77
77
|
export function encodeParameter(name: string, value: string | boolean | number): string {
|
|
78
78
|
return `${name}=${encodeURIComponent(value)}`;
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
export type QueryParameterValue = string | number | boolean | Array<QueryParameterValue> | object;
|
|
82
|
+
|
|
83
|
+
export type NamedQueryParameter = Record<string, QueryParameterValue>;
|
|
84
|
+
|
|
85
|
+
export type PositionalQueryParameter = QueryParameterValue[];
|
|
86
|
+
|
|
87
|
+
export type QueryParameters = NamedQueryParameter | PositionalQueryParameter;
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
MapInstantiation,
|
|
18
18
|
MapType,
|
|
19
19
|
MAP_TYPES,
|
|
20
|
+
QueryParameters,
|
|
20
21
|
SchemaField,
|
|
21
22
|
TileFormat,
|
|
22
23
|
TILE_FORMATS
|
|
@@ -28,9 +29,11 @@ import {assert} from '../utils';
|
|
|
28
29
|
const MAX_GET_LENGTH = 2048;
|
|
29
30
|
const DEFAULT_CLIENT = 'deck-gl-carto';
|
|
30
31
|
|
|
32
|
+
export type Headers = Record<string, string>;
|
|
31
33
|
interface RequestParams {
|
|
32
34
|
method?: string;
|
|
33
35
|
url: string;
|
|
36
|
+
headers?: Headers;
|
|
34
37
|
accessToken?: string;
|
|
35
38
|
body?: any;
|
|
36
39
|
}
|
|
@@ -38,8 +41,15 @@ interface RequestParams {
|
|
|
38
41
|
/**
|
|
39
42
|
* Request against Maps API
|
|
40
43
|
*/
|
|
41
|
-
async function request({
|
|
42
|
-
|
|
44
|
+
async function request({
|
|
45
|
+
method,
|
|
46
|
+
url,
|
|
47
|
+
headers: customHeaders,
|
|
48
|
+
accessToken,
|
|
49
|
+
body
|
|
50
|
+
}: RequestParams): Promise<Response> {
|
|
51
|
+
const headers: Headers = {
|
|
52
|
+
...customHeaders,
|
|
43
53
|
Accept: 'application/json'
|
|
44
54
|
};
|
|
45
55
|
|
|
@@ -66,10 +76,11 @@ async function request({method, url, accessToken, body}: RequestParams): Promise
|
|
|
66
76
|
async function requestJson<T = unknown>({
|
|
67
77
|
method,
|
|
68
78
|
url,
|
|
79
|
+
headers,
|
|
69
80
|
accessToken,
|
|
70
81
|
body
|
|
71
82
|
}: RequestParams): Promise<T> {
|
|
72
|
-
const response = await request({method, url, accessToken, body});
|
|
83
|
+
const response = await request({method, url, headers, accessToken, body});
|
|
73
84
|
const json = await response.json();
|
|
74
85
|
|
|
75
86
|
if (!response.ok) {
|
|
@@ -120,8 +131,10 @@ type FetchLayerDataParams = {
|
|
|
120
131
|
clientId?: string;
|
|
121
132
|
format?: Format;
|
|
122
133
|
formatTiles?: TileFormat;
|
|
134
|
+
headers?: Headers;
|
|
123
135
|
aggregationExp?: string;
|
|
124
136
|
aggregationResLevel?: number;
|
|
137
|
+
queryParameters?: QueryParameters;
|
|
125
138
|
};
|
|
126
139
|
|
|
127
140
|
/**
|
|
@@ -134,13 +147,18 @@ function getParameters({
|
|
|
134
147
|
columns,
|
|
135
148
|
clientId,
|
|
136
149
|
aggregationExp,
|
|
137
|
-
aggregationResLevel
|
|
150
|
+
aggregationResLevel,
|
|
151
|
+
queryParameters
|
|
138
152
|
}: Omit<FetchLayerDataParams, 'connection' | 'credentials'>) {
|
|
139
153
|
const parameters = [encodeParameter('client', clientId || DEFAULT_CLIENT)];
|
|
140
154
|
|
|
141
155
|
const sourceName = type === MAP_TYPES.QUERY ? 'q' : 'name';
|
|
142
156
|
parameters.push(encodeParameter(sourceName, source));
|
|
143
157
|
|
|
158
|
+
if (queryParameters) {
|
|
159
|
+
parameters.push(encodeParameter('queryParameters', JSON.stringify(queryParameters)));
|
|
160
|
+
}
|
|
161
|
+
|
|
144
162
|
if (geoColumn) {
|
|
145
163
|
parameters.push(encodeParameter('geo_column', geoColumn));
|
|
146
164
|
}
|
|
@@ -173,8 +191,10 @@ export async function mapInstantiation({
|
|
|
173
191
|
geoColumn,
|
|
174
192
|
columns,
|
|
175
193
|
clientId,
|
|
194
|
+
headers,
|
|
176
195
|
aggregationExp,
|
|
177
|
-
aggregationResLevel
|
|
196
|
+
aggregationResLevel,
|
|
197
|
+
queryParameters
|
|
178
198
|
}: FetchLayerDataParams): Promise<MapInstantiation> {
|
|
179
199
|
const baseUrl = `${credentials.mapsUrl}/${connection}/${type}`;
|
|
180
200
|
const url = `${baseUrl}?${getParameters({
|
|
@@ -184,7 +204,8 @@ export async function mapInstantiation({
|
|
|
184
204
|
columns,
|
|
185
205
|
clientId,
|
|
186
206
|
aggregationResLevel,
|
|
187
|
-
aggregationExp
|
|
207
|
+
aggregationExp,
|
|
208
|
+
queryParameters
|
|
188
209
|
})}`;
|
|
189
210
|
const {accessToken} = credentials;
|
|
190
211
|
|
|
@@ -192,12 +213,13 @@ export async function mapInstantiation({
|
|
|
192
213
|
// need to be a POST request
|
|
193
214
|
const body = JSON.stringify({
|
|
194
215
|
q: source,
|
|
195
|
-
client: clientId || DEFAULT_CLIENT
|
|
216
|
+
client: clientId || DEFAULT_CLIENT,
|
|
217
|
+
queryParameters
|
|
196
218
|
});
|
|
197
|
-
return await requestJson({method: 'POST', url: baseUrl, accessToken, body});
|
|
219
|
+
return await requestJson({method: 'POST', url: baseUrl, headers, accessToken, body});
|
|
198
220
|
}
|
|
199
221
|
|
|
200
|
-
return await requestJson({url, accessToken});
|
|
222
|
+
return await requestJson({url, headers, accessToken});
|
|
201
223
|
}
|
|
202
224
|
|
|
203
225
|
function getUrlFromMetadata(metadata: MapInstantiation, format: Format): string | null {
|
|
@@ -267,8 +289,10 @@ export async function fetchLayerData({
|
|
|
267
289
|
format,
|
|
268
290
|
formatTiles,
|
|
269
291
|
clientId,
|
|
292
|
+
headers,
|
|
270
293
|
aggregationExp,
|
|
271
|
-
aggregationResLevel
|
|
294
|
+
aggregationResLevel,
|
|
295
|
+
queryParameters
|
|
272
296
|
}: FetchLayerDataParams): Promise<FetchLayerDataResult> {
|
|
273
297
|
// Internally we split data fetching into two parts to allow us to
|
|
274
298
|
// conditionally fetch the actual data, depending on the metadata state
|
|
@@ -282,8 +306,10 @@ export async function fetchLayerData({
|
|
|
282
306
|
format,
|
|
283
307
|
formatTiles,
|
|
284
308
|
clientId,
|
|
309
|
+
headers,
|
|
285
310
|
aggregationExp,
|
|
286
|
-
aggregationResLevel
|
|
311
|
+
aggregationResLevel,
|
|
312
|
+
queryParameters
|
|
287
313
|
});
|
|
288
314
|
|
|
289
315
|
const data = await requestData({url, format: mapFormat, accessToken});
|
|
@@ -301,8 +327,10 @@ async function _fetchDataUrl({
|
|
|
301
327
|
format,
|
|
302
328
|
formatTiles,
|
|
303
329
|
clientId,
|
|
330
|
+
headers,
|
|
304
331
|
aggregationExp,
|
|
305
|
-
aggregationResLevel
|
|
332
|
+
aggregationResLevel,
|
|
333
|
+
queryParameters
|
|
306
334
|
}: FetchLayerDataParams) {
|
|
307
335
|
const defaultCredentials = getDefaultCredentials();
|
|
308
336
|
// Only pick up default credentials if they have been defined for
|
|
@@ -334,8 +362,10 @@ async function _fetchDataUrl({
|
|
|
334
362
|
geoColumn,
|
|
335
363
|
columns,
|
|
336
364
|
clientId,
|
|
365
|
+
headers,
|
|
337
366
|
aggregationExp,
|
|
338
|
-
aggregationResLevel
|
|
367
|
+
aggregationResLevel,
|
|
368
|
+
queryParameters
|
|
339
369
|
});
|
|
340
370
|
let url: string | null = null;
|
|
341
371
|
let mapFormat: Format | undefined;
|
|
@@ -374,7 +404,9 @@ async function _fetchMapDataset(
|
|
|
374
404
|
dataset,
|
|
375
405
|
accessToken: string,
|
|
376
406
|
credentials: CloudNativeCredentials,
|
|
377
|
-
clientId?: string
|
|
407
|
+
clientId?: string,
|
|
408
|
+
headers?: Headers,
|
|
409
|
+
queryParameters?: QueryParameters
|
|
378
410
|
) {
|
|
379
411
|
const {
|
|
380
412
|
aggregationExp,
|
|
@@ -396,8 +428,10 @@ async function _fetchMapDataset(
|
|
|
396
428
|
columns,
|
|
397
429
|
format,
|
|
398
430
|
geoColumn,
|
|
431
|
+
headers,
|
|
399
432
|
source,
|
|
400
|
-
type
|
|
433
|
+
type,
|
|
434
|
+
queryParameters
|
|
401
435
|
});
|
|
402
436
|
|
|
403
437
|
// Extract the last time the data changed
|
|
@@ -441,9 +475,12 @@ async function _fetchTilestats(
|
|
|
441
475
|
async function fillInMapDatasets(
|
|
442
476
|
{datasets, token},
|
|
443
477
|
clientId: string,
|
|
444
|
-
credentials: CloudNativeCredentials
|
|
478
|
+
credentials: CloudNativeCredentials,
|
|
479
|
+
headers?: Headers
|
|
445
480
|
) {
|
|
446
|
-
const promises = datasets.map(dataset =>
|
|
481
|
+
const promises = datasets.map(dataset =>
|
|
482
|
+
_fetchMapDataset(dataset, token, credentials, clientId, headers)
|
|
483
|
+
);
|
|
447
484
|
return await Promise.all(promises);
|
|
448
485
|
}
|
|
449
486
|
|
|
@@ -487,12 +524,14 @@ export async function fetchMap({
|
|
|
487
524
|
cartoMapId,
|
|
488
525
|
clientId,
|
|
489
526
|
credentials,
|
|
527
|
+
headers,
|
|
490
528
|
autoRefresh,
|
|
491
529
|
onNewData
|
|
492
530
|
}: {
|
|
493
531
|
cartoMapId: string;
|
|
494
532
|
clientId: string;
|
|
495
533
|
credentials?: CloudNativeCredentials;
|
|
534
|
+
headers?: Headers;
|
|
496
535
|
autoRefresh?: number;
|
|
497
536
|
onNewData?: (map: any) => void;
|
|
498
537
|
}) {
|
|
@@ -521,7 +560,7 @@ export async function fetchMap({
|
|
|
521
560
|
}
|
|
522
561
|
|
|
523
562
|
const url = `${localCreds.mapsUrl}/public/${cartoMapId}`;
|
|
524
|
-
const map = await requestJson<any>({url, accessToken});
|
|
563
|
+
const map = await requestJson<any>({url, headers, accessToken});
|
|
525
564
|
|
|
526
565
|
// Periodically check if the data has changed. Note that this
|
|
527
566
|
// will not update when a map is published.
|
|
@@ -529,7 +568,7 @@ export async function fetchMap({
|
|
|
529
568
|
if (autoRefresh) {
|
|
530
569
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
531
570
|
const intervalId = setInterval(async () => {
|
|
532
|
-
const changed = await fillInMapDatasets(map, clientId, localCreds);
|
|
571
|
+
const changed = await fillInMapDatasets(map, clientId, localCreds, headers);
|
|
533
572
|
if (onNewData && changed.some(v => v === true)) {
|
|
534
573
|
onNewData(parseMap(map));
|
|
535
574
|
}
|
|
@@ -550,7 +589,7 @@ export async function fetchMap({
|
|
|
550
589
|
});
|
|
551
590
|
|
|
552
591
|
// Mutates map.datasets so that dataset.data contains data
|
|
553
|
-
await fillInMapDatasets(map, clientId, localCreds);
|
|
592
|
+
await fillInMapDatasets(map, clientId, localCreds, headers);
|
|
554
593
|
|
|
555
594
|
// Mutates attributes in visualChannels to contain tile stats
|
|
556
595
|
await fillInTileStats(map, localCreds);
|
package/src/index.ts
CHANGED
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
GEO_COLUMN_SUPPORT,
|
|
17
17
|
MapType,
|
|
18
18
|
MAP_TYPES,
|
|
19
|
-
TileFormat
|
|
19
|
+
TileFormat,
|
|
20
|
+
QueryParameters
|
|
20
21
|
} from '../api/maps-api-common';
|
|
21
22
|
import {
|
|
22
23
|
ClassicCredentials,
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
Credentials,
|
|
25
26
|
getDefaultCredentials
|
|
26
27
|
} from '../config';
|
|
27
|
-
import {FetchLayerDataResult} from '../api/maps-v3-client';
|
|
28
|
+
import {FetchLayerDataResult, Headers} from '../api/maps-v3-client';
|
|
28
29
|
import {assert} from '../utils';
|
|
29
30
|
|
|
30
31
|
const defaultProps = {
|
|
@@ -60,11 +61,17 @@ const defaultProps = {
|
|
|
60
61
|
// (Array<String>, optional): names of columns to fetch. By default, all columns are fetched.
|
|
61
62
|
columns: {type: 'array', value: null},
|
|
62
63
|
|
|
64
|
+
// (Headers, optional): Custom headers to include in the map instantiation request.
|
|
65
|
+
headers: {type: 'object', value: {}, optional: true},
|
|
66
|
+
|
|
63
67
|
// (String, optional): aggregation SQL expression. Only used for spatial index datasets
|
|
64
68
|
aggregationExp: null,
|
|
65
69
|
|
|
66
70
|
// (Number, optional): aggregation resolution level. Only used for spatial index datasets, defaults to 6 for quadbins, 4 for h3
|
|
67
|
-
aggregationResLevel: null
|
|
71
|
+
aggregationResLevel: null,
|
|
72
|
+
|
|
73
|
+
// (QueryParameters, optional): query parameters to be sent to the server.
|
|
74
|
+
queryParameters: null
|
|
68
75
|
};
|
|
69
76
|
|
|
70
77
|
/** All properties supported by CartoLayer. */
|
|
@@ -144,11 +151,17 @@ type _CartoLayerProps = {
|
|
|
144
151
|
|
|
145
152
|
clientId?: string;
|
|
146
153
|
|
|
154
|
+
/** Custom headers to include in the map instantiation request **/
|
|
155
|
+
headers?: Headers;
|
|
156
|
+
|
|
147
157
|
/** Aggregation SQL expression. Only used for spatial index datasets **/
|
|
148
158
|
aggregationExp?: string;
|
|
149
159
|
|
|
150
160
|
/** Aggregation resolution level. Only used for spatial index datasets, defaults to 6 for quadbins, 4 for h3. **/
|
|
151
161
|
aggregationResLevel?: number;
|
|
162
|
+
|
|
163
|
+
/** Query parameters to be sent to the server. **/
|
|
164
|
+
queryParameters?: QueryParameters;
|
|
152
165
|
};
|
|
153
166
|
|
|
154
167
|
export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
@@ -218,7 +231,8 @@ export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
|
218
231
|
props.formatTiles !== oldProps.formatTiles ||
|
|
219
232
|
props.type !== oldProps.type ||
|
|
220
233
|
JSON.stringify(props.columns) !== JSON.stringify(oldProps.columns) ||
|
|
221
|
-
JSON.stringify(props.credentials) !== JSON.stringify(oldProps.credentials)
|
|
234
|
+
JSON.stringify(props.credentials) !== JSON.stringify(oldProps.credentials) ||
|
|
235
|
+
JSON.stringify(props.queryParameters) !== JSON.stringify(oldProps.queryParameters);
|
|
222
236
|
|
|
223
237
|
if (shouldUpdateData) {
|
|
224
238
|
this.setState({data: null, apiVersion: null});
|
|
@@ -229,7 +243,7 @@ export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
|
229
243
|
|
|
230
244
|
async _updateData(): Promise<void> {
|
|
231
245
|
try {
|
|
232
|
-
const {type, data: source,
|
|
246
|
+
const {type, data: source, credentials, connection, ...rest} = this.props;
|
|
233
247
|
const localConfig = {...getDefaultCredentials(), ...credentials};
|
|
234
248
|
const {apiVersion} = localConfig;
|
|
235
249
|
|
|
@@ -242,7 +256,6 @@ export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
|
242
256
|
result = await fetchLayerData({
|
|
243
257
|
type,
|
|
244
258
|
source,
|
|
245
|
-
clientId,
|
|
246
259
|
credentials: credentials as CloudNativeCredentials,
|
|
247
260
|
connection,
|
|
248
261
|
...rest,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '@deck.gl/geo-layers';
|
|
13
13
|
import {GeoJsonLayer} from '@deck.gl/layers';
|
|
14
14
|
import {geojsonToBinary} from '@loaders.gl/gis';
|
|
15
|
-
import {
|
|
15
|
+
import {KeyValueProperties, Tile, TileReader} from './schema/carto-tile';
|
|
16
16
|
import {TileFormat, TILE_FORMATS} from '../api/maps-api-common';
|
|
17
17
|
import {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
18
18
|
import type {BinaryFeatures} from '@loaders.gl/schema';
|
|
@@ -28,7 +28,7 @@ function parsePbf(buffer: ArrayBuffer): Tile {
|
|
|
28
28
|
return tile;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function unpackProperties(properties:
|
|
31
|
+
function unpackProperties(properties: KeyValueProperties[]) {
|
|
32
32
|
if (!properties || !properties.length) {
|
|
33
33
|
return [];
|
|
34
34
|
}
|
|
@@ -67,7 +67,10 @@ const CartoTileLoader: LoaderWithParser = {
|
|
|
67
67
|
id: 'cartoTile',
|
|
68
68
|
module: 'carto',
|
|
69
69
|
extensions: ['pbf'],
|
|
70
|
-
mimeTypes: [
|
|
70
|
+
mimeTypes: [
|
|
71
|
+
'application/vnd.carto-vector-tile',
|
|
72
|
+
'application/x-protobuf' // Back-compatibility
|
|
73
|
+
],
|
|
71
74
|
category: 'geometry',
|
|
72
75
|
worker: false,
|
|
73
76
|
parse: async (arrayBuffer, options) => parseCartoTile(arrayBuffer, options),
|
|
@@ -12,11 +12,11 @@ const B = [
|
|
|
12
12
|
];
|
|
13
13
|
const S = [0n, 1n, 2n, 4n, 8n, 16n];
|
|
14
14
|
|
|
15
|
-
function indexToBigInt(index: string): bigint {
|
|
15
|
+
export function indexToBigInt(index: string): bigint {
|
|
16
16
|
return BigInt(`0x${index}`);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function bigIntToIndex(quadbin: bigint): string {
|
|
19
|
+
export function bigIntToIndex(quadbin: bigint): string {
|
|
20
20
|
return quadbin.toString(16);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import Protobuf from 'pbf';
|
|
2
|
+
import {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
3
|
+
|
|
4
|
+
import {KeyValueProperties} from './carto-tile';
|
|
5
|
+
import {binaryToSpatialjson, Properties, SpatialJson} from './spatialjson-utils';
|
|
6
|
+
import {Tile, TileReader} from './carto-spatial-tile';
|
|
7
|
+
|
|
8
|
+
const CartoSpatialTileLoader: LoaderWithParser = {
|
|
9
|
+
name: 'CARTO Spatial Tile',
|
|
10
|
+
version: '1',
|
|
11
|
+
id: 'cartoSpatialTile',
|
|
12
|
+
module: 'carto',
|
|
13
|
+
extensions: ['pbf'],
|
|
14
|
+
mimeTypes: [
|
|
15
|
+
'application/vnd.carto-spatial-tile',
|
|
16
|
+
'application/x-protobuf' // Back-compatibility
|
|
17
|
+
],
|
|
18
|
+
category: 'geometry',
|
|
19
|
+
worker: false,
|
|
20
|
+
parse: async (arrayBuffer, options) => parseCartoSpatialTile(arrayBuffer, options),
|
|
21
|
+
parseSync: parseCartoSpatialTile,
|
|
22
|
+
options: {}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function parsePbf(buffer: ArrayBuffer): Tile {
|
|
26
|
+
const pbf = new Protobuf(buffer);
|
|
27
|
+
const tile = TileReader.read(pbf);
|
|
28
|
+
return tile;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function unpackProperties(properties: KeyValueProperties[]): Properties[] {
|
|
32
|
+
if (!properties || !properties.length) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
return properties.map(item => {
|
|
36
|
+
const currentRecord: Properties = {};
|
|
37
|
+
item.data.forEach(({key, value}) => {
|
|
38
|
+
currentRecord[key] = value;
|
|
39
|
+
});
|
|
40
|
+
return currentRecord;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseCartoSpatialTile(
|
|
45
|
+
arrayBuffer: ArrayBuffer,
|
|
46
|
+
options?: LoaderOptions
|
|
47
|
+
): SpatialJson | null {
|
|
48
|
+
if (!arrayBuffer) return null;
|
|
49
|
+
const tile = parsePbf(arrayBuffer);
|
|
50
|
+
|
|
51
|
+
const {cells} = tile;
|
|
52
|
+
const data = {
|
|
53
|
+
cells: {...cells, properties: unpackProperties(cells.properties)}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return binaryToSpatialjson(data);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default CartoSpatialTileLoader;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {Indices, IndexScheme} from './spatialjson-utils';
|
|
2
|
+
import {
|
|
3
|
+
KeyValueProperties,
|
|
4
|
+
NumericProp,
|
|
5
|
+
NumericPropKeyValueReader,
|
|
6
|
+
PropertiesReader
|
|
7
|
+
} from './carto-tile';
|
|
8
|
+
|
|
9
|
+
// Indices =====================================
|
|
10
|
+
|
|
11
|
+
export class IndicesReader {
|
|
12
|
+
static read(pbf, end?: number): Indices {
|
|
13
|
+
const {value} = pbf.readFields(IndicesReader._readField, {value: []}, end);
|
|
14
|
+
return {value: new BigUint64Array(value)};
|
|
15
|
+
}
|
|
16
|
+
static _readField(this: void, tag: number, obj, pbf) {
|
|
17
|
+
if (tag === 1) readPackedFixed64(pbf, obj.value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Cells =========================================
|
|
22
|
+
|
|
23
|
+
interface Cells {
|
|
24
|
+
indices: Indices;
|
|
25
|
+
properties: KeyValueProperties[];
|
|
26
|
+
numericProps: Record<string, NumericProp>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class CellsReader {
|
|
30
|
+
static read(pbf, end?: number): Cells {
|
|
31
|
+
return pbf.readFields(
|
|
32
|
+
CellsReader._readField,
|
|
33
|
+
{indices: null, properties: [], numericProps: {}},
|
|
34
|
+
end
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
static _readField(this: void, tag: number, obj: Cells, pbf) {
|
|
38
|
+
if (tag === 1) obj.indices = IndicesReader.read(pbf, pbf.readVarint() + pbf.pos);
|
|
39
|
+
else if (tag === 2) obj.properties.push(PropertiesReader.read(pbf, pbf.readVarint() + pbf.pos));
|
|
40
|
+
else if (tag === 3) {
|
|
41
|
+
const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos);
|
|
42
|
+
obj.numericProps[entry.key] = entry.value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Tile ========================================
|
|
48
|
+
|
|
49
|
+
// TODO this type is very similar to SpatialBinary, should align
|
|
50
|
+
export interface Tile {
|
|
51
|
+
scheme: IndexScheme;
|
|
52
|
+
cells: Cells;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class TileReader {
|
|
56
|
+
static read(pbf, end?: number): Tile {
|
|
57
|
+
return pbf.readFields(TileReader._readField, {scheme: 0, cells: null}, end);
|
|
58
|
+
}
|
|
59
|
+
static _readField(this: void, tag: number, obj: Tile, pbf) {
|
|
60
|
+
if (tag === 1) obj.scheme = pbf.readVarint();
|
|
61
|
+
else if (tag === 2) obj.cells = CellsReader.read(pbf, pbf.readVarint() + pbf.pos);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// pbf doesn't support BigInt natively, implement support for packed fixed64 type
|
|
66
|
+
const SHIFT_LEFT_32 = BigInt((1 << 16) * (1 << 16));
|
|
67
|
+
|
|
68
|
+
function readPackedEnd(pbf) {
|
|
69
|
+
return pbf.type === 2 ? pbf.readVarint() + pbf.pos : pbf.pos + 1;
|
|
70
|
+
}
|
|
71
|
+
function readFixed64(pbf) {
|
|
72
|
+
const a = BigInt(pbf.readFixed32());
|
|
73
|
+
const b = BigInt(pbf.readFixed32());
|
|
74
|
+
return a + b * SHIFT_LEFT_32;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function readPackedFixed64(pbf, arr) {
|
|
78
|
+
if (pbf.type !== 2) return arr.push(readFixed64(pbf));
|
|
79
|
+
const end = readPackedEnd(pbf);
|
|
80
|
+
arr = arr || [];
|
|
81
|
+
while (pbf.pos < end) arr.push(readFixed64(pbf));
|
|
82
|
+
return arr;
|
|
83
|
+
}
|
|
@@ -16,15 +16,15 @@ class KeyValueObjectReader {
|
|
|
16
16
|
|
|
17
17
|
// Properties ========================================
|
|
18
18
|
|
|
19
|
-
export interface
|
|
19
|
+
export interface KeyValueProperties {
|
|
20
20
|
data: KeyValueObject[];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
class PropertiesReader {
|
|
23
|
+
export class PropertiesReader {
|
|
24
24
|
static read(pbf, end?: number) {
|
|
25
25
|
return pbf.readFields(PropertiesReader._readField, {data: []}, end);
|
|
26
26
|
}
|
|
27
|
-
static _readField(this: void, tag: number, obj:
|
|
27
|
+
static _readField(this: void, tag: number, obj: KeyValueProperties, pbf) {
|
|
28
28
|
if (tag === 1) obj.data.push(KeyValueObjectReader.read(pbf, pbf.readVarint() + pbf.pos));
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -69,7 +69,7 @@ class IntsReader {
|
|
|
69
69
|
|
|
70
70
|
// NumericProp ========================================
|
|
71
71
|
|
|
72
|
-
interface NumericProp {
|
|
72
|
+
export interface NumericProp {
|
|
73
73
|
value: number[];
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -88,7 +88,7 @@ interface NumbericPropKeyValue {
|
|
|
88
88
|
value: NumericProp;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
class NumericPropKeyValueReader {
|
|
91
|
+
export class NumericPropKeyValueReader {
|
|
92
92
|
static read(pbf, end?: number): NumbericPropKeyValue {
|
|
93
93
|
return pbf.readFields(NumericPropKeyValueReader._readField, {key: '', value: null}, end);
|
|
94
94
|
}
|
|
@@ -104,7 +104,7 @@ interface Points {
|
|
|
104
104
|
positions: Doubles;
|
|
105
105
|
globalFeatureIds: Ints;
|
|
106
106
|
featureIds: Ints;
|
|
107
|
-
properties:
|
|
107
|
+
properties: KeyValueProperties[];
|
|
108
108
|
numericProps: Record<string, NumericProp>;
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {bigIntToIndex} from '../quadbin-utils';
|
|
2
|
+
|
|
3
|
+
export type IndexScheme = 'h3' | 'quadbin';
|
|
4
|
+
type TypedArray = Float32Array | Float64Array;
|
|
5
|
+
|
|
6
|
+
export type Indices = {value: BigUint64Array};
|
|
7
|
+
export type NumericProps = Record<string, {value: number[] | TypedArray}>;
|
|
8
|
+
export type Properties = Record<string, string | number | boolean | null>;
|
|
9
|
+
export type Cells = {
|
|
10
|
+
indices: Indices;
|
|
11
|
+
numericProps: NumericProps;
|
|
12
|
+
properties: Properties[];
|
|
13
|
+
};
|
|
14
|
+
export type SpatialBinary = {scheme?: IndexScheme; cells: Cells};
|
|
15
|
+
export type SpatialJson = {
|
|
16
|
+
id: string;
|
|
17
|
+
properties: Properties;
|
|
18
|
+
}[];
|
|
19
|
+
|
|
20
|
+
export function binaryToSpatialjson(binary: SpatialBinary): SpatialJson {
|
|
21
|
+
const {cells} = binary;
|
|
22
|
+
const count = cells.indices.value.length;
|
|
23
|
+
const spatial: any[] = [];
|
|
24
|
+
for (let i = 0; i < count; i++) {
|
|
25
|
+
const id = bigIntToIndex(cells.indices.value[i]);
|
|
26
|
+
|
|
27
|
+
const properties = {...cells.properties[i]};
|
|
28
|
+
for (const key of Object.keys(cells.numericProps)) {
|
|
29
|
+
properties[key] = cells.numericProps[key].value[i];
|
|
30
|
+
}
|
|
31
|
+
spatial.push({id, properties});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return spatial;
|
|
35
|
+
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {registerLoaders} from '@loaders.gl/core';
|
|
2
|
+
import CartoSpatialTileLoader from './schema/carto-spatial-tile-loader';
|
|
3
|
+
registerLoaders([CartoSpatialTileLoader]);
|
|
4
|
+
|
|
1
5
|
import {PickingInfo} from '@deck.gl/core';
|
|
2
6
|
import {TileLayer, _Tile2DHeader as Tile2DHeader} from '@deck.gl/geo-layers';
|
|
3
7
|
|
package/typed/api/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { FORMATS, TILE_FORMATS, MAP_TYPES, API_VERSIONS } from './maps-api-common';
|
|
2
|
+
export type { QueryParameters } from './maps-api-common';
|
|
2
3
|
export { getDataV2, CONNECTIONS } from './maps-client';
|
|
3
4
|
export { fetchLayerData, fetchMap, mapInstantiation } from './maps-v3-client';
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/typed/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,EAAC,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAC,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,EAAC,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAC,MAAM,kBAAkB,CAAC"}
|
|
@@ -61,5 +61,9 @@ declare type MapInstantiationFormats = Record<Format, {
|
|
|
61
61
|
* Simple encode parameter
|
|
62
62
|
*/
|
|
63
63
|
export declare function encodeParameter(name: string, value: string | boolean | number): string;
|
|
64
|
+
export declare type QueryParameterValue = string | number | boolean | Array<QueryParameterValue> | object;
|
|
65
|
+
export declare type NamedQueryParameter = Record<string, QueryParameterValue>;
|
|
66
|
+
export declare type PositionalQueryParameter = QueryParameterValue[];
|
|
67
|
+
export declare type QueryParameters = NamedQueryParameter | PositionalQueryParameter;
|
|
64
68
|
export {};
|
|
65
69
|
//# sourceMappingURL=maps-api-common.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maps-api-common.d.ts","sourceRoot":"","sources":["../../src/api/maps-api-common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,WAAW,CAAC;AACtD,eAAO,MAAM,+BAA+B,aAAa,CAAC;AAE1D,oBAAY,QAAQ,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAChD,eAAO,MAAM,YAAY;;;;CAIf,CAAC;AACX,oBAAY,UAAU,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAEvD,eAAO,MAAM,uBAAuB;;;CAG1B,CAAC;AAEX,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AACX,oBAAY,OAAO,GAAG,QAAQ,CAAC,OAAO,SAAS,CAAC,CAAC;AACjD,eAAO,MAAM,eAAe,EAAE,OAAO,EAAsB,CAAC;AAC5D,eAAO,MAAM,kBAAkB,EAAE,OAAO,EAAuC,CAAC;AAGhF,eAAO,MAAM,OAAO;;;;;CAKV,CAAC;AACX,oBAAY,MAAM,GAAG,QAAQ,CAAC,OAAO,OAAO,CAAC,CAAC;AAG9C,eAAO,MAAM,YAAY;;;;;CAKf,CAAC;AACX,oBAAY,UAAU,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAEvD,oBAAY,eAAe;IACzB,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,uBAAuB;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,aAAK,uBAAuB,GAAG,MAAM,CACnC,MAAM,EACN;IACE,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb,CACF,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAEtF"}
|
|
1
|
+
{"version":3,"file":"maps-api-common.d.ts","sourceRoot":"","sources":["../../src/api/maps-api-common.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,WAAW,CAAC;AACtD,eAAO,MAAM,+BAA+B,aAAa,CAAC;AAE1D,oBAAY,QAAQ,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAChD,eAAO,MAAM,YAAY;;;;CAIf,CAAC;AACX,oBAAY,UAAU,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAEvD,eAAO,MAAM,uBAAuB;;;CAG1B,CAAC;AAEX,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AACX,oBAAY,OAAO,GAAG,QAAQ,CAAC,OAAO,SAAS,CAAC,CAAC;AACjD,eAAO,MAAM,eAAe,EAAE,OAAO,EAAsB,CAAC;AAC5D,eAAO,MAAM,kBAAkB,EAAE,OAAO,EAAuC,CAAC;AAGhF,eAAO,MAAM,OAAO;;;;;CAKV,CAAC;AACX,oBAAY,MAAM,GAAG,QAAQ,CAAC,OAAO,OAAO,CAAC,CAAC;AAG9C,eAAO,MAAM,YAAY;;;;;CAKf,CAAC;AACX,oBAAY,UAAU,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAEvD,oBAAY,eAAe;IACzB,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,uBAAuB;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,aAAK,uBAAuB,GAAG,MAAM,CACnC,MAAM,EACN;IACE,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb,CACF,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAEtF;AAED,oBAAY,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC,mBAAmB,CAAC,GAAG,MAAM,CAAC;AAElG,oBAAY,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAEtE,oBAAY,wBAAwB,GAAG,mBAAmB,EAAE,CAAC;AAE7D,oBAAY,eAAe,GAAG,mBAAmB,GAAG,wBAAwB,CAAC"}
|