@honua/sdk-esri-compat 0.1.14 → 0.1.16
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/contract/generated/projjson-v0.7-crs-validator.d.ts +4 -4
- package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -1
- package/contract/generated/projjson-v0.7-crs-validator.js +1954 -3756
- package/contract/query-filter.d.ts +5 -3
- package/contract/query-filter.d.ts.map +1 -1
- package/contract/query-filter.js +38 -22
- package/contract/source.d.ts.map +1 -1
- package/contract/source.js +11 -3
- package/contract/types.js +1 -1
- package/core/client.d.ts +7 -5
- package/core/client.d.ts.map +1 -1
- package/core/client.js +127 -25
- package/core/geoservices.js +38 -2
- package/core/grpc-adapter.d.ts.map +1 -1
- package/core/grpc-adapter.js +31 -62
- package/core/odata.d.ts +3 -0
- package/core/odata.d.ts.map +1 -1
- package/core/odata.js +79 -6
- package/core/process-runner.d.ts +2 -1
- package/core/process-runner.d.ts.map +1 -1
- package/core/process-runner.js +3 -1
- package/core/surfaces.d.ts +2 -0
- package/core/surfaces.d.ts.map +1 -1
- package/core/surfaces.js +15 -26
- package/core/wfs-filter.d.ts.map +1 -1
- package/core/wfs-filter.js +28 -20
- package/package.json +2 -2
- package/query-planner/odata-v1.d.ts.map +1 -1
- package/query-planner/odata-v1.js +3 -1
package/core/client.js
CHANGED
|
@@ -475,11 +475,11 @@ export class HonuaClient {
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
/**
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
* `
|
|
482
|
-
*
|
|
478
|
+
* Consume the native gRPC FeatureService server stream. Each yielded chunk
|
|
479
|
+
* is a `HonuaFeature[]` slice. The server controls batching and may apply a
|
|
480
|
+
* total result limit, including its default when resultRecordCount is absent.
|
|
481
|
+
* Use `featureLayer(...).queryFeaturesStream()` or `Source.stream()` to page
|
|
482
|
+
* through the full match set with a caller-selected per-batch budget.
|
|
483
483
|
*
|
|
484
484
|
* @example
|
|
485
485
|
* ```ts
|
|
@@ -817,6 +817,8 @@ export class HonuaClient {
|
|
|
817
817
|
* `.text()`, or `.arrayBuffer()`. Non-2xx responses still throw the
|
|
818
818
|
* normalized `HonuaHttpError` (and trigger retries) so error handling
|
|
819
819
|
* matches every other client method.
|
|
820
|
+
* The request deadline and caller cancellation remain active while consuming
|
|
821
|
+
* the response body. Consume or cancel the body to release that lifecycle.
|
|
820
822
|
*/
|
|
821
823
|
async pipelineFetch(method, path, init, callerSignal, options = {}) {
|
|
822
824
|
const request = {
|
|
@@ -837,7 +839,8 @@ export class HonuaClient {
|
|
|
837
839
|
...(options.redirect ? { redirect: options.redirect } : {}),
|
|
838
840
|
...(options.beforeAttempt ? { beforeAttempt: options.beforeAttempt } : {}),
|
|
839
841
|
...(options.beforeReplay ? { beforeReplay: options.beforeReplay } : {}),
|
|
840
|
-
|
|
842
|
+
deadlineThroughFinalize: true,
|
|
843
|
+
streamResponse: options.prepareResponse === undefined,
|
|
841
844
|
...(options.errorBody
|
|
842
845
|
? { errorBody: options.errorBody }
|
|
843
846
|
: options.discardErrorBody
|
|
@@ -890,6 +893,7 @@ export class HonuaClient {
|
|
|
890
893
|
};
|
|
891
894
|
return this.executeRequest(request, {
|
|
892
895
|
callerSignal: metadataOptions.signal,
|
|
896
|
+
deadlineThroughFinalize: true,
|
|
893
897
|
// stale-if-error fallback on a terminal network or HTTP failure.
|
|
894
898
|
onTerminalError: (error) => this.staleMetadataFallback(cached, metadataOptions, error),
|
|
895
899
|
// 304 Not Modified: revalidate the cached entry without re-parsing a body.
|
|
@@ -915,8 +919,8 @@ export class HonuaClient {
|
|
|
915
919
|
})),
|
|
916
920
|
};
|
|
917
921
|
},
|
|
918
|
-
finalize: async (response, durationMs, currentRequest, runAfter) => {
|
|
919
|
-
const body = await
|
|
922
|
+
finalize: async (response, durationMs, currentRequest, runAfter, deadlineSignal) => {
|
|
923
|
+
const body = await parseSuccessfulJsonBody(this.hasAfterInterceptors() ? response.clone() : response, metadataOptions.maxResponseBytes, deadlineSignal);
|
|
920
924
|
// GeoServices reports metadata failures (layer not found, invalid token
|
|
921
925
|
// => code 499, …) as HTTP 200 with a top-level `{error}` envelope.
|
|
922
926
|
// Detect it before caching so a transient auth/permission error is never
|
|
@@ -1289,7 +1293,7 @@ export class HonuaClient {
|
|
|
1289
1293
|
finalize: async (response, _durationMs, _currentRequest, runAfter) => {
|
|
1290
1294
|
// Parse the original body directly when no after-interceptor will read
|
|
1291
1295
|
// it; only clone when an interceptor needs an independent copy.
|
|
1292
|
-
const body = await
|
|
1296
|
+
const body = await parseSuccessfulJsonBody(this.hasAfterInterceptors() ? response.clone() : response);
|
|
1293
1297
|
// GeoServices/Esri services return HTTP 200 with a top-level `{error}`
|
|
1294
1298
|
// envelope on failure (bad WHERE, invalid outFields, edit failures, …).
|
|
1295
1299
|
// Surface these through the unified error model instead of handing the
|
|
@@ -1321,19 +1325,22 @@ export class HonuaClient {
|
|
|
1321
1325
|
};
|
|
1322
1326
|
return this.executeRequest(request, {
|
|
1323
1327
|
callerSignal,
|
|
1324
|
-
|
|
1328
|
+
deadlineThroughFinalize: true,
|
|
1329
|
+
finalize: async (response, durationMs, currentRequest, runAfter, deadlineSignal) => {
|
|
1325
1330
|
await runAfter();
|
|
1326
1331
|
// If the server returned PBF, decode it; on decode failure (including
|
|
1327
1332
|
// Z/M geometry the fast path can't handle) retry as f=json.
|
|
1328
1333
|
if (isPbfResponse(response)) {
|
|
1329
1334
|
try {
|
|
1330
|
-
const buffer = await response.
|
|
1335
|
+
const buffer = await readBoundedResponseBytes(response, Number.MAX_SAFE_INTEGER, deadlineSignal);
|
|
1331
1336
|
return decodePbfQueryResponse(buffer);
|
|
1332
1337
|
}
|
|
1333
|
-
catch {
|
|
1338
|
+
catch (error) {
|
|
1339
|
+
if (deadlineSignal?.aborted)
|
|
1340
|
+
throw error;
|
|
1334
1341
|
params.set("f", "json");
|
|
1335
1342
|
const jsonPath = `${stripQuery(path)}?${params.toString()}`;
|
|
1336
|
-
return this.requestJson("GET", jsonPath, undefined, callerSignal ?? currentRequest.init.signal ?? undefined);
|
|
1343
|
+
return this.requestJson("GET", jsonPath, undefined, deadlineSignal ?? callerSignal ?? currentRequest.init.signal ?? undefined);
|
|
1337
1344
|
}
|
|
1338
1345
|
}
|
|
1339
1346
|
// Server returned JSON despite the PBF request (e.g. error or
|
|
@@ -1342,7 +1349,7 @@ export class HonuaClient {
|
|
|
1342
1349
|
// even when f=pbf was requested. Detect the `{error}` envelope here so
|
|
1343
1350
|
// preferBinary callers throw a normalized HonuaHttpError exactly like
|
|
1344
1351
|
// the JSON path instead of receiving the failure envelope as success.
|
|
1345
|
-
const body = await
|
|
1352
|
+
const body = await parseSuccessfulJsonBody(response, undefined, deadlineSignal);
|
|
1346
1353
|
const envelopeError = toGeoServicesError(response.status, body, response.headers);
|
|
1347
1354
|
if (envelopeError) {
|
|
1348
1355
|
await this.applyErrorInterceptors({
|
|
@@ -1386,11 +1393,11 @@ export class HonuaClient {
|
|
|
1386
1393
|
};
|
|
1387
1394
|
return this.executeRequest(request, {
|
|
1388
1395
|
callerSignal: options?.signal,
|
|
1389
|
-
deadlineThroughFinalize:
|
|
1396
|
+
deadlineThroughFinalize: true,
|
|
1390
1397
|
errorBody: async (response, deadlineSignal) => {
|
|
1391
1398
|
const clone = response.clone();
|
|
1392
1399
|
const text = options?.maxResponseBytes === undefined
|
|
1393
|
-
? await clone.
|
|
1400
|
+
? new TextDecoder().decode(await readBoundedResponseBytes(clone, Number.MAX_SAFE_INTEGER, deadlineSignal))
|
|
1394
1401
|
: new TextDecoder().decode(await readBoundedResponseBytes(clone, options.maxResponseBytes, deadlineSignal));
|
|
1395
1402
|
const contentType = response.headers.get("content-type") ?? acceptHeader;
|
|
1396
1403
|
return text ? { raw: text, contentType } : {};
|
|
@@ -1398,7 +1405,7 @@ export class HonuaClient {
|
|
|
1398
1405
|
finalize: async (response, _durationMs, _request, runAfter, deadlineSignal) => {
|
|
1399
1406
|
if (options?.maxResponseBytes === undefined) {
|
|
1400
1407
|
await runAfter();
|
|
1401
|
-
const text = await response.
|
|
1408
|
+
const text = new TextDecoder().decode(await readBoundedResponseBytes(response, Number.MAX_SAFE_INTEGER, deadlineSignal));
|
|
1402
1409
|
const contentType = response.headers.get("content-type") ?? acceptHeader;
|
|
1403
1410
|
return { text, contentType, status: response.status };
|
|
1404
1411
|
}
|
|
@@ -1431,10 +1438,10 @@ export class HonuaClient {
|
|
|
1431
1438
|
};
|
|
1432
1439
|
return this.executeRequest(request, {
|
|
1433
1440
|
callerSignal,
|
|
1434
|
-
|
|
1441
|
+
deadlineThroughFinalize: true,
|
|
1442
|
+
finalize: async (response, _durationMs, _request, runAfter, deadlineSignal) => {
|
|
1435
1443
|
await runAfter();
|
|
1436
|
-
const
|
|
1437
|
-
const bytes = new Uint8Array(buffer);
|
|
1444
|
+
const bytes = await readBoundedResponseBytes(response, Number.MAX_SAFE_INTEGER, deadlineSignal);
|
|
1438
1445
|
return {
|
|
1439
1446
|
bytes,
|
|
1440
1447
|
contentType: response.headers.get("content-type") ?? acceptHeader,
|
|
@@ -1517,6 +1524,8 @@ export class HonuaClient {
|
|
|
1517
1524
|
}
|
|
1518
1525
|
const durationMs = performance.now() - startTime;
|
|
1519
1526
|
const currentRequest = request;
|
|
1527
|
+
let bodyOwnsDeadline = false;
|
|
1528
|
+
let cancelDeadlineResponse;
|
|
1520
1529
|
let terminalErrorNotification;
|
|
1521
1530
|
const beginTerminalErrorNotification = (error, errorDurationMs) => {
|
|
1522
1531
|
if (terminalErrorNotification) {
|
|
@@ -1532,6 +1541,10 @@ export class HonuaClient {
|
|
|
1532
1541
|
};
|
|
1533
1542
|
const awaitDeadlineOwned = async (operation) => {
|
|
1534
1543
|
const owned = operation.catch(async (error) => {
|
|
1544
|
+
// The outer deadline catch decides retry, stale fallback, and the
|
|
1545
|
+
// normalized terminal error. A discarded attempt must not notify.
|
|
1546
|
+
if (timeout.signal?.aborted)
|
|
1547
|
+
throw error;
|
|
1535
1548
|
const notification = beginTerminalErrorNotification(error, performance.now() - startTime);
|
|
1536
1549
|
if (notification.claimed) {
|
|
1537
1550
|
await notification.completion;
|
|
@@ -1553,7 +1566,8 @@ export class HonuaClient {
|
|
|
1553
1566
|
};
|
|
1554
1567
|
try {
|
|
1555
1568
|
if (options.shortCircuit) {
|
|
1556
|
-
const
|
|
1569
|
+
const pending = options.shortCircuit(response, durationMs, currentRequest, runAfter);
|
|
1570
|
+
const shorted = await (options.deadlineThroughFinalize ? awaitDeadlineOwned(pending) : pending);
|
|
1557
1571
|
if (shorted)
|
|
1558
1572
|
return shorted.value;
|
|
1559
1573
|
}
|
|
@@ -1595,8 +1609,15 @@ export class HonuaClient {
|
|
|
1595
1609
|
await this.applyErrorInterceptors({ request: cloneRequestContext(request), error: httpError, durationMs });
|
|
1596
1610
|
throw httpError;
|
|
1597
1611
|
}
|
|
1598
|
-
const
|
|
1599
|
-
|
|
1612
|
+
const ownedResponse = options.streamResponse
|
|
1613
|
+
? responseWithDeadline(response, timeout.signal, () => timeout.dispose(), () => (timeout.didTimeout ? new HonuaTimeoutError(this.timeoutMs ?? 0) : new HonuaAbortError()))
|
|
1614
|
+
: undefined;
|
|
1615
|
+
const preparedResponse = ownedResponse?.response ?? response;
|
|
1616
|
+
cancelDeadlineResponse = ownedResponse?.cancel;
|
|
1617
|
+
const finalized = options.finalize(preparedResponse, durationMs, currentRequest, runAfter, timeout.signal);
|
|
1618
|
+
const result = await (options.deadlineThroughFinalize ? awaitDeadlineOwned(finalized) : finalized);
|
|
1619
|
+
bodyOwnsDeadline = options.streamResponse === true && response.body !== null;
|
|
1620
|
+
return result;
|
|
1600
1621
|
}
|
|
1601
1622
|
catch (error) {
|
|
1602
1623
|
if (!options.deadlineThroughFinalize || !timeout.signal?.aborted)
|
|
@@ -1612,12 +1633,19 @@ export class HonuaClient {
|
|
|
1612
1633
|
await this.sleepBeforeRetry(attempt, undefined, retrySignal);
|
|
1613
1634
|
continue;
|
|
1614
1635
|
}
|
|
1636
|
+
if (timeout.didTimeout) {
|
|
1637
|
+
const fallback = options.onTerminalError?.(terminalError);
|
|
1638
|
+
if (fallback !== undefined)
|
|
1639
|
+
return fallback;
|
|
1640
|
+
}
|
|
1615
1641
|
beginTerminalErrorNotification(terminalError, performance.now() - startTime);
|
|
1616
1642
|
throw terminalError;
|
|
1617
1643
|
}
|
|
1618
1644
|
finally {
|
|
1619
|
-
if (options.deadlineThroughFinalize)
|
|
1645
|
+
if (options.deadlineThroughFinalize && !bodyOwnsDeadline) {
|
|
1620
1646
|
timeout.dispose();
|
|
1647
|
+
cancelDeadlineResponse?.();
|
|
1648
|
+
}
|
|
1621
1649
|
}
|
|
1622
1650
|
}
|
|
1623
1651
|
}
|
|
@@ -1721,7 +1749,7 @@ export class HonuaClient {
|
|
|
1721
1749
|
* results or confusing `undefined` access. Returns a normalized
|
|
1722
1750
|
* {@link HonuaHttpError} when the envelope is present, otherwise `undefined`.
|
|
1723
1751
|
*/
|
|
1724
|
-
async function parseResponseBody(response, maxResponseBytes) {
|
|
1752
|
+
async function parseResponseBody(response, maxResponseBytes, requireJson = false) {
|
|
1725
1753
|
const text = maxResponseBytes === undefined
|
|
1726
1754
|
? await response.text()
|
|
1727
1755
|
: new TextDecoder().decode(await readBoundedResponseBytes(response, maxResponseBytes));
|
|
@@ -1732,9 +1760,20 @@ async function parseResponseBody(response, maxResponseBytes) {
|
|
|
1732
1760
|
return JSON.parse(text);
|
|
1733
1761
|
}
|
|
1734
1762
|
catch {
|
|
1763
|
+
if (requireJson) {
|
|
1764
|
+
throw new HonuaHttpError(response.status, "Expected a JSON response", { raw: text }, {
|
|
1765
|
+
responseHeaders: response.headers,
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1735
1768
|
return { raw: text };
|
|
1736
1769
|
}
|
|
1737
1770
|
}
|
|
1771
|
+
async function parseSuccessfulJsonBody(response, maxResponseBytes, signal) {
|
|
1772
|
+
const prepared = signal
|
|
1773
|
+
? bufferedResponse(response, await readBoundedResponseBytes(response, maxResponseBytes ?? Number.MAX_SAFE_INTEGER, signal))
|
|
1774
|
+
: response;
|
|
1775
|
+
return parseResponseBody(prepared, maxResponseBytes, true);
|
|
1776
|
+
}
|
|
1738
1777
|
async function readBoundedResponseBytes(response, maximum, signal) {
|
|
1739
1778
|
if (signal?.aborted) {
|
|
1740
1779
|
void response.body?.cancel().catch(() => undefined);
|
|
@@ -2046,3 +2085,66 @@ function isGrpcAdapterModule(value) {
|
|
|
2046
2085
|
typeof value.wrapConnectError === "function" &&
|
|
2047
2086
|
typeof value.streamProtoPages === "function");
|
|
2048
2087
|
}
|
|
2088
|
+
/** Keep raw response consumption inside the original request deadline without buffering. */
|
|
2089
|
+
function responseWithDeadline(response, signal, dispose, abortError) {
|
|
2090
|
+
if (!response.body)
|
|
2091
|
+
return { response, cancel: dispose };
|
|
2092
|
+
const reader = response.body.getReader();
|
|
2093
|
+
let finished = false;
|
|
2094
|
+
let controller;
|
|
2095
|
+
const cleanup = () => {
|
|
2096
|
+
if (finished)
|
|
2097
|
+
return;
|
|
2098
|
+
finished = true;
|
|
2099
|
+
signal?.removeEventListener("abort", abort);
|
|
2100
|
+
dispose();
|
|
2101
|
+
};
|
|
2102
|
+
const abort = () => {
|
|
2103
|
+
if (finished)
|
|
2104
|
+
return;
|
|
2105
|
+
cleanup();
|
|
2106
|
+
controller.error(abortError());
|
|
2107
|
+
void reader.cancel().catch(() => undefined);
|
|
2108
|
+
};
|
|
2109
|
+
const body = new ReadableStream({
|
|
2110
|
+
start(value) {
|
|
2111
|
+
controller = value;
|
|
2112
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
2113
|
+
if (signal?.aborted)
|
|
2114
|
+
abort();
|
|
2115
|
+
},
|
|
2116
|
+
async pull(value) {
|
|
2117
|
+
if (finished)
|
|
2118
|
+
return;
|
|
2119
|
+
try {
|
|
2120
|
+
const next = await reader.read();
|
|
2121
|
+
if (finished)
|
|
2122
|
+
return;
|
|
2123
|
+
if (next.done) {
|
|
2124
|
+
cleanup();
|
|
2125
|
+
value.close();
|
|
2126
|
+
}
|
|
2127
|
+
else
|
|
2128
|
+
value.enqueue(next.value);
|
|
2129
|
+
}
|
|
2130
|
+
catch (error) {
|
|
2131
|
+
if (finished)
|
|
2132
|
+
return;
|
|
2133
|
+
cleanup();
|
|
2134
|
+
value.error(error);
|
|
2135
|
+
}
|
|
2136
|
+
},
|
|
2137
|
+
async cancel(reason) {
|
|
2138
|
+
cleanup();
|
|
2139
|
+
await reader.cancel(reason);
|
|
2140
|
+
},
|
|
2141
|
+
});
|
|
2142
|
+
const prepared = preserveResponseSemantics(new Response(body, {
|
|
2143
|
+
status: response.status,
|
|
2144
|
+
statusText: response.statusText,
|
|
2145
|
+
headers: response.headers,
|
|
2146
|
+
}), response);
|
|
2147
|
+
// Cancel the original reader directly: cancelling one cloned Response branch
|
|
2148
|
+
// alone waits forever when an interceptor leaves the other tee branch unread.
|
|
2149
|
+
return { response: prepared, cancel: abort };
|
|
2150
|
+
}
|
package/core/geoservices.js
CHANGED
|
@@ -58,7 +58,7 @@ export async function queryFeaturesRest(transport, request, preferBinary) {
|
|
|
58
58
|
const params = new URLSearchParams();
|
|
59
59
|
params.set("f", preferBinary && (request.method === undefined || request.method === "GET") ? "pbf" : "json");
|
|
60
60
|
params.set("where", request.where ?? "1=1");
|
|
61
|
-
params
|
|
61
|
+
applyOutFields(params, request);
|
|
62
62
|
params.set("returnGeometry", String(request.returnGeometry ?? true));
|
|
63
63
|
serializeQueryParams(params, request);
|
|
64
64
|
appendQueryExtraParams(params, request);
|
|
@@ -84,7 +84,7 @@ export async function queryMapLayer(transport, request) {
|
|
|
84
84
|
const params = new URLSearchParams();
|
|
85
85
|
params.set("f", "json");
|
|
86
86
|
params.set("where", request.where ?? "1=1");
|
|
87
|
-
params
|
|
87
|
+
applyOutFields(params, request);
|
|
88
88
|
params.set("returnGeometry", String(request.returnGeometry ?? true));
|
|
89
89
|
serializeQueryParams(params, request);
|
|
90
90
|
appendQueryExtraParams(params, request);
|
|
@@ -348,6 +348,38 @@ function normalizeOutFields(outFields) {
|
|
|
348
348
|
}
|
|
349
349
|
return outFields;
|
|
350
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* Count-only and IDs-only queries must not send `outFields`. Some servers
|
|
353
|
+
* reject the combination. Flag values follow `parseExtraBoolean` in
|
|
354
|
+
* `grpc-adapter.ts`: boolean, non-zero numbers, and the strings
|
|
355
|
+
* `true` / `1` / `yes` (trimmed, case-insensitive).
|
|
356
|
+
*/
|
|
357
|
+
function querySuppressesOutFields(extraParams) {
|
|
358
|
+
return extraParamIsTrue(extraParams, "returnCountOnly") || extraParamIsTrue(extraParams, "returnIdsOnly");
|
|
359
|
+
}
|
|
360
|
+
function extraParamIsTrue(params, key) {
|
|
361
|
+
if (params === undefined) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
const value = params[key];
|
|
365
|
+
if (typeof value === "boolean") {
|
|
366
|
+
return value;
|
|
367
|
+
}
|
|
368
|
+
if (typeof value === "number") {
|
|
369
|
+
return value !== 0;
|
|
370
|
+
}
|
|
371
|
+
if (typeof value !== "string") {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
const normalized = value.trim().toLowerCase();
|
|
375
|
+
return normalized === "true" || normalized === "1" || normalized === "yes";
|
|
376
|
+
}
|
|
377
|
+
function applyOutFields(params, request) {
|
|
378
|
+
if (querySuppressesOutFields(request.extraParams)) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
params.set("outFields", normalizeOutFields(request.outFields));
|
|
382
|
+
}
|
|
351
383
|
function encodeFormValue(value) {
|
|
352
384
|
if (typeof value === "string") {
|
|
353
385
|
return value;
|
|
@@ -452,10 +484,14 @@ function appendQueryExtraParams(params, request) {
|
|
|
452
484
|
if (!request.extraParams) {
|
|
453
485
|
return;
|
|
454
486
|
}
|
|
487
|
+
const suppressOutFields = querySuppressesOutFields(request.extraParams);
|
|
455
488
|
for (const [key, value] of Object.entries(request.extraParams)) {
|
|
456
489
|
if (request.outSr !== undefined && (key === "outSr" || key === "outSR")) {
|
|
457
490
|
continue;
|
|
458
491
|
}
|
|
492
|
+
if (suppressOutFields && key === "outFields") {
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
459
495
|
params.set(key, String(value));
|
|
460
496
|
}
|
|
461
497
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grpc-adapter.d.ts","sourceRoot":"","sources":["../../../src/core/grpc-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,WAAW,EAWhB,KAAK,qBAAqB,
|
|
1
|
+
{"version":3,"file":"grpc-adapter.d.ts","sourceRoot":"","sources":["../../../src/core/grpc-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,WAAW,EAWhB,KAAK,qBAAqB,EAI3B,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EAEZ,sBAAsB,EACtB,kBAAkB,EAElB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAmGpB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,6EA0IhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,qBAAqB,GAC9B,kBAAkB,GAAG,kBAAkB,GAAG,sBAAsB,GAAG,mBAAmB,CAkDxF;AAyRD;;;;GAIG;AACH,wBAAuB,gBAAgB,CACrC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,GACjC,cAAc,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAsBjD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAiBtD"}
|
package/core/grpc-adapter.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { create } from "@bufbuild/protobuf";
|
|
2
|
-
import { CoordinateSchema, CoordinateSequenceSchema, DistanceUnit, FieldType, GeometrySchema, GeometryType, MultiPointGeometrySchema, PointGeometrySchema, PolygonGeometrySchema, PolylineGeometrySchema, QueryFeaturesRequestSchema, SpatialFilterSchema, SpatialReferenceSchema, SpatialRelationship,
|
|
3
|
-
import { HonuaGrpcError } from "./errors.js";
|
|
2
|
+
import { CoordinateSchema, CoordinateSequenceSchema, DistanceUnit, FieldType, GeometrySchema, GeometryType, MultiPointGeometrySchema, PointGeometrySchema, PolygonGeometrySchema, PolylineGeometrySchema, QueryFeaturesRequestSchema, SpatialFilterSchema, SpatialReferenceSchema, SpatialRelationship, } from "../gen/geospatial/v1/index.js";
|
|
3
|
+
import { HonuaCapabilityNotSupportedError, HonuaGrpcError } from "./errors.js";
|
|
4
4
|
import { geometryInputSpatialReference } from "./geometry-input-sr.js";
|
|
5
5
|
/**
|
|
6
6
|
* Maps proto FieldType enum values to Esri-style field type strings
|
|
@@ -71,15 +71,6 @@ const ESRI_TO_PROTO_DISTANCE_UNIT_MAP = {
|
|
|
71
71
|
miles: DistanceUnit.MILES,
|
|
72
72
|
mi: DistanceUnit.MILES,
|
|
73
73
|
};
|
|
74
|
-
const STATISTIC_TYPE_MAP = {
|
|
75
|
-
count: StatisticType.COUNT,
|
|
76
|
-
sum: StatisticType.SUM,
|
|
77
|
-
min: StatisticType.MIN,
|
|
78
|
-
max: StatisticType.MAX,
|
|
79
|
-
avg: StatisticType.AVG,
|
|
80
|
-
stddev: StatisticType.STDDEV,
|
|
81
|
-
var: StatisticType.VAR,
|
|
82
|
-
};
|
|
83
74
|
const MAX_SAFE_INTEGER_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
84
75
|
const MIN_SAFE_INTEGER_BIGINT = BigInt(Number.MIN_SAFE_INTEGER);
|
|
85
76
|
const MIN_PROTO_INT64 = -(1n << 63n);
|
|
@@ -105,6 +96,12 @@ function toProtoPageInt64(field, value) {
|
|
|
105
96
|
* Converts a SDK QueryFeaturesRequest into a proto QueryFeaturesRequest message.
|
|
106
97
|
*/
|
|
107
98
|
export function toProtoQueryRequest(request) {
|
|
99
|
+
if (request.outStatistics !== undefined ||
|
|
100
|
+
request.groupByFieldsForStatistics !== undefined ||
|
|
101
|
+
request.extraParams?.outStatistics !== undefined ||
|
|
102
|
+
request.extraParams?.groupByFieldsForStatistics !== undefined) {
|
|
103
|
+
throw new HonuaCapabilityNotSupportedError("queryAggregate", "grpc", `${request.serviceId}/${request.layerId}`);
|
|
104
|
+
}
|
|
108
105
|
const msg = create(QueryFeaturesRequestSchema);
|
|
109
106
|
msg.serviceId = request.serviceId;
|
|
110
107
|
msg.layerId = request.layerId;
|
|
@@ -148,15 +145,6 @@ export function toProtoQueryRequest(request) {
|
|
|
148
145
|
if (request.returnDistinctValues !== undefined) {
|
|
149
146
|
msg.returnDistinct = request.returnDistinctValues;
|
|
150
147
|
}
|
|
151
|
-
if (request.groupByFieldsForStatistics !== undefined) {
|
|
152
|
-
msg.groupBy = request.groupByFieldsForStatistics
|
|
153
|
-
.split(",")
|
|
154
|
-
.map((field) => field.trim())
|
|
155
|
-
.filter(Boolean);
|
|
156
|
-
}
|
|
157
|
-
if (request.outStatistics !== undefined) {
|
|
158
|
-
msg.outStatistics = toProtoStatistics(request.outStatistics);
|
|
159
|
-
}
|
|
160
148
|
if (request.geometry !== undefined) {
|
|
161
149
|
const filter = create(SpatialFilterSchema);
|
|
162
150
|
const { geometry, spatialReference } = toProtoGeometry(request.geometry);
|
|
@@ -267,7 +255,7 @@ export function fromProtoQueryResponse(response) {
|
|
|
267
255
|
geometryType: GEOMETRY_TYPE_MAP[response.geometryType] ?? "esriGeometryPoint",
|
|
268
256
|
spatialReference: response.spatialReference ? convertSpatialReference(response.spatialReference) : undefined,
|
|
269
257
|
fields: response.fields.map(convertField),
|
|
270
|
-
features: response.features.map(convertFeature),
|
|
258
|
+
features: response.features.map((feature) => convertFeature(feature, response.objectIdFieldName)),
|
|
271
259
|
exceededTransferLimit: response.exceededTransferLimit || undefined,
|
|
272
260
|
};
|
|
273
261
|
}
|
|
@@ -320,45 +308,6 @@ function parseExtraString(params, key) {
|
|
|
320
308
|
}
|
|
321
309
|
return String(value);
|
|
322
310
|
}
|
|
323
|
-
function toProtoStatistics(value) {
|
|
324
|
-
const raw = typeof value === "string" ? parseStatisticsString(value) : value;
|
|
325
|
-
return raw.map((item, index) => {
|
|
326
|
-
const statisticTypeValue = item.statisticType;
|
|
327
|
-
if (typeof statisticTypeValue !== "string") {
|
|
328
|
-
throw new Error(`Invalid outStatistics[${index}].statisticType`);
|
|
329
|
-
}
|
|
330
|
-
const statisticType = STATISTIC_TYPE_MAP[statisticTypeValue.toLowerCase()];
|
|
331
|
-
if (!statisticType) {
|
|
332
|
-
throw new Error(`Unsupported statisticType for gRPC transport: ${statisticTypeValue}`);
|
|
333
|
-
}
|
|
334
|
-
const onStatisticFieldValue = item.onStatisticField;
|
|
335
|
-
if (typeof onStatisticFieldValue !== "string" || onStatisticFieldValue.trim().length === 0) {
|
|
336
|
-
throw new Error(`Invalid outStatistics[${index}].onStatisticField`);
|
|
337
|
-
}
|
|
338
|
-
const outStatisticFieldNameValue = item.outStatisticFieldName;
|
|
339
|
-
const outStatisticFieldName = typeof outStatisticFieldNameValue === "string" && outStatisticFieldNameValue.trim().length > 0
|
|
340
|
-
? outStatisticFieldNameValue.trim()
|
|
341
|
-
: `${statisticTypeValue}_${onStatisticFieldValue}`;
|
|
342
|
-
const definition = create(StatisticDefinitionSchema);
|
|
343
|
-
definition.onStatisticField = onStatisticFieldValue;
|
|
344
|
-
definition.statisticType = statisticType;
|
|
345
|
-
definition.outStatisticFieldName = outStatisticFieldName;
|
|
346
|
-
return definition;
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
function parseStatisticsString(value) {
|
|
350
|
-
let parsed;
|
|
351
|
-
try {
|
|
352
|
-
parsed = JSON.parse(value);
|
|
353
|
-
}
|
|
354
|
-
catch {
|
|
355
|
-
throw new Error("Invalid outStatistics JSON for gRPC transport.");
|
|
356
|
-
}
|
|
357
|
-
if (!Array.isArray(parsed)) {
|
|
358
|
-
throw new Error("outStatistics JSON must be an array for gRPC transport.");
|
|
359
|
-
}
|
|
360
|
-
return parsed;
|
|
361
|
-
}
|
|
362
311
|
function toProtoGeometry(geometryValue) {
|
|
363
312
|
const source = parseGeometryValue(geometryValue);
|
|
364
313
|
const geometry = create(GeometrySchema);
|
|
@@ -557,12 +506,17 @@ function isPolygon(value) {
|
|
|
557
506
|
* existing queryFeaturesStream yield type.
|
|
558
507
|
*/
|
|
559
508
|
export async function* streamProtoPages(stream) {
|
|
509
|
+
// Metadata is populated on the first page only; later pages reuse it.
|
|
510
|
+
let objectIdFieldName = "";
|
|
560
511
|
try {
|
|
561
512
|
for await (const page of stream) {
|
|
513
|
+
if (page.objectIdFieldName) {
|
|
514
|
+
objectIdFieldName = page.objectIdFieldName;
|
|
515
|
+
}
|
|
562
516
|
if (page.features.length === 0 && page.isLastPage) {
|
|
563
517
|
break;
|
|
564
518
|
}
|
|
565
|
-
const features = page.features.map(convertFeature);
|
|
519
|
+
const features = page.features.map((feature) => convertFeature(feature, objectIdFieldName));
|
|
566
520
|
if (features.length > 0) {
|
|
567
521
|
yield features;
|
|
568
522
|
}
|
|
@@ -614,17 +568,32 @@ function convertField(field) {
|
|
|
614
568
|
nullable: field.nullable,
|
|
615
569
|
};
|
|
616
570
|
}
|
|
617
|
-
|
|
571
|
+
/**
|
|
572
|
+
* geospatial.v1 carries the object ID in `Feature.id` and the server no
|
|
573
|
+
* longer repeats it in `Feature.attributes` (honua-server#5330), so it is
|
|
574
|
+
* restored under the declared `objectIdFieldName` to match `f=json` output.
|
|
575
|
+
* An `id` of 0 means no object ID (for example distinct projections), and an
|
|
576
|
+
* attribute already present under that name in any casing (a legacy server
|
|
577
|
+
* repeating it, or a differing custom public ID) is kept as sent.
|
|
578
|
+
*/
|
|
579
|
+
function convertFeature(feature, objectIdFieldName) {
|
|
618
580
|
const attributes = {};
|
|
619
581
|
for (const [key, attrValue] of Object.entries(feature.attributes)) {
|
|
620
582
|
attributes[key] = convertAttributeValue(attrValue);
|
|
621
583
|
}
|
|
584
|
+
if (objectIdFieldName.length > 0 && feature.id !== 0n && !hasAttributeIgnoreCase(attributes, objectIdFieldName)) {
|
|
585
|
+
attributes[objectIdFieldName] = toSafeNumberOrString(feature.id);
|
|
586
|
+
}
|
|
622
587
|
const result = { attributes };
|
|
623
588
|
if (feature.geometry) {
|
|
624
589
|
result.geometry = convertGeometry(feature.geometry);
|
|
625
590
|
}
|
|
626
591
|
return result;
|
|
627
592
|
}
|
|
593
|
+
function hasAttributeIgnoreCase(attributes, name) {
|
|
594
|
+
const lowered = name.toLowerCase();
|
|
595
|
+
return Object.keys(attributes).some((key) => key.toLowerCase() === lowered);
|
|
596
|
+
}
|
|
628
597
|
function convertAttributeValue(attr) {
|
|
629
598
|
switch (attr.value.case) {
|
|
630
599
|
case "stringValue":
|
package/core/odata.d.ts
CHANGED
|
@@ -311,6 +311,7 @@ export declare class HonuaOdataEntitySet {
|
|
|
311
311
|
raw(method: string, path: string, init?: RequestInit): Promise<Response>;
|
|
312
312
|
private entitySetPath;
|
|
313
313
|
private fetchMetadata;
|
|
314
|
+
private checkNextLink;
|
|
314
315
|
private followNextLink;
|
|
315
316
|
/**
|
|
316
317
|
* Wrap `HonuaClient.pipelineRequestJson` with OData-shaped query
|
|
@@ -401,5 +402,7 @@ export declare function buildOdataSpatialFilter(spatialFilter: {
|
|
|
401
402
|
* text from the same geometry value.
|
|
402
403
|
*/
|
|
403
404
|
export declare function geometryToWkt(geometry: Record<string, unknown>, geometryType: string): string;
|
|
405
|
+
/** Group clockwise Esri exteriors and assign counter-clockwise holes by containment, independent of order. */
|
|
406
|
+
export declare function groupEsriPolygonRings(rings: unknown[][][]): unknown[][][][];
|
|
404
407
|
export {};
|
|
405
408
|
//# sourceMappingURL=odata.d.ts.map
|
package/core/odata.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odata.d.ts","sourceRoot":"","sources":["../../../src/core/odata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,2BAA2B,EAQjC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"odata.d.ts","sourceRoot":"","sources":["../../../src/core/odata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,2BAA2B,EAQjC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,WAAW,CAAC;IACpB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,sDAAsD;AACtD,MAAM,WAAW,wBAAwB;IACvC,wDAAwD;IACxD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC5C,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;CAClD;AAED,qDAAqD;AACrD,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,6DAA6D;AAC7D,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,kDAAkD;IAClD,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IAClD,yEAAyE;IACzE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC,CAAC,CAAC;IACjE,oDAAoD;IACpD,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC,CAAC,CAAC;IACxE,+DAA+D;IAC/D,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAC7D,oEAAoE;IACpE,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3C,4FAA4F;IAC5F,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC,CAAC;IACzE,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,kFAAkF;AAClF,MAAM,WAAW,sCAAsC;IACrD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;CAClD;AAKD,UAAU,uCAAuC;IAC/C,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC,CAAC,CAAC;IAC1E,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC,CAAC,CAAC;IAChF,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;IACrE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;CACpD;AAED,8FAA8F;AAC9F,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,kBAAkB,GAC3B,sCAAsC,GAAG,SAAS,CAKpD;AAED,8FAA8F;AAC9F,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,kBAAkB,GAC3B,uCAAuC,GAAG,SAAS,CAKrD;AAgBD,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IACzC,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,yBAAyB,GACjC;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAA;CAAE,GAClF;IACE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,MAAM,EACX,yBAAyB,GACzB,mBAAmB,GACnB,+BAA+B,GAC/B,qBAAqB,GACrB,uBAAuB,GACvB,sBAAsB,GACtB,cAAc,GACd,sBAAsB,CAAC;CAC5B,CAAC;AAEN,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACtD,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,yBAAyB,CAAC;CAClD;AAED;;;;GAIG;AACH,MAAM,WAAW,gCAAgC;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAWD,6DAA6D;AAC7D,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,4DAA4D;AAC5D,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID;;;;;GAKG;AACH,qBAAa,mBAAmB;IAC9B,SAAgB,MAAM,EAAE,WAAW,CAAC;IACpC,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC;;;;;;OAMG;IACH,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,gBAAgB,CAA0C;gBAE/C,OAAO,EAAE,0BAA0B;IAOtD;;;;OAIG;IACU,QAAQ,CAAC,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwD7F,wCAAwC;IAC3B,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAE,qBAA0B,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAY/G;;;;;;;;OAQG;IACU,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/C,MAAM,GAAE,qBAA0B,GACjC,OAAO,CAAC;QACT,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IA4BF,qEAAqE;IACvD,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnD,MAAM,GAAE,qBAA0B,GACjC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC;IAWrD,4CAA4C;IAC/B,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,CAAC,CAAC;IAOb;;;;;;OAMG;IACU,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAOzB,qDAAqD;IACxC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvF;;;;;;;;;;;;OAYG;IACU,KAAK,CAChB,UAAU,EAAE,aAAa,CAAC,wBAAwB,CAAC,EACnD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,qBAAqB,CAAC;IAwBjC;;;;;OAKG;IACU,KAAK,CAChB,eAAe,EAAE,MAAM,EACvB,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrD,OAAO,CAAC,yBAAyB,CAAC;IAUrC;;;OAGG;IACU,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7C,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,qBAA0B,GACjC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAI7B;;;;OAIG;IACW,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7C,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrD,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC;IAqB1D;;;;;OAKG;IACU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOzF,OAAO,CAAC,aAAa;YAIP,aAAa;IA4C3B,OAAO,CAAC,aAAa;YASP,cAAc;IAc5B;;;;;;;OAOG;YACW,WAAW;CAyB1B;AA2HD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAwJlE;AAqHD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE,CAM3G;AAyOD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqC/D;AAgDD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,yBAAyB;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACpD,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B;AAED,wBAAgB,uBAAuB,CACrC,aAAa,EAAE;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAsBR;AAkED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAqC7F;AAED,8GAA8G;AAC9G,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,CAgC3E"}
|