@flowselections/pick-schermen-kwekers 1.0.21 → 1.0.23
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-lib/components/pick/PickScherm.d.ts.map +1 -1
- package/dist-lib/components/pick/PickScherm.js +56 -27
- package/dist-lib/hooks/usePickConfig.d.ts +11 -11
- package/dist-lib/hooks/usePickConfig.d.ts.map +1 -1
- package/dist-lib/hooks/usePickQueue.d.ts +5 -3
- package/dist-lib/hooks/usePickQueue.d.ts.map +1 -1
- package/dist-lib/hooks/usePickQueue.js +17 -4
- package/dist-lib/hooks/usePickReferenceData.d.ts +1 -1
- package/dist-lib/hooks/usePickReferenceData.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +4754 -230
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +4754 -230
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.js +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +4754 -230
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.js +1 -1
- package/dist-lib/integrations/supabase/previewAuthStorage.d.ts +1 -1
- package/dist-lib/integrations/supabase/previewAuthStorage.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/previewAuthStorage.js +8 -1
- package/dist-lib/integrations/supabase/types.d.ts +4795 -203
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/__tests__/pickRobustness.test.d.ts +2 -0
- package/dist-lib/lib/__tests__/pickRobustness.test.d.ts.map +1 -0
- package/dist-lib/lib/__tests__/pickRobustness.test.js +68 -0
- package/dist-lib/lib/pickApi.d.ts +25 -1
- package/dist-lib/lib/pickApi.d.ts.map +1 -1
- package/dist-lib/lib/pickApi.js +56 -3
- package/dist-lib/lib/pickRetry.d.ts +13 -0
- package/dist-lib/lib/pickRetry.d.ts.map +1 -0
- package/dist-lib/lib/pickRetry.js +52 -0
- package/dist-lib/lib/pickUiText.d.ts.map +1 -1
- package/dist-lib/lib/pickUiText.js +5 -3
- package/dist-lib/lib/pickVerify.d.ts +15 -0
- package/dist-lib/lib/pickVerify.d.ts.map +1 -0
- package/dist-lib/lib/pickVerify.js +32 -0
- package/package.json +5 -4
- package/dist-lib/lib/layoutApi.d.ts +0 -23
- package/dist-lib/lib/layoutApi.d.ts.map +0 -1
- package/dist-lib/lib/layoutApi.js +0 -94
- package/dist-lib/lib/layoutMaker/documentProfiles.d.ts +0 -50
- package/dist-lib/lib/layoutMaker/documentProfiles.d.ts.map +0 -1
- package/dist-lib/lib/layoutMaker/documentProfiles.js +0 -458
- package/dist-lib/lib/layoutMaker/documentTypes.d.ts +0 -123
- package/dist-lib/lib/layoutMaker/documentTypes.d.ts.map +0 -1
- package/dist-lib/lib/layoutMaker/documentTypes.js +0 -74
- package/dist-lib/lib/layoutMaker/logoLibrary.d.ts +0 -13
- package/dist-lib/lib/layoutMaker/logoLibrary.d.ts.map +0 -1
- package/dist-lib/lib/layoutMaker/logoLibrary.js +0 -54
- package/dist-lib/lib/layoutMaker/pakbonBuilder.d.ts +0 -196
- package/dist-lib/lib/layoutMaker/pakbonBuilder.d.ts.map +0 -1
- package/dist-lib/lib/layoutMaker/pakbonBuilder.js +0 -813
- package/dist-lib/lib/layoutMaker/pakbonHtml.d.ts +0 -48
- package/dist-lib/lib/layoutMaker/pakbonHtml.d.ts.map +0 -1
- package/dist-lib/lib/layoutMaker/pakbonHtml.js +0 -703
- package/dist-lib/lib/layoutRenderer.d.ts +0 -7
- package/dist-lib/lib/layoutRenderer.d.ts.map +0 -1
- package/dist-lib/lib/layoutRenderer.js +0 -233
- package/dist-lib/lib/layoutTypes.d.ts +0 -84
- package/dist-lib/lib/layoutTypes.d.ts.map +0 -1
- package/dist-lib/lib/layoutTypes.js +0 -25
- package/dist-lib/lib/orderContext.d.ts +0 -50
- package/dist-lib/lib/orderContext.d.ts.map +0 -1
- package/dist-lib/lib/orderContext.js +0 -162
- package/dist-lib/lib/pakbonOrderInput.d.ts +0 -8
- package/dist-lib/lib/pakbonOrderInput.d.ts.map +0 -1
- package/dist-lib/lib/pakbonOrderInput.js +0 -150
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickRobustness.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/pickRobustness.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
vi.mock("@flowselections/core", () => ({ supabase: {} }));
|
|
3
|
+
import { verifyRowsWith, createRetryingDb } from "../pickApi";
|
|
4
|
+
import { withRetry } from "../pickRetry";
|
|
5
|
+
import { rowsToVerify, rowFingerprint } from "../pickVerify";
|
|
6
|
+
import { friendlyPickError } from "../pickUiText";
|
|
7
|
+
const rows = (n) => Array.from({ length: n }, (_, i) => ({ id: `id-${i}`, updated_at: "t1", payload: {} }));
|
|
8
|
+
const noSleep = { sleep: async () => { } };
|
|
9
|
+
describe("gebundelde controle", () => {
|
|
10
|
+
for (const n of [33, 100]) {
|
|
11
|
+
it(`${n} rijen: 1 aanroep i.p.v. ${n * 2}`, async () => {
|
|
12
|
+
const rpc = vi.fn(async (_fn, args) => ({
|
|
13
|
+
data: args["_rows"].map((r) => ({ id: r.id, plan: null, status: null })),
|
|
14
|
+
error: null,
|
|
15
|
+
}));
|
|
16
|
+
const out = await verifyRowsWith({ rpc }, rows(n).map((r) => ({ id: r.id, ref: r.id })));
|
|
17
|
+
expect(out).toHaveLength(n);
|
|
18
|
+
expect(rpc).toHaveBeenCalledTimes(1);
|
|
19
|
+
console.log(`[test] ${n} rijen → oud ${n * 2} aanroepen, nieuw ${rpc.mock.calls.length}`);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
it("ongewijzigde, printklare rijen: 0 aanroepen in de volgende ronde", () => {
|
|
23
|
+
const items = rows(33);
|
|
24
|
+
const memo = new Map();
|
|
25
|
+
const now = 1000000;
|
|
26
|
+
items.forEach((it) => memo.set(it.id, { fingerprint: rowFingerprint(it), ready: true, checkedAt: now }));
|
|
27
|
+
expect(rowsToVerify(items, memo, now + 15000)).toHaveLength(0);
|
|
28
|
+
// gewijzigde rij gaat wel mee
|
|
29
|
+
const changed = [...items];
|
|
30
|
+
changed[0] = { ...changed[0], updated_at: "t2" };
|
|
31
|
+
expect(rowsToVerify(changed, memo, now + 15000)).toHaveLength(1);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe("herhaalpoging", () => {
|
|
35
|
+
it("Failed to fetch bij pick_claim_next_document: herhaalt en slaagt", async () => {
|
|
36
|
+
const rpc = vi
|
|
37
|
+
.fn()
|
|
38
|
+
.mockResolvedValueOnce({ data: null, error: { message: "TypeError: Failed to fetch" } })
|
|
39
|
+
.mockResolvedValueOnce({ data: { id: "ok" }, error: null });
|
|
40
|
+
const res = await withRetry(() => rpc("pick_claim_next_document"), noSleep);
|
|
41
|
+
expect(res.error).toBeNull();
|
|
42
|
+
expect(rpc).toHaveBeenCalledTimes(2);
|
|
43
|
+
});
|
|
44
|
+
it("de gedeelde client herhaalt ook", async () => {
|
|
45
|
+
const base = {
|
|
46
|
+
rpc: vi.fn().mockRejectedValueOnce(new TypeError("Failed to fetch")).mockResolvedValue({ data: 1, error: null }),
|
|
47
|
+
};
|
|
48
|
+
vi.useFakeTimers();
|
|
49
|
+
const p = createRetryingDb(base).rpc("pick_claim_next_document");
|
|
50
|
+
await vi.runAllTimersAsync();
|
|
51
|
+
expect((await p).data).toBe(1);
|
|
52
|
+
expect(base.rpc).toHaveBeenCalledTimes(2);
|
|
53
|
+
vi.useRealTimers();
|
|
54
|
+
});
|
|
55
|
+
it("blijvende netwerkfout: 4 pogingen, dan nette melding", async () => {
|
|
56
|
+
const rpc = vi.fn().mockResolvedValue({ data: null, error: { message: "Failed to fetch" } });
|
|
57
|
+
const res = await withRetry(() => rpc(), noSleep);
|
|
58
|
+
expect(rpc).toHaveBeenCalledTimes(4);
|
|
59
|
+
const f = friendlyPickError(new Error(res.error.message), "nl");
|
|
60
|
+
expect(f.message).toMatch(/Geen verbinding/);
|
|
61
|
+
expect(f.message).not.toMatch(/Failed to fetch/);
|
|
62
|
+
});
|
|
63
|
+
it("databasefout wordt niet herhaald", async () => {
|
|
64
|
+
const rpc = vi.fn().mockResolvedValue({ data: null, error: { message: "Station is niet actief" } });
|
|
65
|
+
await withRetry(() => rpc(), noSleep);
|
|
66
|
+
expect(rpc).toHaveBeenCalledTimes(1);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { supabase } from "@flowselections/core";
|
|
2
2
|
import type { PickCartPlan, PickCountry, PickDashboardRow, PickDocumentType, PickLock, PickActivePrinter, PickPrintJob, PickPrintPlek, PickStationPrintPlek, PickStationPrintPlekRow, PickPrinter, PickQueueItem, PickScreen, PickSortRule, PickStation, PickStationType, PickStatus, PickTask } from "./pickTypes";
|
|
3
|
-
|
|
3
|
+
type PickDbClient = {
|
|
4
4
|
from: (t: string) => any;
|
|
5
5
|
rpc: (fn: string, args?: Record<string, unknown>) => Promise<{
|
|
6
6
|
data: any;
|
|
@@ -10,7 +10,25 @@ declare const db: {
|
|
|
10
10
|
removeChannel: (c: any) => void;
|
|
11
11
|
auth: typeof supabase.auth;
|
|
12
12
|
};
|
|
13
|
+
/** Zelfde client, maar RPC-aanroepen vangen tijdelijke netwerkhaperingen op. */
|
|
14
|
+
export declare function createRetryingDb(base: PickDbClient): PickDbClient;
|
|
15
|
+
declare const db: PickDbClient;
|
|
13
16
|
export { db as pickDb };
|
|
17
|
+
export interface VerifiedRow {
|
|
18
|
+
id: string;
|
|
19
|
+
plan: PickCartPlan | null;
|
|
20
|
+
status: {
|
|
21
|
+
ready: boolean;
|
|
22
|
+
released: boolean;
|
|
23
|
+
reason: string | null;
|
|
24
|
+
} | null;
|
|
25
|
+
error: string | null;
|
|
26
|
+
}
|
|
27
|
+
/** Eén aanroep per blok van max. 200 regels i.p.v. twee per regel. */
|
|
28
|
+
export declare function verifyRowsWith(client: Pick<PickDbClient, "rpc">, rows: {
|
|
29
|
+
id: string;
|
|
30
|
+
ref: string | null;
|
|
31
|
+
}[]): Promise<VerifiedRow[]>;
|
|
14
32
|
export interface PickBatchPrintJob {
|
|
15
33
|
cartId: string;
|
|
16
34
|
cartLabel: string | null;
|
|
@@ -61,6 +79,7 @@ export declare const pickApi: {
|
|
|
61
79
|
* De database knijpt de aanroep af (max. 1x per minuut voor alle schermen
|
|
62
80
|
* samen), zodat tien geopende pickschermen niet tien keer synchroniseren.
|
|
63
81
|
*/
|
|
82
|
+
/** Gooit een fout als de synchronisatie (of de laatst bekende ronde) een fout meldde. */
|
|
64
83
|
syncQueue(): Promise<void>;
|
|
65
84
|
/** Aantallen van de actuele pickdag: nog printen versus geprint (in de database geteld). */
|
|
66
85
|
dayCounts(args: {
|
|
@@ -158,6 +177,11 @@ export declare const pickApi: {
|
|
|
158
177
|
* Karplan van de hele pick-eenheid: bij een bufferorder alle karren van alle
|
|
159
178
|
* orders in de buffer samen. Nummers en totalen komen uit de Engine.
|
|
160
179
|
*/
|
|
180
|
+
/** Gebundelde gereedheidscontrole voor meerdere regels. */
|
|
181
|
+
verifyRows(rows: {
|
|
182
|
+
id: string;
|
|
183
|
+
ref: string | null;
|
|
184
|
+
}[]): Promise<VerifiedRow[]>;
|
|
161
185
|
queueCartPlan(queueItemId: string): Promise<PickCartPlan | null>;
|
|
162
186
|
/** Zet één kar in de printopdracht en rondt alleen deze kar af. */
|
|
163
187
|
completePrintCart(itemId: string, sessionId: string, cartId: string): Promise<PickQueueItem>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pickApi.d.ts","sourceRoot":"","sources":["../../src/lib/pickApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,WAAW,EAEX,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,UAAU,EACV,QAAQ,EACT,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"pickApi.d.ts","sourceRoot":"","sources":["../../src/lib/pickApi.ts"],"names":[],"mappings":"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"}
|
package/dist-lib/lib/pickApi.js
CHANGED
|
@@ -1,9 +1,51 @@
|
|
|
1
1
|
import { supabase } from "@flowselections/core";
|
|
2
2
|
import { parsePickCartPlan } from "./pickTypes";
|
|
3
3
|
import { safeArray } from "./pickTypes";
|
|
4
|
-
|
|
5
|
-
const
|
|
4
|
+
import { withRetry } from "./pickRetry";
|
|
5
|
+
const raw = supabase;
|
|
6
|
+
/** Zelfde client, maar RPC-aanroepen vangen tijdelijke netwerkhaperingen op. */
|
|
7
|
+
export function createRetryingDb(base) {
|
|
8
|
+
return {
|
|
9
|
+
from: (t) => base.from(t),
|
|
10
|
+
rpc: (fn, args) => withRetry(() => base.rpc(fn, args)),
|
|
11
|
+
channel: (name) => base.channel(name),
|
|
12
|
+
removeChannel: (c) => base.removeChannel(c),
|
|
13
|
+
get auth() {
|
|
14
|
+
return base.auth;
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const db = createRetryingDb(raw);
|
|
6
19
|
export { db as pickDb };
|
|
20
|
+
function parsePlanStatus(data) {
|
|
21
|
+
if (!data || typeof data !== "object")
|
|
22
|
+
return null;
|
|
23
|
+
const row = data;
|
|
24
|
+
return {
|
|
25
|
+
ready: row["ready"] === true,
|
|
26
|
+
released: row["released"] === true,
|
|
27
|
+
reason: typeof row["reason"] === "string" ? row["reason"] : null,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Eén aanroep per blok van max. 200 regels i.p.v. twee per regel. */
|
|
31
|
+
export async function verifyRowsWith(client, rows) {
|
|
32
|
+
const out = [];
|
|
33
|
+
for (let i = 0; i < rows.length; i += 200) {
|
|
34
|
+
const chunk = rows.slice(i, i + 200);
|
|
35
|
+
const { data, error } = await client.rpc("pick_verify_rows", { _rows: chunk });
|
|
36
|
+
if (error)
|
|
37
|
+
throw new Error(error.message);
|
|
38
|
+
for (const r of safeArray(data)) {
|
|
39
|
+
out.push({
|
|
40
|
+
id: String(r["id"]),
|
|
41
|
+
plan: parsePickCartPlan(r["plan"]),
|
|
42
|
+
status: parsePlanStatus(r["status"]),
|
|
43
|
+
error: typeof r["error"] === "string" ? r["error"] : null,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
7
49
|
function unwrap(res) {
|
|
8
50
|
if (res.error)
|
|
9
51
|
throw new Error(res.error.message);
|
|
@@ -143,10 +185,17 @@ export const pickApi = {
|
|
|
143
185
|
* De database knijpt de aanroep af (max. 1x per minuut voor alle schermen
|
|
144
186
|
* samen), zodat tien geopende pickschermen niet tien keer synchroniseren.
|
|
145
187
|
*/
|
|
188
|
+
/** Gooit een fout als de synchronisatie (of de laatst bekende ronde) een fout meldde. */
|
|
146
189
|
async syncQueue() {
|
|
147
|
-
const { error } = await db.rpc("pick_sync_queue_throttled", { _min_seconds: 60 });
|
|
190
|
+
const { data, error } = await db.rpc("pick_sync_queue_throttled", { _min_seconds: 60 });
|
|
148
191
|
if (error)
|
|
149
192
|
throw new Error(error.message);
|
|
193
|
+
const row = (data && typeof data === "object" ? data : {});
|
|
194
|
+
const syncError = typeof row["error"] === "string" && row["error"] ? row["error"] : null;
|
|
195
|
+
if (syncError) {
|
|
196
|
+
console.error("[pick] Synchronisatie pickwachtrij mislukt:", syncError);
|
|
197
|
+
throw new Error(syncError);
|
|
198
|
+
}
|
|
150
199
|
},
|
|
151
200
|
/** Aantallen van de actuele pickdag: nog printen versus geprint (in de database geteld). */
|
|
152
201
|
async dayCounts(args) {
|
|
@@ -354,6 +403,10 @@ export const pickApi = {
|
|
|
354
403
|
* Karplan van de hele pick-eenheid: bij een bufferorder alle karren van alle
|
|
355
404
|
* orders in de buffer samen. Nummers en totalen komen uit de Engine.
|
|
356
405
|
*/
|
|
406
|
+
/** Gebundelde gereedheidscontrole voor meerdere regels. */
|
|
407
|
+
verifyRows(rows) {
|
|
408
|
+
return verifyRowsWith(db, rows);
|
|
409
|
+
},
|
|
357
410
|
async queueCartPlan(queueItemId) {
|
|
358
411
|
const { data, error } = await db.rpc("pick_queue_cart_plan", { _queue_item_id: queueItemId });
|
|
359
412
|
if (error)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const RETRY_DELAYS_MS: readonly [300, 900, 2000];
|
|
2
|
+
export declare function isNetworkError(error: unknown): boolean;
|
|
3
|
+
type RpcResult = {
|
|
4
|
+
data: unknown;
|
|
5
|
+
error: unknown;
|
|
6
|
+
};
|
|
7
|
+
/** Voert een Supabase-aanroep uit; herhaalt alleen bij netwerkfouten. */
|
|
8
|
+
export declare function withRetry<T extends RpcResult>(call: () => PromiseLike<T>, opts?: {
|
|
9
|
+
delays?: readonly number[];
|
|
10
|
+
sleep?: (ms: number) => Promise<void>;
|
|
11
|
+
}): Promise<T>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=pickRetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickRetry.d.ts","sourceRoot":"","sources":["../../src/lib/pickRetry.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,2BAA4B,CAAC;AAmBzD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOtD;AAED,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnD,yEAAyE;AACzE,wBAAsB,SAAS,CAAC,CAAC,SAAS,SAAS,EACjD,IAAI,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,EAC1B,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAO,GAC/E,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Herhaalpogingen voor tijdelijke netwerkhaperingen. Databasefouten
|
|
2
|
+
// (bijv. "niet actief", "andere sessie") worden nooit herhaald.
|
|
3
|
+
export const RETRY_DELAYS_MS = [300, 900, 2000];
|
|
4
|
+
const NETWORK_PATTERNS = [
|
|
5
|
+
"failed to fetch",
|
|
6
|
+
"networkerror",
|
|
7
|
+
"network request failed",
|
|
8
|
+
"load failed",
|
|
9
|
+
"fetch failed",
|
|
10
|
+
"timeout",
|
|
11
|
+
"timed out",
|
|
12
|
+
"econnreset",
|
|
13
|
+
"502",
|
|
14
|
+
"503",
|
|
15
|
+
"504",
|
|
16
|
+
"bad gateway",
|
|
17
|
+
"service unavailable",
|
|
18
|
+
"gateway timeout",
|
|
19
|
+
];
|
|
20
|
+
export function isNetworkError(error) {
|
|
21
|
+
if (!error)
|
|
22
|
+
return false;
|
|
23
|
+
const e = error;
|
|
24
|
+
const status = Number(e.status);
|
|
25
|
+
if (status === 502 || status === 503 || status === 504)
|
|
26
|
+
return true;
|
|
27
|
+
const msg = (typeof e.message === "string" ? e.message : String(error)).toLowerCase();
|
|
28
|
+
return NETWORK_PATTERNS.some((p) => msg.includes(p));
|
|
29
|
+
}
|
|
30
|
+
/** Voert een Supabase-aanroep uit; herhaalt alleen bij netwerkfouten. */
|
|
31
|
+
export async function withRetry(call, opts = {}) {
|
|
32
|
+
const delays = opts.delays ?? RETRY_DELAYS_MS;
|
|
33
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
34
|
+
for (let attempt = 0;; attempt += 1) {
|
|
35
|
+
let result = null;
|
|
36
|
+
let thrown = null;
|
|
37
|
+
try {
|
|
38
|
+
result = await call();
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
thrown = e;
|
|
42
|
+
}
|
|
43
|
+
const err = thrown ?? result?.error;
|
|
44
|
+
if (!err || !isNetworkError(err) || attempt >= delays.length) {
|
|
45
|
+
if (thrown)
|
|
46
|
+
throw thrown;
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
const base = delays[attempt];
|
|
50
|
+
await sleep(base + Math.round(Math.random() * base * 0.25));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pickUiText.d.ts","sourceRoot":"","sources":["../../src/lib/pickUiText.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pickUiText.d.ts","sourceRoot":"","sources":["../../src/lib/pickUiText.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AA4DD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAExD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,GACX;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAsC7D"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// Bewust los van pickI18n: die dictionaries zijn volledig per taal gevuld,
|
|
3
|
-
// hier volstaat Nederlands met Engels als terugval.
|
|
1
|
+
import { isNetworkError } from "./pickRetry";
|
|
4
2
|
const nl = {
|
|
5
3
|
onlyPending: "Alleen nog printen",
|
|
6
4
|
onlyUrgent: "Alleen spoed",
|
|
@@ -65,6 +63,10 @@ export function friendlyPickError(error, lang) {
|
|
|
65
63
|
const texts = getPickUiTexts(lang);
|
|
66
64
|
const raw = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
67
65
|
const low = raw.toLowerCase();
|
|
66
|
+
// Netwerkhapering die na alle herhaalpogingen blijft: nooit rauw tonen.
|
|
67
|
+
if (isNetworkError(error) || isNetworkError(raw)) {
|
|
68
|
+
return { message: texts.connectionLost, detail: raw || undefined, expiredClaim: false };
|
|
69
|
+
}
|
|
68
70
|
// Een botsing op de idempotentiesleutel van de printdienst is géén race:
|
|
69
71
|
// er is dan geen ander scherm bezig met dit document.
|
|
70
72
|
if (low.includes("idempotentie_sleutel") || low.includes("idempotentiesleutel")) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PickQueueItem } from "./pickTypes";
|
|
2
|
+
export interface VerifyMemo {
|
|
3
|
+
fingerprint: string;
|
|
4
|
+
ready: boolean;
|
|
5
|
+
checkedAt: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const VERIFY_MAX_AGE_MS = 60000;
|
|
8
|
+
/** Alles wat aangeeft dat een regel in de wachtrij veranderd is. */
|
|
9
|
+
export declare function rowFingerprint(item: PickQueueItem): string;
|
|
10
|
+
/**
|
|
11
|
+
* Kiest welke regels deze ronde opnieuw bij de bron gecontroleerd moeten worden:
|
|
12
|
+
* gewijzigd, nog niet printklaar, of langer dan maxAge niet gecontroleerd.
|
|
13
|
+
*/
|
|
14
|
+
export declare function rowsToVerify(items: PickQueueItem[], memo: Map<string, VerifyMemo>, now: number, maxAge?: number): PickQueueItem[];
|
|
15
|
+
//# sourceMappingURL=pickVerify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickVerify.d.ts","sourceRoot":"","sources":["../../src/lib/pickVerify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAgB1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,aAAa,EAAE,EACtB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC7B,GAAG,EAAE,MAAM,EACX,MAAM,SAAoB,GACzB,aAAa,EAAE,CAQjB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const VERIFY_MAX_AGE_MS = 60000;
|
|
2
|
+
/** Alles wat aangeeft dat een regel in de wachtrij veranderd is. */
|
|
3
|
+
export function rowFingerprint(item) {
|
|
4
|
+
const r = item;
|
|
5
|
+
const p = (r["payload"] && typeof r["payload"] === "object" ? r["payload"] : {});
|
|
6
|
+
return JSON.stringify([
|
|
7
|
+
r["status_id"] ?? r["status"] ?? null,
|
|
8
|
+
r["printed_at"] ?? null,
|
|
9
|
+
r["updated_at"] ?? null,
|
|
10
|
+
p["cartPlanReady"] ?? null,
|
|
11
|
+
p["cartPlanReleased"] ?? null,
|
|
12
|
+
p["cartPlanReason"] ?? null,
|
|
13
|
+
p["totalCarts"] ?? p["cartTotal"] ?? null,
|
|
14
|
+
p["cartRowFor"] ?? null,
|
|
15
|
+
]);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Kiest welke regels deze ronde opnieuw bij de bron gecontroleerd moeten worden:
|
|
19
|
+
* gewijzigd, nog niet printklaar, of langer dan maxAge niet gecontroleerd.
|
|
20
|
+
*/
|
|
21
|
+
export function rowsToVerify(items, memo, now, maxAge = VERIFY_MAX_AGE_MS) {
|
|
22
|
+
return items.filter((item) => {
|
|
23
|
+
const m = memo.get(item.id);
|
|
24
|
+
if (!m)
|
|
25
|
+
return true;
|
|
26
|
+
if (m.fingerprint !== rowFingerprint(item))
|
|
27
|
+
return true;
|
|
28
|
+
if (!m.ready)
|
|
29
|
+
return true;
|
|
30
|
+
return now - m.checkedAt >= maxAge;
|
|
31
|
+
});
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowselections/pick-schermen-kwekers",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.23",
|
|
4
4
|
"flowselections": {
|
|
5
5
|
"moduleId": "pick-schermen",
|
|
6
6
|
"pages": [
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@cloudflare/vite-plugin": "^1.25.5",
|
|
66
66
|
"@eslint/js": "^9.32.0",
|
|
67
|
-
"@flowselections/core": "1.0.
|
|
68
|
-
"@lovable.dev/vite-tanstack-config": "2.
|
|
67
|
+
"@flowselections/core": "1.0.28",
|
|
68
|
+
"@lovable.dev/vite-tanstack-config": "2.23.1",
|
|
69
69
|
"@rsbuild/core": "^1.0.0",
|
|
70
70
|
"@tailwindcss/vite": "^4.2.1",
|
|
71
71
|
"@tanstack/react-query": "^5.83.0",
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"typescript": "^5.8.3",
|
|
92
92
|
"typescript-eslint": "^8.56.1",
|
|
93
93
|
"vite": "^7.3.1",
|
|
94
|
-
"vite-tsconfig-paths": "^6.0.2"
|
|
94
|
+
"vite-tsconfig-paths": "^6.0.2",
|
|
95
|
+
"vitest": "5.0.3"
|
|
95
96
|
}
|
|
96
97
|
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type LayoutLogoRow, type LayoutRef, type ResolvedLayout } from "./layoutTypes";
|
|
2
|
-
/** Vraagt de actieve layout voor een documentsoort op bij de Logistiek Engine. */
|
|
3
|
-
export declare function fetchLayoutRef(documentType: string): Promise<LayoutRef | null>;
|
|
4
|
-
/** Haalt de layoutrij plus elementen, variabelen en logo's op. */
|
|
5
|
-
export declare function fetchLayout(layoutId: string, documentType: string): Promise<ResolvedLayout>;
|
|
6
|
-
/**
|
|
7
|
-
* Bepaalt en laadt de layout voor een documentsoort. Gebruikt bij voorkeur de
|
|
8
|
-
* layoutId die de Engine in de wachtrijregel heeft meegegeven.
|
|
9
|
-
*/
|
|
10
|
-
export declare function resolveLayout(args: {
|
|
11
|
-
documentType: string;
|
|
12
|
-
layoutId?: string | null;
|
|
13
|
-
}): Promise<ResolvedLayout>;
|
|
14
|
-
/**
|
|
15
|
-
* Zet de logo-records uit de layout om in de vorm die de layout-module
|
|
16
|
-
* verwacht: een publiek bereikbare `viewUrl` per logo.
|
|
17
|
-
*/
|
|
18
|
-
export declare function logosMetViewUrl(logos: Record<string, LayoutLogoRow>): Promise<{
|
|
19
|
-
id: string;
|
|
20
|
-
naam: string;
|
|
21
|
-
viewUrl: string | null;
|
|
22
|
-
}[]>;
|
|
23
|
-
//# sourceMappingURL=layoutApi.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"layoutApi.d.ts","sourceRoot":"","sources":["../../src/lib/layoutApi.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB,kFAAkF;AAClF,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAOpF;AAED,kEAAkE;AAClE,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAmBjG;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,cAAc,CAAC,CAS1B;AAID;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,CAAC,CAgCjE"}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
// Leest documentlayouts uit de gedeelde database. De module bepaalt zelf nooit
|
|
2
|
-
// welke layout bij een documentsoort hoort: dat doet logistics_document_layout.
|
|
3
|
-
import { pickDb } from "./pickApi";
|
|
4
|
-
import { safeArray } from "./pickTypes";
|
|
5
|
-
import { MissingLayoutError, } from "./layoutTypes";
|
|
6
|
-
/** Vraagt de actieve layout voor een documentsoort op bij de Logistiek Engine. */
|
|
7
|
-
export async function fetchLayoutRef(documentType) {
|
|
8
|
-
const { data, error } = await pickDb.rpc("logistics_document_layout", {
|
|
9
|
-
_document_code: documentType,
|
|
10
|
-
});
|
|
11
|
-
if (error)
|
|
12
|
-
throw new Error(error.message);
|
|
13
|
-
const ref = data;
|
|
14
|
-
return ref && ref.layoutId ? ref : null;
|
|
15
|
-
}
|
|
16
|
-
/** Haalt de layoutrij plus elementen, variabelen en logo's op. */
|
|
17
|
-
export async function fetchLayout(layoutId, documentType) {
|
|
18
|
-
// Het pickscherm is openbaar. Lees daarom via de beperkte SECURITY DEFINER
|
|
19
|
-
// functie in plaats van rechtstreeks door de RLS van de Layout maker heen.
|
|
20
|
-
const { data, error } = await pickDb.rpc("pick_document_layout_data", {
|
|
21
|
-
_layout_id: layoutId,
|
|
22
|
-
});
|
|
23
|
-
if (error)
|
|
24
|
-
throw new Error(error.message);
|
|
25
|
-
const bundle = data && typeof data === "object" && !Array.isArray(data)
|
|
26
|
-
? data
|
|
27
|
-
: {};
|
|
28
|
-
const layout = bundle["layout"];
|
|
29
|
-
if (!layout || layout.actief === false)
|
|
30
|
-
throw new MissingLayoutError(documentType);
|
|
31
|
-
const elements = safeArray(bundle["elements"]);
|
|
32
|
-
const variables = safeArray(bundle["variables"]);
|
|
33
|
-
const logos = {};
|
|
34
|
-
for (const logo of safeArray(bundle["logos"]))
|
|
35
|
-
logos[logo.id] = logo;
|
|
36
|
-
return { layout, elements, variables, logos };
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Bepaalt en laadt de layout voor een documentsoort. Gebruikt bij voorkeur de
|
|
40
|
-
* layoutId die de Engine in de wachtrijregel heeft meegegeven.
|
|
41
|
-
*/
|
|
42
|
-
export async function resolveLayout(args) {
|
|
43
|
-
const documentType = args.documentType || "pakbon";
|
|
44
|
-
let layoutId = args.layoutId ?? null;
|
|
45
|
-
if (!layoutId) {
|
|
46
|
-
const ref = await fetchLayoutRef(documentType);
|
|
47
|
-
if (!ref)
|
|
48
|
-
throw new MissingLayoutError(documentType);
|
|
49
|
-
layoutId = ref.layoutId;
|
|
50
|
-
}
|
|
51
|
-
return fetchLayout(layoutId, documentType);
|
|
52
|
-
}
|
|
53
|
-
const LOGO_BUCKET = "layout-logos";
|
|
54
|
-
/**
|
|
55
|
-
* Zet de logo-records uit de layout om in de vorm die de layout-module
|
|
56
|
-
* verwacht: een publiek bereikbare `viewUrl` per logo.
|
|
57
|
-
*/
|
|
58
|
-
export async function logosMetViewUrl(logos) {
|
|
59
|
-
const rijen = Object.values(logos ?? {});
|
|
60
|
-
if (!rijen.length)
|
|
61
|
-
return [];
|
|
62
|
-
const storage = pickDb.storage;
|
|
63
|
-
const paden = rijen.map((l) => l.bestandspad ?? l.bestand_url).filter(Boolean);
|
|
64
|
-
const map = new Map();
|
|
65
|
-
if (storage && paden.length) {
|
|
66
|
-
try {
|
|
67
|
-
const { data } = await storage.from(LOGO_BUCKET).createSignedUrls(paden, 60 * 60);
|
|
68
|
-
for (const r of safeArray(data)) {
|
|
69
|
-
if (r.path && r.signedUrl)
|
|
70
|
-
map.set(r.path, r.signedUrl);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
// geen leesrechten op ondertekende URL's: hieronder valt de publieke URL in
|
|
75
|
-
}
|
|
76
|
-
for (const pad of paden) {
|
|
77
|
-
if (map.has(pad))
|
|
78
|
-
continue;
|
|
79
|
-
try {
|
|
80
|
-
const { data } = storage.from(LOGO_BUCKET).getPublicUrl(pad);
|
|
81
|
-
if (data?.publicUrl)
|
|
82
|
-
map.set(pad, data.publicUrl);
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
// logo blijft leeg
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return rijen.map((l) => {
|
|
90
|
-
const pad = l.bestandspad ?? l.bestand_url ?? "";
|
|
91
|
-
const url = map.get(pad) ?? (/^https?:\/\//.test(pad) ? pad : null);
|
|
92
|
-
return { id: l.id, naam: l.naam, viewUrl: url };
|
|
93
|
-
});
|
|
94
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { PapierFormaatDef } from "./documentTypes";
|
|
2
|
-
export type InstellingType = "schakelaar" | "keuze" | "meerkeuze" | "tekst" | "getal" | "kleur";
|
|
3
|
-
export interface InstellingDef {
|
|
4
|
-
key: string;
|
|
5
|
-
label: string;
|
|
6
|
-
type: InstellingType;
|
|
7
|
-
hint?: string;
|
|
8
|
-
/** opties voor keuze / meerkeuze */
|
|
9
|
-
opties?: {
|
|
10
|
-
value: string;
|
|
11
|
-
label: string;
|
|
12
|
-
}[];
|
|
13
|
-
standaard?: unknown;
|
|
14
|
-
}
|
|
15
|
-
export interface InstellingGroep {
|
|
16
|
-
key: string;
|
|
17
|
-
label: string;
|
|
18
|
-
omschrijving?: string;
|
|
19
|
-
instellingen: InstellingDef[];
|
|
20
|
-
}
|
|
21
|
-
export interface DocumentProfiel {
|
|
22
|
-
/** komt overeen met document_layouts.documenttype */
|
|
23
|
-
id: string;
|
|
24
|
-
label: string;
|
|
25
|
-
omschrijving: string;
|
|
26
|
-
/** getoond in stap 1 van de wizard */
|
|
27
|
-
primair?: boolean;
|
|
28
|
-
/** formaten die bij dit documenttype horen */
|
|
29
|
-
formaten: PapierFormaatDef[];
|
|
30
|
-
standaardFormaat: string;
|
|
31
|
-
standaardOrientatie: "portrait" | "landscape";
|
|
32
|
-
/** entiteiten uit het veldregister die relevant zijn */
|
|
33
|
-
entiteiten: string[];
|
|
34
|
-
/** extra aanwijzing voor de AI-layoutimport */
|
|
35
|
-
aiHint: string;
|
|
36
|
-
/** kan per formaat een standaardprinter krijgen */
|
|
37
|
-
printerPerFormaat?: boolean;
|
|
38
|
-
groepen: InstellingGroep[];
|
|
39
|
-
}
|
|
40
|
-
export declare const STICKER_FORMATEN: PapierFormaatDef[];
|
|
41
|
-
export declare const VERZENDLABEL_FORMATEN: PapierFormaatDef[];
|
|
42
|
-
export declare const DOCUMENT_PROFIELEN: DocumentProfiel[];
|
|
43
|
-
export declare function documentProfiel(id: string): DocumentProfiel;
|
|
44
|
-
export declare function primaireProfielen(): DocumentProfiel[];
|
|
45
|
-
export type DocumentConfig = Record<string, Record<string, unknown>>;
|
|
46
|
-
/** Standaardwaarden van een profiel als opslagbaar configuratieobject. */
|
|
47
|
-
export declare function standaardConfig(profiel: DocumentProfiel): DocumentConfig;
|
|
48
|
-
/** Waarde uit de opgeslagen config, met terugval op de profielstandaard. */
|
|
49
|
-
export declare function configWaarde(config: DocumentConfig | null | undefined, groep: InstellingGroep, inst: InstellingDef): unknown;
|
|
50
|
-
//# sourceMappingURL=documentProfiles.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentProfiles.d.ts","sourceRoot":"","sources":["../../../src/lib/layoutMaker/documentProfiles.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,aAAa,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,UAAU,GAAG,WAAW,CAAC;IAC9C,wDAAwD;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAyBD,eAAO,MAAM,gBAAgB,EAAE,gBAAgB,EAO9C,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,EAOnD,CAAC;AA4YF,eAAO,MAAM,kBAAkB,EAAE,eAAe,EAe/C,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,CAK3D;AAED,wBAAgB,iBAAiB,IAAI,eAAe,EAAE,CAErD;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAErE,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAUxE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACzC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,aAAa,GAClB,OAAO,CAIT"}
|