@nocobase/app-plugin-office-flows-example 0.0.0-stage → 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/README.md +55 -2
- package/dist/client/components/flow-ui.d.ts +111 -0
- package/dist/client/components/flow-ui.d.ts.map +1 -0
- package/dist/client/components/flow-ui.js +175 -0
- package/dist/client/components/flow-ui.js.map +1 -0
- package/dist/client/components/page-container.d.ts +4 -0
- package/dist/client/components/page-container.d.ts.map +1 -0
- package/dist/client/components/page-container.js +6 -0
- package/dist/client/components/page-container.js.map +1 -0
- package/dist/client/components/page-header.d.ts +8 -0
- package/dist/client/components/page-header.d.ts.map +1 -0
- package/dist/client/components/page-header.js +5 -0
- package/dist/client/components/page-header.js.map +1 -0
- package/dist/client/components/ui/badge.d.ts +7 -0
- package/dist/client/components/ui/badge.d.ts.map +1 -0
- package/dist/client/components/ui/badge.js +19 -0
- package/dist/client/components/ui/badge.js.map +1 -0
- package/dist/client/components/ui/button.d.ts +8 -0
- package/dist/client/components/ui/button.d.ts.map +1 -0
- package/dist/client/components/ui/button.js +25 -0
- package/dist/client/components/ui/button.js.map +1 -0
- package/dist/client/components/ui/card.d.ts +11 -0
- package/dist/client/components/ui/card.d.ts.map +1 -0
- package/dist/client/components/ui/card.js +19 -0
- package/dist/client/components/ui/card.js.map +1 -0
- package/dist/client/components/ui/input.d.ts +4 -0
- package/dist/client/components/ui/input.d.ts.map +1 -0
- package/dist/client/components/ui/input.js +8 -0
- package/dist/client/components/ui/input.js.map +1 -0
- package/dist/client/components/ui/select.d.ts +16 -0
- package/dist/client/components/ui/select.d.ts.map +1 -0
- package/dist/client/components/ui/select.js +36 -0
- package/dist/client/components/ui/select.js.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/lib/api.d.ts +93 -0
- package/dist/client/lib/api.d.ts.map +1 -0
- package/dist/client/lib/api.js +67 -0
- package/dist/client/lib/api.js.map +1 -0
- package/dist/client/lib/format.d.ts +4 -0
- package/dist/client/lib/format.d.ts.map +1 -0
- package/dist/client/lib/format.js +8 -0
- package/dist/client/lib/format.js.map +1 -0
- package/dist/client/lib/labels.d.ts +5 -0
- package/dist/client/lib/labels.d.ts.map +1 -0
- package/dist/client/lib/labels.js +38 -0
- package/dist/client/lib/labels.js.map +1 -0
- package/dist/client/lib/use-loader.d.ts +10 -0
- package/dist/client/lib/use-loader.d.ts.map +1 -0
- package/dist/client/lib/use-loader.js +43 -0
- package/dist/client/lib/use-loader.js.map +1 -0
- package/dist/client/lib/utils.d.ts +2 -0
- package/dist/client/lib/utils.d.ts.map +1 -0
- package/dist/client/lib/utils.js +2 -0
- package/dist/client/lib/utils.js.map +1 -0
- package/dist/client/locales/en-US.d.ts +99 -0
- package/dist/client/locales/en-US.d.ts.map +1 -0
- package/dist/client/locales/en-US.js +92 -0
- package/dist/client/locales/en-US.js.map +1 -0
- package/dist/client/locales/index.d.ts +4 -0
- package/dist/client/locales/index.d.ts.map +1 -0
- package/dist/client/locales/index.js +7 -0
- package/dist/client/locales/index.js.map +1 -0
- package/dist/client/locales/zh-CN.d.ts +4 -0
- package/dist/client/locales/zh-CN.d.ts.map +1 -0
- package/dist/client/locales/zh-CN.js +92 -0
- package/dist/client/locales/zh-CN.js.map +1 -0
- package/dist/client/pages/configuration.d.ts +4 -0
- package/dist/client/pages/configuration.d.ts.map +1 -0
- package/dist/client/pages/configuration.js +34 -0
- package/dist/client/pages/configuration.js.map +1 -0
- package/dist/client/pages/data-requests.d.ts +3 -0
- package/dist/client/pages/data-requests.d.ts.map +1 -0
- package/dist/client/pages/data-requests.js +216 -0
- package/dist/client/pages/data-requests.js.map +1 -0
- package/dist/client/pages/incoming.d.ts +3 -0
- package/dist/client/pages/incoming.d.ts.map +1 -0
- package/dist/client/pages/incoming.js +128 -0
- package/dist/client/pages/incoming.js.map +1 -0
- package/dist/client/pages/tasks.d.ts +3 -0
- package/dist/client/pages/tasks.d.ts.map +1 -0
- package/dist/client/pages/tasks.js +116 -0
- package/dist/client/pages/tasks.js.map +1 -0
- package/dist/client/plugin.d.ts +4 -0
- package/dist/client/plugin.d.ts.map +1 -0
- package/dist/client/plugin.js +10 -0
- package/dist/client/plugin.js.map +1 -0
- package/dist/client/routes.d.ts +4 -0
- package/dist/client/routes.d.ts.map +1 -0
- package/dist/client/routes.js +51 -0
- package/dist/client/routes.js.map +1 -0
- package/dist/database/migrations/.manifest.json +9 -0
- package/dist/database/migrations/202610010001_office_flows_example_create_collections.d.ts +4 -0
- package/dist/database/migrations/202610010001_office_flows_example_create_collections.d.ts.map +1 -0
- package/dist/database/migrations/202610010001_office_flows_example_create_collections.js +280 -0
- package/dist/database/migrations/202610010001_office_flows_example_create_collections.js.map +1 -0
- package/dist/database/seeds/.manifest.json +9 -0
- package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.d.ts +10 -0
- package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.d.ts.map +1 -0
- package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.js +104 -0
- package/dist/database/seeds/202610010002_office_flows_example_seed_configuration.js.map +1 -0
- package/dist/server/calendar.d.ts +35 -0
- package/dist/server/calendar.d.ts.map +1 -0
- package/dist/server/calendar.js +103 -0
- package/dist/server/calendar.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/lifecycles/data-request.d.ts +36 -0
- package/dist/server/lifecycles/data-request.d.ts.map +1 -0
- package/dist/server/lifecycles/data-request.js +182 -0
- package/dist/server/lifecycles/data-request.js.map +1 -0
- package/dist/server/lifecycles/extraction.d.ts +21 -0
- package/dist/server/lifecycles/extraction.d.ts.map +1 -0
- package/dist/server/lifecycles/extraction.js +60 -0
- package/dist/server/lifecycles/extraction.js.map +1 -0
- package/dist/server/lifecycles/incoming.d.ts +27 -0
- package/dist/server/lifecycles/incoming.d.ts.map +1 -0
- package/dist/server/lifecycles/incoming.js +177 -0
- package/dist/server/lifecycles/incoming.js.map +1 -0
- package/dist/server/lifecycles/index.d.ts +8 -0
- package/dist/server/lifecycles/index.d.ts.map +1 -0
- package/dist/server/lifecycles/index.js +20 -0
- package/dist/server/lifecycles/index.js.map +1 -0
- package/dist/server/lifecycles/tasks.d.ts +63 -0
- package/dist/server/lifecycles/tasks.d.ts.map +1 -0
- package/dist/server/lifecycles/tasks.js +259 -0
- package/dist/server/lifecycles/tasks.js.map +1 -0
- package/dist/server/plugin.d.ts +4 -0
- package/dist/server/plugin.d.ts.map +1 -0
- package/dist/server/plugin.js +16 -0
- package/dist/server/plugin.js.map +1 -0
- package/dist/server/providers/index.d.ts +4 -0
- package/dist/server/providers/index.d.ts.map +1 -0
- package/dist/server/providers/index.js +6 -0
- package/dist/server/providers/index.js.map +1 -0
- package/dist/server/providers/office-flows.d.ts +23 -0
- package/dist/server/providers/office-flows.d.ts.map +1 -0
- package/dist/server/providers/office-flows.js +90 -0
- package/dist/server/providers/office-flows.js.map +1 -0
- package/dist/server/routes/index.d.ts +8 -0
- package/dist/server/routes/index.d.ts.map +1 -0
- package/dist/server/routes/index.js +553 -0
- package/dist/server/routes/index.js.map +1 -0
- package/dist/server/routes/schemas.d.ts +157 -0
- package/dist/server/routes/schemas.d.ts.map +1 -0
- package/dist/server/routes/schemas.js +188 -0
- package/dist/server/routes/schemas.js.map +1 -0
- package/dist/server/scope.d.ts +23 -0
- package/dist/server/scope.d.ts.map +1 -0
- package/dist/server/scope.js +23 -0
- package/dist/server/scope.js.map +1 -0
- package/dist/server/services/office-flows.d.ts +151 -0
- package/dist/server/services/office-flows.d.ts.map +1 -0
- package/dist/server/services/office-flows.js +603 -0
- package/dist/server/services/office-flows.js.map +1 -0
- package/dist/server/services/store.d.ts +119 -0
- package/dist/server/services/store.d.ts.map +1 -0
- package/dist/server/services/store.js +389 -0
- package/dist/server/services/store.js.map +1 -0
- package/dist/server/tokens.d.ts +4 -0
- package/dist/server/tokens.d.ts.map +1 -0
- package/dist/server/tokens.js +3 -0
- package/dist/server/tokens.js.map +1 -0
- package/dist/shared/data-request.d.ts +73 -0
- package/dist/shared/data-request.d.ts.map +1 -0
- package/dist/shared/data-request.js +182 -0
- package/dist/shared/data-request.js.map +1 -0
- package/dist/shared/fields.d.ts +12 -0
- package/dist/shared/fields.d.ts.map +1 -0
- package/dist/shared/fields.js +48 -0
- package/dist/shared/fields.js.map +1 -0
- package/dist/shared/people.d.ts +29 -0
- package/dist/shared/people.d.ts.map +1 -0
- package/dist/shared/people.js +54 -0
- package/dist/shared/people.js.map +1 -0
- package/dist/shared/routes.d.ts +7 -0
- package/dist/shared/routes.d.ts.map +1 -0
- package/dist/shared/routes.js +7 -0
- package/dist/shared/routes.js.map +1 -0
- package/dist/shared/text.d.ts +3 -0
- package/dist/shared/text.d.ts.map +1 -0
- package/dist/shared/text.js +9 -0
- package/dist/shared/text.js.map +1 -0
- package/package.json +72 -3
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { DatabaseConnection, DatabaseManager, Repository, Row } from '@nocobase/db';
|
|
2
|
+
import { type WorkCalendar } from '../calendar.js';
|
|
3
|
+
export type TaskKind = 'clerk' | 'team' | 'executor';
|
|
4
|
+
/** The level a distribution row sends to, and what it creates there. */
|
|
5
|
+
export declare const LEVELS: Readonly<Record<1 | 2 | 3, {
|
|
6
|
+
readonly kind: TaskKind;
|
|
7
|
+
readonly collection: string;
|
|
8
|
+
readonly prefix: string;
|
|
9
|
+
readonly initial: string;
|
|
10
|
+
}>>;
|
|
11
|
+
export declare const TASK_COLLECTIONS: Readonly<Record<TaskKind, string>>;
|
|
12
|
+
export type Plain = Record<string, unknown>;
|
|
13
|
+
/** A bigInt filter takes a number; ids travel as strings. */
|
|
14
|
+
export declare function idOf(value: unknown): number;
|
|
15
|
+
export declare function plain(row: Row | undefined): Plain | undefined;
|
|
16
|
+
export declare function people(value: unknown): string[];
|
|
17
|
+
export interface NoticeInput {
|
|
18
|
+
readonly rootKind: 'incoming' | 'dataRequest';
|
|
19
|
+
readonly rootId: number;
|
|
20
|
+
/** Each recipient is reminded once per root and level. */
|
|
21
|
+
readonly level: string;
|
|
22
|
+
readonly recipients: readonly string[];
|
|
23
|
+
readonly message: string;
|
|
24
|
+
readonly sourceKind: string;
|
|
25
|
+
readonly sourceId: number;
|
|
26
|
+
}
|
|
27
|
+
export interface DispatchResult {
|
|
28
|
+
readonly created: readonly {
|
|
29
|
+
readonly kind: TaskKind;
|
|
30
|
+
readonly id: number;
|
|
31
|
+
readonly number: string;
|
|
32
|
+
readonly departmentName: string;
|
|
33
|
+
}[];
|
|
34
|
+
readonly notified: readonly string[];
|
|
35
|
+
readonly skipped: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Database operations the lifecycles' guards and effects share. Each one is
|
|
39
|
+
* safe to repeat: an effect may run more than once, so creating a task
|
|
40
|
+
* claims its distribution row first and reminders go through a ledger with
|
|
41
|
+
* a unique key.
|
|
42
|
+
*/
|
|
43
|
+
export declare class OfficeStore {
|
|
44
|
+
private readonly database;
|
|
45
|
+
private readonly clock;
|
|
46
|
+
private readonly connection;
|
|
47
|
+
constructor(database: DatabaseManager, clock?: () => Date, connection?: DatabaseConnection | undefined);
|
|
48
|
+
/**
|
|
49
|
+
* The same operations on one transaction's connection. Guards run inside
|
|
50
|
+
* the transition's transaction and must read through it: SQLite has one
|
|
51
|
+
* connection, and a read elsewhere would wait for it.
|
|
52
|
+
*/
|
|
53
|
+
bound(handle: unknown): OfficeStore;
|
|
54
|
+
repository(collection: string): Repository;
|
|
55
|
+
private transaction;
|
|
56
|
+
now(): string;
|
|
57
|
+
find(collection: string, id: unknown): Promise<Plain | undefined>;
|
|
58
|
+
list(collection: string, filter: Record<string, string | number | boolean | null>): Promise<Plain[]>;
|
|
59
|
+
/** `PREFIX-YYYYMM-0001`, numbered per prefix and month. */
|
|
60
|
+
nextNumber(prefix: string): Promise<string>;
|
|
61
|
+
calendar(): Promise<WorkCalendar>;
|
|
62
|
+
/** Extraction tasks of a request, by status. Voided tasks never count. */
|
|
63
|
+
countExtractions(requestId: unknown, statuses: readonly string[]): Promise<number>;
|
|
64
|
+
/**
|
|
65
|
+
* Creates an extraction task for a request in acceptance, unless the
|
|
66
|
+
* period already has one: the (request, period) key is unique, so a
|
|
67
|
+
* repeated sweep or a retried effect creates nothing twice. A manual task
|
|
68
|
+
* has no period and takes its number as its key. Returns nothing when the
|
|
69
|
+
* task exists or the request has left acceptance.
|
|
70
|
+
*
|
|
71
|
+
* The insert and the request's acceptance are decided together: the task's
|
|
72
|
+
* transaction first bumps the request's `lifecycleVersion` while it is
|
|
73
|
+
* still `accepting`, which locks the row against a `complete` deciding at
|
|
74
|
+
* the same time and makes the one that commits second meet a conflict.
|
|
75
|
+
* The version belongs to the lifecycle, and this is why it is touched from
|
|
76
|
+
* outside it: a transition that counted the request's tasks must not
|
|
77
|
+
* commit over a task it did not see.
|
|
78
|
+
*/
|
|
79
|
+
createExtraction(values: {
|
|
80
|
+
readonly requestId: number;
|
|
81
|
+
readonly periodKey?: string;
|
|
82
|
+
readonly origin: 'scheduled' | 'once' | 'manual';
|
|
83
|
+
readonly scheduledDate: string;
|
|
84
|
+
readonly topic: string;
|
|
85
|
+
readonly requirement: string;
|
|
86
|
+
readonly executorIds: readonly string[];
|
|
87
|
+
}): Promise<Plain | undefined>;
|
|
88
|
+
/**
|
|
89
|
+
* Reminds each recipient once per root document and level; returns who
|
|
90
|
+
* was reminded now. Someone already reminded at this level is skipped,
|
|
91
|
+
* however many rows or rounds name them again.
|
|
92
|
+
*/
|
|
93
|
+
notify(input: NoticeInput): Promise<string[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Adds a line to a document's distribution record. An effect passes its
|
|
96
|
+
* run's idempotency key, so a retry after a partial attempt writes the
|
|
97
|
+
* line once; without a key every call writes one.
|
|
98
|
+
*/
|
|
99
|
+
trace(values: {
|
|
100
|
+
readonly docKind: string;
|
|
101
|
+
readonly docId: number;
|
|
102
|
+
readonly actorId: string;
|
|
103
|
+
readonly action: string;
|
|
104
|
+
readonly detail: Plain;
|
|
105
|
+
readonly key?: string;
|
|
106
|
+
}): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Sends distribution rows down one level: each row not yet dispatched
|
|
109
|
+
* becomes a task for its department, and everyone the row names is
|
|
110
|
+
* reminded. Claiming the row and creating its task are one transaction.
|
|
111
|
+
* A row an earlier attempt already dispatched is reported again rather
|
|
112
|
+
* than skipped, so a retry after the reminders failed still sends them;
|
|
113
|
+
* the reminders themselves go out once per person and level.
|
|
114
|
+
*/
|
|
115
|
+
dispatch(level: 1 | 2 | 3, rowIds: readonly number[]): Promise<DispatchResult>;
|
|
116
|
+
/** Readable names, for messages and traces. */
|
|
117
|
+
names(ids: readonly string[]): string;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../server/services/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
3
|
+
import { personName } from '../../shared/people.js';
|
|
4
|
+
import { createWorkCalendar, } from '../calendar.js';
|
|
5
|
+
import { COLLECTIONS } from '../scope.js';
|
|
6
|
+
import { text } from '../../shared/text.js';
|
|
7
|
+
/** The level a distribution row sends to, and what it creates there. */
|
|
8
|
+
export const LEVELS = {
|
|
9
|
+
1: {
|
|
10
|
+
kind: 'clerk',
|
|
11
|
+
collection: COLLECTIONS.clerkTasks,
|
|
12
|
+
prefix: 'SWSQ_BSRY',
|
|
13
|
+
initial: 'signing',
|
|
14
|
+
},
|
|
15
|
+
2: {
|
|
16
|
+
kind: 'team',
|
|
17
|
+
collection: COLLECTIONS.teamTasks,
|
|
18
|
+
prefix: 'SWSQ_ZXTDCL',
|
|
19
|
+
initial: 'processing',
|
|
20
|
+
},
|
|
21
|
+
3: {
|
|
22
|
+
kind: 'executor',
|
|
23
|
+
collection: COLLECTIONS.executorTasks,
|
|
24
|
+
prefix: 'SWSQ_BSRY_ZB',
|
|
25
|
+
initial: 'processing',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export const TASK_COLLECTIONS = {
|
|
29
|
+
clerk: COLLECTIONS.clerkTasks,
|
|
30
|
+
team: COLLECTIONS.teamTasks,
|
|
31
|
+
executor: COLLECTIONS.executorTasks,
|
|
32
|
+
};
|
|
33
|
+
/** A bigInt filter takes a number; ids travel as strings. */
|
|
34
|
+
export function idOf(value) {
|
|
35
|
+
const id = Number(value);
|
|
36
|
+
if (!Number.isSafeInteger(id))
|
|
37
|
+
throw new Error(`"${text(value)}" is not an id.`);
|
|
38
|
+
return id;
|
|
39
|
+
}
|
|
40
|
+
export function plain(row) {
|
|
41
|
+
if (!row)
|
|
42
|
+
return undefined;
|
|
43
|
+
const values = {};
|
|
44
|
+
for (const [field, value] of Object.entries(row))
|
|
45
|
+
values[field] = value instanceof Date ? value.toISOString() : value;
|
|
46
|
+
return values;
|
|
47
|
+
}
|
|
48
|
+
export function people(value) {
|
|
49
|
+
if (Array.isArray(value))
|
|
50
|
+
return value.map(String);
|
|
51
|
+
if (typeof value === 'string' && value.startsWith('['))
|
|
52
|
+
return JSON.parse(value).map(String);
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
/** These errors confirm a deadlock victim's transaction was aborted. */
|
|
56
|
+
function isDeadlock(error) {
|
|
57
|
+
const visited = new Set();
|
|
58
|
+
let current = error;
|
|
59
|
+
while (current && typeof current === 'object' && !visited.has(current)) {
|
|
60
|
+
visited.add(current);
|
|
61
|
+
const record = current;
|
|
62
|
+
if (record.code === 'ER_LOCK_DEADLOCK' ||
|
|
63
|
+
record.code === '40P01' ||
|
|
64
|
+
record.number === 1205)
|
|
65
|
+
return true;
|
|
66
|
+
current = record.cause ?? record.originalError;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
function unique(values) {
|
|
71
|
+
return [...new Set(values)];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Database operations the lifecycles' guards and effects share. Each one is
|
|
75
|
+
* safe to repeat: an effect may run more than once, so creating a task
|
|
76
|
+
* claims its distribution row first and reminders go through a ledger with
|
|
77
|
+
* a unique key.
|
|
78
|
+
*/
|
|
79
|
+
export class OfficeStore {
|
|
80
|
+
database;
|
|
81
|
+
clock;
|
|
82
|
+
connection;
|
|
83
|
+
constructor(database, clock = () => new Date(), connection = undefined) {
|
|
84
|
+
this.database = database;
|
|
85
|
+
this.clock = clock;
|
|
86
|
+
this.connection = connection;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The same operations on one transaction's connection. Guards run inside
|
|
90
|
+
* the transition's transaction and must read through it: SQLite has one
|
|
91
|
+
* connection, and a read elsewhere would wait for it.
|
|
92
|
+
*/
|
|
93
|
+
bound(handle) {
|
|
94
|
+
return handle === undefined
|
|
95
|
+
? this
|
|
96
|
+
: new OfficeStore(this.database, this.clock, handle);
|
|
97
|
+
}
|
|
98
|
+
repository(collection) {
|
|
99
|
+
return this.connection
|
|
100
|
+
? this.connection.repository(collection)
|
|
101
|
+
: this.database.repository(collection);
|
|
102
|
+
}
|
|
103
|
+
transaction(work) {
|
|
104
|
+
return this.connection
|
|
105
|
+
? work(this.connection)
|
|
106
|
+
: this.database.transaction(work);
|
|
107
|
+
}
|
|
108
|
+
now() {
|
|
109
|
+
return this.clock().toISOString();
|
|
110
|
+
}
|
|
111
|
+
async find(collection, id) {
|
|
112
|
+
return plain(await this.repository(collection).findOne({ filter: { id: idOf(id) } }));
|
|
113
|
+
}
|
|
114
|
+
async list(collection, filter) {
|
|
115
|
+
const rows = await this.repository(collection).findMany({
|
|
116
|
+
filter,
|
|
117
|
+
sort: (sort) => sort.field('id').asc(),
|
|
118
|
+
});
|
|
119
|
+
return rows.map((row) => plain(row));
|
|
120
|
+
}
|
|
121
|
+
/** `PREFIX-YYYYMM-0001`, numbered per prefix and month. */
|
|
122
|
+
async nextNumber(prefix) {
|
|
123
|
+
const period = this.now().slice(0, 7).replace('-', '');
|
|
124
|
+
const key = `${prefix}-${period}`;
|
|
125
|
+
// The value the upsert itself wrote: a separate read could see another
|
|
126
|
+
// caller's increment and hand out the same number twice.
|
|
127
|
+
for (let attempt = 0;; attempt++) {
|
|
128
|
+
try {
|
|
129
|
+
const { record } = await this.repository(COLLECTIONS.serials).upsertOne({
|
|
130
|
+
filter: { key },
|
|
131
|
+
create: { key, value: 1 },
|
|
132
|
+
update: { value: (value) => value.increment(1) },
|
|
133
|
+
});
|
|
134
|
+
return `${key}-${text(Number(record.value)).padStart(4, '0')}`;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
// A new counter can deadlock with another insert. Retry only the
|
|
138
|
+
// implicit transaction we own, never part of a caller's aborted
|
|
139
|
+
// transaction or an error with an unknown commit outcome.
|
|
140
|
+
if (this.connection || attempt >= 5 || !isDeadlock(error))
|
|
141
|
+
throw error;
|
|
142
|
+
await delay(5 * 2 ** attempt + Math.floor(Math.random() * 5));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async calendar() {
|
|
147
|
+
const rows = await this.repository(COLLECTIONS.holidays).findMany({});
|
|
148
|
+
return createWorkCalendar(rows.map((row) => ({
|
|
149
|
+
date: text(row.date),
|
|
150
|
+
kind: row.kind === 'workday' ? 'workday' : 'holiday',
|
|
151
|
+
})));
|
|
152
|
+
}
|
|
153
|
+
/** Extraction tasks of a request, by status. Voided tasks never count. */
|
|
154
|
+
async countExtractions(requestId, statuses) {
|
|
155
|
+
return this.repository(COLLECTIONS.extractions).count({
|
|
156
|
+
filter: (filter) => filter.and([
|
|
157
|
+
filter.number('requestId').eq(idOf(requestId)),
|
|
158
|
+
filter.or(statuses.map((status) => filter.string('status').eq(status))),
|
|
159
|
+
]),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Creates an extraction task for a request in acceptance, unless the
|
|
164
|
+
* period already has one: the (request, period) key is unique, so a
|
|
165
|
+
* repeated sweep or a retried effect creates nothing twice. A manual task
|
|
166
|
+
* has no period and takes its number as its key. Returns nothing when the
|
|
167
|
+
* task exists or the request has left acceptance.
|
|
168
|
+
*
|
|
169
|
+
* The insert and the request's acceptance are decided together: the task's
|
|
170
|
+
* transaction first bumps the request's `lifecycleVersion` while it is
|
|
171
|
+
* still `accepting`, which locks the row against a `complete` deciding at
|
|
172
|
+
* the same time and makes the one that commits second meet a conflict.
|
|
173
|
+
* The version belongs to the lifecycle, and this is why it is touched from
|
|
174
|
+
* outside it: a transition that counted the request's tasks must not
|
|
175
|
+
* commit over a task it did not see.
|
|
176
|
+
*/
|
|
177
|
+
async createExtraction(values) {
|
|
178
|
+
const { periodKey } = values;
|
|
179
|
+
const existing = async (repository) => periodKey === undefined
|
|
180
|
+
? undefined
|
|
181
|
+
: repository.findOne({
|
|
182
|
+
filter: { requestId: values.requestId, periodKey },
|
|
183
|
+
});
|
|
184
|
+
if (await existing(this.repository(COLLECTIONS.extractions)))
|
|
185
|
+
return undefined;
|
|
186
|
+
// Numbered before the transaction: SQLite has one connection, and a
|
|
187
|
+
// read outside the transaction would wait for it.
|
|
188
|
+
const number = await this.nextNumber('SJSY_CS');
|
|
189
|
+
const now = this.now();
|
|
190
|
+
return this.transaction(async (connection) => {
|
|
191
|
+
const accepting = await connection
|
|
192
|
+
.repository(COLLECTIONS.dataRequests)
|
|
193
|
+
.updateMany({
|
|
194
|
+
filter: { id: values.requestId, status: 'accepting' },
|
|
195
|
+
values: { lifecycleVersion: { increment: 1 } },
|
|
196
|
+
});
|
|
197
|
+
if (accepting.updatedCount === 0)
|
|
198
|
+
return undefined;
|
|
199
|
+
const extractions = connection.repository(COLLECTIONS.extractions);
|
|
200
|
+
if (await existing(extractions))
|
|
201
|
+
return undefined;
|
|
202
|
+
try {
|
|
203
|
+
const created = await extractions.createOne({
|
|
204
|
+
values: {
|
|
205
|
+
...values,
|
|
206
|
+
periodKey: periodKey ?? `manual:${number}`,
|
|
207
|
+
executorIds: [...values.executorIds],
|
|
208
|
+
feedbackFiles: [],
|
|
209
|
+
number,
|
|
210
|
+
status: 'pending',
|
|
211
|
+
statusChangedAt: now,
|
|
212
|
+
lifecycleVersion: 0,
|
|
213
|
+
createdAt: now,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
return plain(created.record);
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
// Another sweep created it between the read and the insert.
|
|
220
|
+
if (await existing(extractions))
|
|
221
|
+
return undefined;
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Reminds each recipient once per root document and level; returns who
|
|
228
|
+
* was reminded now. Someone already reminded at this level is skipped,
|
|
229
|
+
* however many rows or rounds name them again.
|
|
230
|
+
*/
|
|
231
|
+
async notify(input) {
|
|
232
|
+
const reached = [];
|
|
233
|
+
for (const recipient of unique(input.recipients)) {
|
|
234
|
+
const key = {
|
|
235
|
+
rootKind: input.rootKind,
|
|
236
|
+
rootId: input.rootId,
|
|
237
|
+
level: input.level,
|
|
238
|
+
recipient,
|
|
239
|
+
};
|
|
240
|
+
if (await this.repository(COLLECTIONS.notices).exists({ filter: key }))
|
|
241
|
+
continue;
|
|
242
|
+
try {
|
|
243
|
+
await this.repository(COLLECTIONS.notices).createOne({
|
|
244
|
+
values: {
|
|
245
|
+
...key,
|
|
246
|
+
message: input.message,
|
|
247
|
+
sourceKind: input.sourceKind,
|
|
248
|
+
sourceId: input.sourceId,
|
|
249
|
+
createdAt: this.now(),
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
reached.push(recipient);
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
// The unique key: a concurrent dispatch reminded them first.
|
|
256
|
+
if (!(await this.repository(COLLECTIONS.notices).exists({ filter: key })))
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return reached;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Adds a line to a document's distribution record. An effect passes its
|
|
264
|
+
* run's idempotency key, so a retry after a partial attempt writes the
|
|
265
|
+
* line once; without a key every call writes one.
|
|
266
|
+
*/
|
|
267
|
+
async trace(values) {
|
|
268
|
+
const key = values.key ?? `trace:${randomUUID()}`;
|
|
269
|
+
const traces = this.repository(COLLECTIONS.traces);
|
|
270
|
+
if (values.key && (await traces.exists({ filter: { key } })))
|
|
271
|
+
return;
|
|
272
|
+
try {
|
|
273
|
+
await traces.createOne({
|
|
274
|
+
values: { ...values, key, at: this.now() },
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
// The unique key: a concurrent attempt wrote it first.
|
|
279
|
+
if (!(await traces.exists({ filter: { key } })))
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Sends distribution rows down one level: each row not yet dispatched
|
|
285
|
+
* becomes a task for its department, and everyone the row names is
|
|
286
|
+
* reminded. Claiming the row and creating its task are one transaction.
|
|
287
|
+
* A row an earlier attempt already dispatched is reported again rather
|
|
288
|
+
* than skipped, so a retry after the reminders failed still sends them;
|
|
289
|
+
* the reminders themselves go out once per person and level.
|
|
290
|
+
*/
|
|
291
|
+
async dispatch(level, rowIds) {
|
|
292
|
+
const target = LEVELS[level];
|
|
293
|
+
const created = [];
|
|
294
|
+
const recipients = [];
|
|
295
|
+
let rootId = 0;
|
|
296
|
+
for (const rowId of rowIds) {
|
|
297
|
+
// Numbered before the transaction: SQLite has one connection, and a
|
|
298
|
+
// read outside the transaction would wait for it. A claim that loses
|
|
299
|
+
// leaves a gap in the sequence, nothing worse.
|
|
300
|
+
const number = await this.nextNumber(target.prefix);
|
|
301
|
+
const task = await this.transaction(async (connection) => {
|
|
302
|
+
const rows = connection.repository(COLLECTIONS.assignments);
|
|
303
|
+
const claimed = await rows.updateMany({
|
|
304
|
+
filter: { id: rowId, dispatched: false, level },
|
|
305
|
+
values: { dispatched: true },
|
|
306
|
+
});
|
|
307
|
+
if (claimed.updatedCount === 0) {
|
|
308
|
+
const done = plain(await rows.findOne({ filter: { id: rowId } }));
|
|
309
|
+
if (!done || done.level !== level || done.childId == null)
|
|
310
|
+
return undefined;
|
|
311
|
+
const child = plain(await connection
|
|
312
|
+
.repository(target.collection)
|
|
313
|
+
.findOne({ filter: { id: idOf(done.childId) } }));
|
|
314
|
+
return child
|
|
315
|
+
? { row: done, id: idOf(done.childId), number: text(child.number) }
|
|
316
|
+
: undefined;
|
|
317
|
+
}
|
|
318
|
+
const row = plain(await rows.findOne({ filter: { id: rowId } }));
|
|
319
|
+
const now = this.now();
|
|
320
|
+
const record = await connection
|
|
321
|
+
.repository(target.collection)
|
|
322
|
+
.createOne({
|
|
323
|
+
values: {
|
|
324
|
+
number,
|
|
325
|
+
rootId: idOf(row.rootId),
|
|
326
|
+
parentId: idOf(row.parentId),
|
|
327
|
+
assignmentId: rowId,
|
|
328
|
+
departmentName: text(row.departmentName),
|
|
329
|
+
assignees: people(row.assignees),
|
|
330
|
+
ccHeads: people(row.ccHeads),
|
|
331
|
+
ccLeaders: people(row.ccLeaders),
|
|
332
|
+
signedBy: [],
|
|
333
|
+
attachments: [],
|
|
334
|
+
status: target.initial,
|
|
335
|
+
statusChangedAt: now,
|
|
336
|
+
lifecycleVersion: 0,
|
|
337
|
+
createdAt: now,
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
const id = idOf(record.record.id);
|
|
341
|
+
// Publish ownership with the task and the dispatch claim. A retry
|
|
342
|
+
// reuses the existing task, so it cannot duplicate these memberships.
|
|
343
|
+
for (const personId of unique(people(row.assignees))) {
|
|
344
|
+
await connection.repository(COLLECTIONS.taskAssignees).createOne({
|
|
345
|
+
values: { kind: target.kind, taskId: id, personId },
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
await rows.updateMany({
|
|
349
|
+
filter: { id: rowId },
|
|
350
|
+
values: { childId: id },
|
|
351
|
+
});
|
|
352
|
+
return { row, id, number };
|
|
353
|
+
});
|
|
354
|
+
if (!task)
|
|
355
|
+
continue;
|
|
356
|
+
rootId = idOf(task.row.rootId);
|
|
357
|
+
recipients.push(...people(task.row.assignees), ...people(task.row.ccHeads), ...people(task.row.ccLeaders));
|
|
358
|
+
created.push({
|
|
359
|
+
kind: target.kind,
|
|
360
|
+
id: task.id,
|
|
361
|
+
number: task.number,
|
|
362
|
+
departmentName: text(task.row.departmentName),
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
if (!created.length)
|
|
366
|
+
return { created, notified: [], skipped: [] };
|
|
367
|
+
const root = await this.find(COLLECTIONS.incoming, rootId);
|
|
368
|
+
const title = text(root?.title);
|
|
369
|
+
const notified = await this.notify({
|
|
370
|
+
rootKind: 'incoming',
|
|
371
|
+
rootId,
|
|
372
|
+
level: text(level),
|
|
373
|
+
recipients,
|
|
374
|
+
message: `收文《${title}》已派发至${created.map((item) => item.departmentName).join('、')}`,
|
|
375
|
+
sourceKind: target.kind,
|
|
376
|
+
sourceId: created[0].id,
|
|
377
|
+
});
|
|
378
|
+
return {
|
|
379
|
+
created,
|
|
380
|
+
notified,
|
|
381
|
+
skipped: unique(recipients).filter((person) => !notified.includes(person)),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/** Readable names, for messages and traces. */
|
|
385
|
+
names(ids) {
|
|
386
|
+
return ids.map(personName).join('、');
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../server/services/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../server/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,eAAO,MAAM,uBAAuB,EAAE,YAAY,CAAC,kBAAkB,CAGlE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../server/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAEnB,MAAM,4BAA4B,CAAC;AAIpC,MAAM,CAAC,MAAM,uBAAuB,GAClC,kBAAkB,CAChB,mDAAmD,CACpD,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The data usage request form: which fields exist, which options they offer
|
|
3
|
+
* and when they appear. The page renders from these rules and the server
|
|
4
|
+
* validates with them, so the two cannot drift apart.
|
|
5
|
+
*/
|
|
6
|
+
export declare const VOLUMES: readonly string[];
|
|
7
|
+
export type Frequency = 'once' | 'quarterly' | 'monthly' | 'weekly' | 'daily' | 'other';
|
|
8
|
+
export declare const FREQUENCIES: readonly {
|
|
9
|
+
value: Frequency;
|
|
10
|
+
label: string;
|
|
11
|
+
}[];
|
|
12
|
+
export type UsageScope = 'external' | 'internal';
|
|
13
|
+
export declare const SCOPES: readonly {
|
|
14
|
+
value: UsageScope;
|
|
15
|
+
label: string;
|
|
16
|
+
}[];
|
|
17
|
+
export declare const CONSUMERS: Readonly<Record<UsageScope, readonly string[]>>;
|
|
18
|
+
export declare const WEEKDAYS: readonly string[];
|
|
19
|
+
export declare const INTERNAL_ANALYSIS = "\u5185\u90E8\u7BA1\u7406\u53CA\u5206\u6790";
|
|
20
|
+
export declare const THIRD_PARTY = "\u7B2C\u4E09\u65B9\u5408\u4F5C";
|
|
21
|
+
/** The fields an applicant fills in, as the server stores them. */
|
|
22
|
+
export interface DataRequestForm {
|
|
23
|
+
subject: string;
|
|
24
|
+
reason: string;
|
|
25
|
+
volume: string;
|
|
26
|
+
frequency: Frequency | '';
|
|
27
|
+
deliveryDate: string;
|
|
28
|
+
firstUseDate: string;
|
|
29
|
+
lastDeliveryDate: string;
|
|
30
|
+
/** 1–92: the day of the quarter, counted from its first day. */
|
|
31
|
+
quarterDay: number | null;
|
|
32
|
+
/** 1–31; a shorter month uses its last day. */
|
|
33
|
+
monthDay: number | null;
|
|
34
|
+
/** 1 (Monday) – 7 (Sunday). */
|
|
35
|
+
weekDay: number | null;
|
|
36
|
+
frequencyNote: string;
|
|
37
|
+
scope: UsageScope | '';
|
|
38
|
+
consumers: string[];
|
|
39
|
+
fileShieldAccepted: boolean | null;
|
|
40
|
+
fileShieldScope: string;
|
|
41
|
+
fileShieldCopy: boolean | null;
|
|
42
|
+
fileShieldValidUntil: string;
|
|
43
|
+
ndaFiles: string[];
|
|
44
|
+
securityFiles: string[];
|
|
45
|
+
}
|
|
46
|
+
export declare function emptyDataRequest(): DataRequestForm;
|
|
47
|
+
/** Which conditional parts of the form are showing for these values. */
|
|
48
|
+
export interface DataRequestVisibility {
|
|
49
|
+
readonly deliveryDate: boolean;
|
|
50
|
+
readonly periodDates: boolean;
|
|
51
|
+
readonly quarterDay: boolean;
|
|
52
|
+
readonly monthDay: boolean;
|
|
53
|
+
readonly weekDay: boolean;
|
|
54
|
+
readonly frequencyNote: boolean;
|
|
55
|
+
readonly fileShield: boolean;
|
|
56
|
+
readonly thirdParty: boolean;
|
|
57
|
+
}
|
|
58
|
+
export declare function visibility(form: DataRequestForm): DataRequestVisibility;
|
|
59
|
+
/** The consumer types the chosen scope offers. */
|
|
60
|
+
export declare function consumerOptions(scope: UsageScope | ''): readonly string[];
|
|
61
|
+
/** A `YYYY-MM-DD` that names a real day: `2026-02-31` is refused, not moved to March. */
|
|
62
|
+
export declare function isDate(value: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Field → message for every problem; empty when the form may be submitted.
|
|
65
|
+
* Fields that are hidden for these values are neither required nor checked.
|
|
66
|
+
*/
|
|
67
|
+
export declare function validateDataRequest(form: DataRequestForm): Record<string, string>;
|
|
68
|
+
/**
|
|
69
|
+
* Drops the values of fields the choices hide, so a stored request never
|
|
70
|
+
* carries an answer to a question it did not ask.
|
|
71
|
+
*/
|
|
72
|
+
export declare function normalizeDataRequest(form: DataRequestForm): DataRequestForm;
|
|
73
|
+
//# sourceMappingURL=data-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-request.d.ts","sourceRoot":"","sources":["../../shared/data-request.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,OAAO,EAAE,SAAS,MAAM,EAKpC,CAAC;AAEF,MAAM,MAAM,SAAS,GACnB,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAElE,eAAO,MAAM,WAAW,EAAE,SAAS;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAOrE,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AAEjD,eAAO,MAAM,MAAM,EAAE,SAAS;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAGjE,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC,CAUrE,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EAQrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,+CAAY,CAAC;AAC3C,eAAO,MAAM,WAAW,mCAAU,CAAC;AAEnC,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,gBAAgB,IAAI,eAAe,CAsBlD;AAED,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,qBAAqB,CAYvE;AAED,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,EAAE,GAAG,SAAS,MAAM,EAAE,CAEzE;AAID,yFAAyF;AACzF,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAM7C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,eAAe,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoExB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,CAqB3E"}
|