@filen/sync 0.1.1

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.
@@ -0,0 +1,46 @@
1
+ import SDK, { type FilenSDKConfig } from "@filen/sdk";
2
+ import type { SyncPair } from "../types";
3
+ import { LocalFileSystem, LocalTree } from "./filesystems/local";
4
+ import { RemoteFileSystem, RemoteTree } from "./filesystems/remote";
5
+ import Deltas from "./deltas";
6
+ import Tasks from "./tasks";
7
+ import State from "./state";
8
+ /**
9
+ * Sync
10
+ *
11
+ * @export
12
+ * @class Sync
13
+ * @typedef {Sync}
14
+ */
15
+ export declare class Sync {
16
+ readonly sdk: SDK;
17
+ readonly syncPair: SyncPair;
18
+ private isInitialized;
19
+ readonly localFileSystem: LocalFileSystem;
20
+ readonly remoteFileSystem: RemoteFileSystem;
21
+ readonly deltas: Deltas;
22
+ previousLocalTree: LocalTree;
23
+ previousRemoteTree: RemoteTree;
24
+ localFileHashes: Record<string, string>;
25
+ readonly tasks: Tasks;
26
+ readonly state: State;
27
+ readonly dbPath: string;
28
+ /**
29
+ * Creates an instance of Sync.
30
+ *
31
+ * @constructor
32
+ * @public
33
+ * @param {{ syncPair: SyncPair; dbPath: string, sdkConfig: FilenSDKConfig }} param0
34
+ * @param {SyncPair} param0.syncPair
35
+ * @param {string} param0.dbPath
36
+ * @param {FilenSDKConfig} param0.sdkConfig
37
+ */
38
+ constructor({ syncPair, dbPath, sdkConfig }: {
39
+ syncPair: SyncPair;
40
+ dbPath: string;
41
+ sdkConfig: FilenSDKConfig;
42
+ });
43
+ initialize(): Promise<void>;
44
+ private run;
45
+ }
46
+ export default Sync;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Sync = void 0;
7
+ const sdk_1 = __importDefault(require("@filen/sdk"));
8
+ const constants_1 = require("../constants");
9
+ const local_1 = require("./filesystems/local");
10
+ const remote_1 = require("./filesystems/remote");
11
+ const deltas_1 = __importDefault(require("./deltas"));
12
+ const tasks_1 = __importDefault(require("./tasks"));
13
+ const state_1 = __importDefault(require("./state"));
14
+ /**
15
+ * Sync
16
+ *
17
+ * @export
18
+ * @class Sync
19
+ * @typedef {Sync}
20
+ */
21
+ class Sync {
22
+ /**
23
+ * Creates an instance of Sync.
24
+ *
25
+ * @constructor
26
+ * @public
27
+ * @param {{ syncPair: SyncPair; dbPath: string, sdkConfig: FilenSDKConfig }} param0
28
+ * @param {SyncPair} param0.syncPair
29
+ * @param {string} param0.dbPath
30
+ * @param {FilenSDKConfig} param0.sdkConfig
31
+ */
32
+ constructor({ syncPair, dbPath, sdkConfig }) {
33
+ this.isInitialized = false;
34
+ this.previousLocalTree = { tree: {}, inodes: {} };
35
+ this.previousRemoteTree = { tree: {}, uuids: {} };
36
+ this.localFileHashes = {};
37
+ this.syncPair = syncPair;
38
+ this.dbPath = dbPath;
39
+ this.sdk = new sdk_1.default(sdkConfig);
40
+ this.localFileSystem = new local_1.LocalFileSystem({ sync: this });
41
+ this.remoteFileSystem = new remote_1.RemoteFileSystem({ sync: this });
42
+ this.deltas = new deltas_1.default({ sync: this });
43
+ this.tasks = new tasks_1.default({ sync: this });
44
+ this.state = new state_1.default({ sync: this });
45
+ }
46
+ async initialize() {
47
+ if (this.isInitialized) {
48
+ return;
49
+ }
50
+ this.isInitialized = true;
51
+ try {
52
+ //local/remote smoke test
53
+ await this.localFileSystem.startDirectoryWatcher();
54
+ await this.state.initialize();
55
+ this.run();
56
+ }
57
+ catch (e) {
58
+ this.isInitialized = false;
59
+ throw e;
60
+ }
61
+ }
62
+ async run() {
63
+ try {
64
+ await this.localFileSystem.waitForLocalDirectoryChanges();
65
+ let [currentLocalTree, currentRemoteTree] = await Promise.all([
66
+ this.localFileSystem.getDirectoryTree(),
67
+ this.remoteFileSystem.getDirectoryTree()
68
+ ]);
69
+ const deltas = await this.deltas.process({
70
+ currentLocalTree,
71
+ currentRemoteTree,
72
+ previousLocalTree: this.previousLocalTree,
73
+ previousRemoteTree: this.previousRemoteTree
74
+ });
75
+ console.log(deltas);
76
+ const doneTasks = await this.tasks.process({ deltas });
77
+ console.log(doneTasks);
78
+ if (doneTasks.length > 0) {
79
+ const applied = this.state.applyDoneTasksToState({ doneTasks, currentLocalTree, currentRemoteTree });
80
+ currentLocalTree = applied.currentLocalTree;
81
+ currentRemoteTree = applied.currentRemoteTree;
82
+ }
83
+ this.previousLocalTree = currentLocalTree;
84
+ this.previousRemoteTree = currentRemoteTree;
85
+ await this.state.save();
86
+ }
87
+ catch (e) {
88
+ console.error(e); // TODO: Proper debugger
89
+ }
90
+ finally {
91
+ setTimeout(() => {
92
+ this.run();
93
+ }, constants_1.SYNC_INTERVAL);
94
+ }
95
+ }
96
+ }
97
+ exports.Sync = Sync;
98
+ exports.default = Sync;
99
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /// <reference types="node" />
2
+ import type Sync from "./sync";
3
+ import type { Delta } from "./deltas";
4
+ import type { CloudItem } from "@filen/sdk";
5
+ import fs from "fs-extra";
6
+ export type DoneTask = {
7
+ path: string;
8
+ } & ({
9
+ type: "uploadFile";
10
+ item: CloudItem;
11
+ } | {
12
+ type: "createRemoteDirectory";
13
+ uuid: string;
14
+ } | {
15
+ type: "createLocalDirectory";
16
+ stats: fs.Stats;
17
+ } | {
18
+ type: "deleteLocalFile";
19
+ } | {
20
+ type: "deleteRemoteFile";
21
+ } | {
22
+ type: "deleteLocalDirectory";
23
+ } | {
24
+ type: "deleteRemoteDirectory";
25
+ } | {
26
+ type: "downloadFile";
27
+ stats: fs.Stats;
28
+ } | {
29
+ type: "moveLocalFile";
30
+ from: string;
31
+ to: string;
32
+ } | {
33
+ type: "renameLocalFile";
34
+ from: string;
35
+ to: string;
36
+ stats: fs.Stats;
37
+ } | {
38
+ type: "moveRemoteFile";
39
+ from: string;
40
+ to: string;
41
+ } | {
42
+ type: "renameRemoteFile";
43
+ from: string;
44
+ to: string;
45
+ } | {
46
+ type: "renameRemoteDirectory";
47
+ from: string;
48
+ to: string;
49
+ } | {
50
+ type: "renameLocalDirectory";
51
+ from: string;
52
+ to: string;
53
+ stats: fs.Stats;
54
+ } | {
55
+ type: "moveRemoteDirectory";
56
+ from: string;
57
+ to: string;
58
+ } | {
59
+ type: "moveLocalFile";
60
+ from: string;
61
+ to: string;
62
+ stats: fs.Stats;
63
+ } | {
64
+ type: "moveLocalDirectory";
65
+ from: string;
66
+ to: string;
67
+ stats: fs.Stats;
68
+ });
69
+ /**
70
+ * Tasks
71
+ * @date 3/1/2024 - 11:11:32 PM
72
+ *
73
+ * @export
74
+ * @class Tasks
75
+ * @typedef {Tasks}
76
+ */
77
+ export declare class Tasks {
78
+ private readonly sync;
79
+ /**
80
+ * Creates an instance of Tasks.
81
+ * @date 3/1/2024 - 11:11:36 PM
82
+ *
83
+ * @constructor
84
+ * @public
85
+ * @param {{ sync: Sync }} param0
86
+ * @param {Sync} param0.sync
87
+ */
88
+ constructor({ sync }: {
89
+ sync: Sync;
90
+ });
91
+ /**
92
+ * Process a task.
93
+ * @date 3/2/2024 - 12:14:48 PM
94
+ *
95
+ * @private
96
+ * @async
97
+ * @param {{delta: Delta}} param0
98
+ * @param {Delta} param0.delta
99
+ * @returns {Promise<DoneTask>}
100
+ */
101
+ private processTask;
102
+ /**
103
+ * Process all deltas.
104
+ * @date 3/5/2024 - 3:59:51 PM
105
+ *
106
+ * @public
107
+ * @async
108
+ * @param {{ deltas: Delta[] }} param0
109
+ * @param {{}} param0.deltas
110
+ * @returns {Promise<DoneTask[]>}
111
+ */
112
+ process({ deltas }: {
113
+ deltas: Delta[];
114
+ }): Promise<DoneTask[]>;
115
+ }
116
+ export default Tasks;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Tasks = void 0;
4
+ const utils_1 = require("../utils");
5
+ /**
6
+ * Tasks
7
+ * @date 3/1/2024 - 11:11:32 PM
8
+ *
9
+ * @export
10
+ * @class Tasks
11
+ * @typedef {Tasks}
12
+ */
13
+ class Tasks {
14
+ /**
15
+ * Creates an instance of Tasks.
16
+ * @date 3/1/2024 - 11:11:36 PM
17
+ *
18
+ * @constructor
19
+ * @public
20
+ * @param {{ sync: Sync }} param0
21
+ * @param {Sync} param0.sync
22
+ */
23
+ constructor({ sync }) {
24
+ this.sync = sync;
25
+ }
26
+ /**
27
+ * Process a task.
28
+ * @date 3/2/2024 - 12:14:48 PM
29
+ *
30
+ * @private
31
+ * @async
32
+ * @param {{delta: Delta}} param0
33
+ * @param {Delta} param0.delta
34
+ * @returns {Promise<DoneTask>}
35
+ */
36
+ async processTask({ delta }) {
37
+ switch (delta.type) {
38
+ case "createLocalDirectory": {
39
+ const stats = await this.sync.localFileSystem.mkdir({ relativePath: delta.path });
40
+ return Object.assign(Object.assign({}, delta), { stats });
41
+ }
42
+ case "createRemoteDirectory": {
43
+ const uuid = await this.sync.remoteFileSystem.mkdir({ relativePath: delta.path });
44
+ return Object.assign(Object.assign({}, delta), { uuid });
45
+ }
46
+ case "deleteLocalDirectory":
47
+ case "deleteLocalFile": {
48
+ await this.sync.localFileSystem.unlink({ relativePath: delta.path });
49
+ return delta;
50
+ }
51
+ case "deleteRemoteDirectory":
52
+ case "deleteRemoteFile": {
53
+ await this.sync.remoteFileSystem.unlink({ relativePath: delta.path });
54
+ return delta;
55
+ }
56
+ case "moveLocalDirectory":
57
+ case "renameLocalDirectory":
58
+ case "renameLocalFile":
59
+ case "moveLocalFile": {
60
+ const stats = await this.sync.localFileSystem.rename({ fromRelativePath: delta.from, toRelativePath: delta.to });
61
+ return Object.assign(Object.assign({}, delta), { stats });
62
+ }
63
+ case "moveRemoteDirectory":
64
+ case "renameRemoteDirectory":
65
+ case "renameRemoteFile":
66
+ case "moveRemoteFile": {
67
+ await this.sync.remoteFileSystem.rename({ fromRelativePath: delta.from, toRelativePath: delta.to });
68
+ return delta;
69
+ }
70
+ case "downloadFile": {
71
+ const stats = await this.sync.remoteFileSystem.download({ relativePath: delta.path });
72
+ return Object.assign(Object.assign({}, delta), { stats });
73
+ }
74
+ case "uploadFile": {
75
+ const item = await this.sync.localFileSystem.upload({ relativePath: delta.path });
76
+ return Object.assign(Object.assign({}, delta), { item });
77
+ }
78
+ }
79
+ }
80
+ /**
81
+ * Process all deltas.
82
+ * @date 3/5/2024 - 3:59:51 PM
83
+ *
84
+ * @public
85
+ * @async
86
+ * @param {{ deltas: Delta[] }} param0
87
+ * @param {{}} param0.deltas
88
+ * @returns {Promise<DoneTask[]>}
89
+ */
90
+ async process({ deltas }) {
91
+ // Work on deltas from "left to right" (ascending order, path length).
92
+ deltas = deltas.sort((a, b) => a.path.split("/").length - b.path.split("/").length);
93
+ const executed = [];
94
+ const promises = [];
95
+ for (const delta of deltas) {
96
+ promises.push(new Promise((resolve, reject) => {
97
+ this.processTask({ delta })
98
+ .then(doneTask => {
99
+ executed.push(doneTask);
100
+ resolve();
101
+ })
102
+ .catch(reject);
103
+ }));
104
+ }
105
+ await (0, utils_1.promiseAllSettledChunked)(promises);
106
+ return executed;
107
+ }
108
+ }
109
+ exports.Tasks = Tasks;
110
+ exports.default = Tasks;
111
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/lib/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ISemaphore {
2
+ acquire(): Promise<void>;
3
+ release(): void;
4
+ count(): number;
5
+ setMax(newMax: number): void;
6
+ purge(): number;
7
+ }
8
+ /**
9
+ * Basic Semaphore implementation.
10
+ * @date 2/15/2024 - 4:52:51 AM
11
+ *
12
+ * @type {new (max: number) => ISemaphore}
13
+ */
14
+ export declare const Semaphore: new (max: number) => ISemaphore;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Semaphore = void 0;
4
+ /**
5
+ * Basic Semaphore implementation.
6
+ * @date 2/15/2024 - 4:52:51 AM
7
+ *
8
+ * @type {new (max: number) => ISemaphore}
9
+ */
10
+ exports.Semaphore = function (max) {
11
+ let counter = 0;
12
+ let waiting = [];
13
+ let maxCount = max || 1;
14
+ const take = function () {
15
+ if (waiting.length > 0 && counter < maxCount) {
16
+ counter++;
17
+ const promise = waiting.shift();
18
+ if (!promise) {
19
+ return;
20
+ }
21
+ promise.resolve();
22
+ }
23
+ };
24
+ this.acquire = function () {
25
+ if (counter < maxCount) {
26
+ counter++;
27
+ return new Promise(resolve => {
28
+ resolve();
29
+ });
30
+ }
31
+ else {
32
+ return new Promise((resolve, err) => {
33
+ waiting.push({
34
+ resolve: resolve,
35
+ err: err
36
+ });
37
+ });
38
+ }
39
+ };
40
+ this.release = function () {
41
+ counter--;
42
+ take();
43
+ };
44
+ this.count = function () {
45
+ return counter;
46
+ };
47
+ this.setMax = function (newMax) {
48
+ maxCount = newMax;
49
+ };
50
+ this.purge = function () {
51
+ const unresolved = waiting.length;
52
+ for (let i = 0; i < unresolved; i++) {
53
+ const w = waiting[i];
54
+ if (!w) {
55
+ continue;
56
+ }
57
+ w.err("Task has been purged");
58
+ }
59
+ counter = 0;
60
+ waiting = [];
61
+ return unresolved;
62
+ };
63
+ };
64
+ //# sourceMappingURL=semaphore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semaphore.js","sourceRoot":"","sources":["../src/semaphore.ts"],"names":[],"mappings":";;;AAQA;;;;;GAKG;AACU,QAAA,SAAS,GAAG,UAA4B,GAAW;IAC/D,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,OAAO,GAA8F,EAAE,CAAA;IAC3G,IAAI,QAAQ,GAAG,GAAG,IAAI,CAAC,CAAA;IAEvB,MAAM,IAAI,GAAG;QACZ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,GAAG,QAAQ,EAAE,CAAC;YAC9C,OAAO,EAAE,CAAA;YAET,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;YAE/B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,OAAM;YACP,CAAC;YAED,OAAO,CAAC,OAAO,EAAE,CAAA;QAClB,CAAC;IACF,CAAC,CAAA;IAED,IAAI,CAAC,OAAO,GAAG;QACd,IAAI,OAAO,GAAG,QAAQ,EAAE,CAAC;YACxB,OAAO,EAAE,CAAA;YAET,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;gBAClC,OAAO,EAAE,CAAA;YACV,CAAC,CAAC,CAAA;QACH,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;gBACzC,OAAO,CAAC,IAAI,CAAC;oBACZ,OAAO,EAAE,OAAO;oBAChB,GAAG,EAAE,GAAG;iBACR,CAAC,CAAA;YACH,CAAC,CAAC,CAAA;QACH,CAAC;IACF,CAAC,CAAA;IAED,IAAI,CAAC,OAAO,GAAG;QACd,OAAO,EAAE,CAAA;QAET,IAAI,EAAE,CAAA;IACP,CAAC,CAAA;IAED,IAAI,CAAC,KAAK,GAAG;QACZ,OAAO,OAAO,CAAA;IACf,CAAC,CAAA;IAED,IAAI,CAAC,MAAM,GAAG,UAAU,MAAc;QACrC,QAAQ,GAAG,MAAM,CAAA;IAClB,CAAC,CAAA;IAED,IAAI,CAAC,KAAK,GAAG;QACZ,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAA;QAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;YAEpB,IAAI,CAAC,CAAC,EAAE,CAAC;gBACR,SAAQ;YACT,CAAC;YAED,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;QAC9B,CAAC;QAED,OAAO,GAAG,CAAC,CAAA;QACX,OAAO,GAAG,EAAE,CAAA;QAEZ,OAAO,UAAU,CAAA;IAClB,CAAC,CAAA;AACF,CAAiD,CAAA"}
@@ -0,0 +1,12 @@
1
+ export type SyncMode = "twoWay" | "localToCloud" | "localBackup" | "cloudToLocal" | "cloudBackup";
2
+ export type SyncPair = {
3
+ uuid: string;
4
+ localPath: string;
5
+ remotePath: string;
6
+ remoteParentUUID: string;
7
+ mode: SyncMode;
8
+ };
9
+ export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
10
+ export type Prettify<T> = {
11
+ [K in keyof T]: T[K];
12
+ } & {};
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Chunk large Promise.all executions.
3
+ * @date 2/14/2024 - 11:59:34 PM
4
+ *
5
+ * @export
6
+ * @async
7
+ * @template T
8
+ * @param {Promise<T>[]} promises
9
+ * @param {number} [chunkSize=10000]
10
+ * @returns {Promise<T[]>}
11
+ */
12
+ export declare function promiseAllChunked<T>(promises: Promise<T>[], chunkSize?: number): Promise<T[]>;
13
+ /**
14
+ * Chunk large Promise.allSettled executions.
15
+ * @date 3/5/2024 - 12:41:08 PM
16
+ *
17
+ * @export
18
+ * @async
19
+ * @template T
20
+ * @param {Promise<T>[]} promises
21
+ * @param {number} [chunkSize=100000]
22
+ * @returns {Promise<T[]>}
23
+ */
24
+ export declare function promiseAllSettledChunked<T>(promises: Promise<T>[], chunkSize?: number): Promise<T[]>;
package/dist/utils.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promiseAllSettledChunked = exports.promiseAllChunked = void 0;
4
+ /**
5
+ * Chunk large Promise.all executions.
6
+ * @date 2/14/2024 - 11:59:34 PM
7
+ *
8
+ * @export
9
+ * @async
10
+ * @template T
11
+ * @param {Promise<T>[]} promises
12
+ * @param {number} [chunkSize=10000]
13
+ * @returns {Promise<T[]>}
14
+ */
15
+ async function promiseAllChunked(promises, chunkSize = 100000) {
16
+ const results = [];
17
+ for (let i = 0; i < promises.length; i += chunkSize) {
18
+ const chunkResults = await Promise.all(promises.slice(i, i + chunkSize));
19
+ results.push(...chunkResults);
20
+ }
21
+ return results;
22
+ }
23
+ exports.promiseAllChunked = promiseAllChunked;
24
+ /**
25
+ * Chunk large Promise.allSettled executions.
26
+ * @date 3/5/2024 - 12:41:08 PM
27
+ *
28
+ * @export
29
+ * @async
30
+ * @template T
31
+ * @param {Promise<T>[]} promises
32
+ * @param {number} [chunkSize=100000]
33
+ * @returns {Promise<T[]>}
34
+ */
35
+ async function promiseAllSettledChunked(promises, chunkSize = 100000) {
36
+ const results = [];
37
+ for (let i = 0; i < promises.length; i += chunkSize) {
38
+ const chunkPromisesSettled = await Promise.allSettled(promises.slice(i, i + chunkSize));
39
+ const chunkResults = chunkPromisesSettled.reduce((acc, current) => {
40
+ if (current.status === "fulfilled") {
41
+ acc.push(current.value);
42
+ }
43
+ else {
44
+ // Handle rejected promises or do something with the error (current.reason)
45
+ }
46
+ return acc;
47
+ }, []);
48
+ results.push(...chunkResults);
49
+ }
50
+ return results;
51
+ }
52
+ exports.promiseAllSettledChunked = promiseAllSettledChunked;
53
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;GAUG;AACI,KAAK,UAAU,iBAAiB,CAAI,QAAsB,EAAE,SAAS,GAAG,MAAM;IACpF,MAAM,OAAO,GAAQ,EAAE,CAAA;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACrD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAA;QAExE,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,OAAO,CAAA;AACf,CAAC;AAVD,8CAUC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,wBAAwB,CAAI,QAAsB,EAAE,SAAS,GAAG,MAAM;IAC3F,MAAM,OAAO,GAAQ,EAAE,CAAA;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACrD,MAAM,oBAAoB,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAA;QACvF,MAAM,YAAY,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,GAAQ,EAAE,OAAO,EAAE,EAAE;YACtE,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACpC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACxB,CAAC;iBAAM,CAAC;gBACP,2EAA2E;YAC5E,CAAC;YAED,OAAO,GAAG,CAAA;QACX,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,OAAO,CAAA;AACf,CAAC;AAnBD,4DAmBC"}