speechflow 1.6.4 → 1.6.5

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.
Files changed (86) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +5 -3
  3. package/etc/speechflow.yaml +15 -13
  4. package/package.json +5 -5
  5. package/speechflow-cli/dst/speechflow-main-api.js +3 -7
  6. package/speechflow-cli/dst/speechflow-main-api.js.map +1 -1
  7. package/speechflow-cli/dst/speechflow-main-graph.js +1 -1
  8. package/speechflow-cli/dst/speechflow-main.js +6 -0
  9. package/speechflow-cli/dst/speechflow-main.js.map +1 -1
  10. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js +1 -21
  11. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js.map +1 -1
  12. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js +1 -21
  13. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js.map +1 -1
  14. package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js +2 -2
  15. package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js.map +1 -1
  16. package/speechflow-cli/dst/speechflow-node-a2a-gender.js +35 -29
  17. package/speechflow-cli/dst/speechflow-node-a2a-gender.js.map +1 -1
  18. package/speechflow-cli/dst/speechflow-node-a2a-meter.js +50 -34
  19. package/speechflow-cli/dst/speechflow-node-a2a-meter.js.map +1 -1
  20. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js +1 -0
  21. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js.map +1 -1
  22. package/speechflow-cli/dst/speechflow-node-a2a-vad.js +2 -2
  23. package/speechflow-cli/dst/speechflow-node-a2a-vad.js.map +1 -1
  24. package/speechflow-cli/dst/speechflow-node-a2t-openai.d.ts +0 -1
  25. package/speechflow-cli/dst/speechflow-node-a2t-openai.js +0 -6
  26. package/speechflow-cli/dst/speechflow-node-a2t-openai.js.map +1 -1
  27. package/speechflow-cli/dst/speechflow-node-t2a-amazon.d.ts +0 -1
  28. package/speechflow-cli/dst/speechflow-node-t2a-amazon.js +0 -6
  29. package/speechflow-cli/dst/speechflow-node-t2a-amazon.js.map +1 -1
  30. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.d.ts +0 -1
  31. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.js +0 -6
  32. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.js.map +1 -1
  33. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.d.ts +0 -1
  34. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js +0 -6
  35. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js.map +1 -1
  36. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js +1 -1
  37. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js.map +1 -1
  38. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js +6 -6
  39. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js.map +1 -1
  40. package/speechflow-cli/dst/speechflow-node-xio-device.js +3 -2
  41. package/speechflow-cli/dst/speechflow-node-xio-device.js.map +1 -1
  42. package/speechflow-cli/dst/speechflow-node-xio-websocket.js.map +1 -1
  43. package/speechflow-cli/dst/speechflow-util-audio.d.ts +1 -0
  44. package/speechflow-cli/dst/speechflow-util-audio.js +21 -0
  45. package/speechflow-cli/dst/speechflow-util-audio.js.map +1 -1
  46. package/speechflow-cli/dst/speechflow-util-error.d.ts +1 -1
  47. package/speechflow-cli/dst/speechflow-util-error.js +7 -1
  48. package/speechflow-cli/dst/speechflow-util-error.js.map +1 -1
  49. package/speechflow-cli/dst/speechflow-util-stream.d.ts +1 -1
  50. package/speechflow-cli/dst/speechflow-util-stream.js +2 -2
  51. package/speechflow-cli/dst/speechflow-util-stream.js.map +1 -1
  52. package/speechflow-cli/etc/oxlint.jsonc +2 -1
  53. package/speechflow-cli/package.json +17 -17
  54. package/speechflow-cli/src/speechflow-main-api.ts +6 -13
  55. package/speechflow-cli/src/speechflow-main-graph.ts +1 -1
  56. package/speechflow-cli/src/speechflow-main.ts +4 -0
  57. package/speechflow-cli/src/speechflow-node-a2a-compressor-wt.ts +1 -29
  58. package/speechflow-cli/src/speechflow-node-a2a-expander-wt.ts +1 -29
  59. package/speechflow-cli/src/speechflow-node-a2a-ffmpeg.ts +2 -2
  60. package/speechflow-cli/src/speechflow-node-a2a-gender.ts +44 -39
  61. package/speechflow-cli/src/speechflow-node-a2a-meter.ts +58 -38
  62. package/speechflow-cli/src/speechflow-node-a2a-rnnoise.ts +1 -0
  63. package/speechflow-cli/src/speechflow-node-a2a-vad.ts +2 -2
  64. package/speechflow-cli/src/speechflow-node-a2t-openai.ts +0 -6
  65. package/speechflow-cli/src/speechflow-node-t2a-amazon.ts +0 -6
  66. package/speechflow-cli/src/speechflow-node-t2a-elevenlabs.ts +0 -6
  67. package/speechflow-cli/src/speechflow-node-t2a-kokoro.ts +0 -6
  68. package/speechflow-cli/src/speechflow-node-t2t-ollama.ts +1 -1
  69. package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +10 -14
  70. package/speechflow-cli/src/speechflow-node-xio-device.ts +3 -2
  71. package/speechflow-cli/src/speechflow-node-xio-websocket.ts +1 -1
  72. package/speechflow-cli/src/speechflow-util-audio.ts +30 -0
  73. package/speechflow-cli/src/speechflow-util-error.ts +9 -3
  74. package/speechflow-cli/src/speechflow-util-stream.ts +2 -2
  75. package/speechflow-ui-db/dst/index.js +20 -20
  76. package/speechflow-ui-db/package.json +8 -8
  77. package/speechflow-ui-db/src/app.vue +14 -5
  78. package/speechflow-ui-st/dst/index.js +455 -20
  79. package/speechflow-ui-st/package.json +9 -9
  80. package/speechflow-ui-st/src/app.vue +8 -3
  81. package/speechflow-cli/dst/speechflow-util-webaudio-wt.d.ts +0 -1
  82. package/speechflow-cli/dst/speechflow-util-webaudio-wt.js +0 -124
  83. package/speechflow-cli/dst/speechflow-util-webaudio-wt.js.map +0 -1
  84. package/speechflow-cli/dst/speechflow-util-webaudio.d.ts +0 -13
  85. package/speechflow-cli/dst/speechflow-util-webaudio.js +0 -137
  86. package/speechflow-cli/dst/speechflow-util-webaudio.js.map +0 -1
@@ -15,21 +15,21 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "vue": "3.5.21",
18
- "vue3-spinners": "1.3.1",
18
+ "vue3-spinners": "1.3.3",
19
19
  "luxon": "3.7.2",
20
20
  "@opensumi/reconnecting-websocket": "4.4.0",
21
- "axios": "1.12.1",
21
+ "axios": "1.12.2",
22
22
  "typopro-web": "4.2.7",
23
23
  "@fortawesome/fontawesome-free": "7.0.1",
24
24
  "patch-package": "8.0.0",
25
- "@rse/stx": "1.1.1",
25
+ "@rse/stx": "1.1.2",
26
26
  "animejs": "4.1.3"
27
27
  },
28
28
  "devDependencies": {
29
- "vite": "7.1.5",
30
- "typescript-eslint": "8.43.0",
31
- "@typescript-eslint/eslint-plugin": "8.43.0",
32
- "@typescript-eslint/parser": "8.43.0",
29
+ "vite": "7.1.6",
30
+ "typescript-eslint": "8.44.0",
31
+ "@typescript-eslint/eslint-plugin": "8.44.0",
32
+ "@typescript-eslint/parser": "8.44.0",
33
33
  "@vitejs/plugin-vue": "6.0.1",
34
34
  "@rollup/plugin-yaml": "4.1.2",
35
35
  "vite-plugin-node-polyfills": "0.24.0",
@@ -39,8 +39,8 @@
39
39
 
40
40
  "@vue/eslint-config-typescript": "14.6.0",
41
41
  "vue-eslint-parser": "10.2.0",
42
- "eslint": "9.35.0",
43
- "@eslint/js": "9.35.0",
42
+ "eslint": "9.36.0",
43
+ "@eslint/js": "9.36.0",
44
44
  "neostandard": "0.12.2",
45
45
  "eslint-plugin-import": "2.32.0",
46
46
  "eslint-plugin-vue": "10.4.0",
@@ -117,8 +117,10 @@ export default defineComponent({
117
117
  cleanupIntervalId: null as ReturnType<typeof setInterval> | null
118
118
  }),
119
119
  async mounted () {
120
- /* determine API URL */
121
- const url = new URL("/api", document.location.href).toString()
120
+ /* determine API URLs */
121
+ const urlHTTP = new URL("/api", document.location.href)
122
+ const urlWS = new URL("/api", document.location.href)
123
+ urlWS.protocol = (urlHTTP.protocol === "https:" ? "wss:" : "ws:")
122
124
 
123
125
  /* optically remove outdated text chunks */
124
126
  this.cleanupIntervalId = setInterval(() => {
@@ -146,13 +148,16 @@ export default defineComponent({
146
148
  }, 500)
147
149
 
148
150
  /* connect to WebSocket API for receiving dashboard information */
149
- const ws = new ReconnectingWebSocket(url, [], {
151
+ const ws = new ReconnectingWebSocket(urlWS.toString(), [], {
150
152
  reconnectionDelayGrowFactor: 1.3,
151
153
  maxReconnectionDelay: 4000,
152
154
  minReconnectionDelay: 1000,
153
155
  connectionTimeout: 4000,
154
156
  minUptime: 5000
155
157
  })
158
+ ws.addEventListener("error", (ev) => {
159
+ this.log("ERROR", `WebSocket error: ${ev.message}`)
160
+ })
156
161
 
157
162
  /* track connection open/close */
158
163
  ws.addEventListener("open", (ev) => {
@@ -1 +0,0 @@
1
- export {};
@@ -1,124 +0,0 @@
1
- "use strict";
2
- /*
3
- ** SpeechFlow - Speech Processing Flow Graph
4
- ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
5
- ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- /* audio source node */
9
- class AudioSourceProcessor extends AudioWorkletProcessor {
10
- /* internal state */
11
- pendingData = [];
12
- currentChunk = null;
13
- currentOffset = 0;
14
- /* node construction */
15
- constructor() {
16
- super();
17
- /* receive input chunks */
18
- this.port.addEventListener("message", (event) => {
19
- const { type, chunkId } = event.data;
20
- if (type === "input-chunk")
21
- this.pendingData.push({ data: event.data.data.pcmData, chunkId });
22
- });
23
- }
24
- /* process audio frame */
25
- process(inputs, /* unused */ outputs, parameters /* unused */) {
26
- /* determine output */
27
- const output = outputs[0];
28
- if (!output || output.length === 0)
29
- return true;
30
- const frameCount = output[0].length;
31
- const channelCount = output.length;
32
- /* get current chunk if we don't have one */
33
- if (this.currentChunk === null && this.pendingData.length > 0) {
34
- this.currentChunk = this.pendingData.shift();
35
- this.currentOffset = 0;
36
- /* signal chunk start */
37
- const message = {
38
- type: "chunk-started",
39
- chunkId: this.currentChunk.chunkId
40
- };
41
- this.port.postMessage(message);
42
- }
43
- /* process input */
44
- if (this.currentChunk) {
45
- /* output current chunk */
46
- const samplesPerChannel = this.currentChunk.data.length / channelCount;
47
- const remainingFrames = samplesPerChannel - this.currentOffset;
48
- const framesToProcess = Math.min(frameCount, remainingFrames);
49
- /* copy data from current chunk (interleaved to planar) */
50
- for (let frame = 0; frame < framesToProcess; frame++) {
51
- for (let ch = 0; ch < channelCount; ch++) {
52
- const interleavedIndex = (this.currentOffset + frame) * channelCount + ch;
53
- output[ch][frame] = this.currentChunk.data[interleavedIndex] ?? 0;
54
- }
55
- }
56
- /* zero-pad remaining output if needed */
57
- for (let frame = framesToProcess; frame < frameCount; frame++)
58
- for (let ch = 0; ch < channelCount; ch++)
59
- output[ch][frame] = 0;
60
- /* check if current chunk is finished */
61
- this.currentOffset += framesToProcess;
62
- if (this.currentOffset >= samplesPerChannel) {
63
- this.currentChunk = null;
64
- this.currentOffset = 0;
65
- }
66
- }
67
- else {
68
- /* output silence when no input */
69
- for (let ch = 0; ch < channelCount; ch++)
70
- output[ch].fill(0);
71
- }
72
- return true;
73
- }
74
- }
75
- /* audio capture node */
76
- class AudioCaptureProcessor extends AudioWorkletProcessor {
77
- /* internal state */
78
- activeCaptures = new Map();
79
- /* node construction */
80
- constructor() {
81
- super();
82
- /* receive start of capturing command */
83
- this.port.addEventListener("message", (event) => {
84
- const { type, chunkId } = event.data;
85
- if (type === "start-capture") {
86
- this.activeCaptures.set(chunkId, {
87
- data: [],
88
- expectedSamples: event.data.expectedSamples
89
- });
90
- }
91
- });
92
- }
93
- /* process audio frame */
94
- process(inputs, outputs, /* unused */ parameters /* unused */) {
95
- /* determine input */
96
- const input = inputs[0];
97
- if (!input || input.length === 0 || this.activeCaptures.size === 0)
98
- return true;
99
- const frameCount = input[0].length;
100
- const channelCount = input.length;
101
- /* iterate over all active captures */
102
- for (const [chunkId, capture] of this.activeCaptures) {
103
- /* convert planar to interleaved */
104
- for (let frame = 0; frame < frameCount; frame++)
105
- for (let ch = 0; ch < channelCount; ch++)
106
- capture.data.push(input[ch][frame]);
107
- /* send back captured data */
108
- if (capture.data.length >= capture.expectedSamples) {
109
- const message = {
110
- type: "capture-complete",
111
- chunkId,
112
- data: capture.data.slice(0, capture.expectedSamples)
113
- };
114
- this.port.postMessage(message);
115
- this.activeCaptures.delete(chunkId);
116
- }
117
- }
118
- return true;
119
- }
120
- }
121
- /* register the new audio nodes */
122
- registerProcessor("source", AudioSourceProcessor);
123
- registerProcessor("capture", AudioCaptureProcessor);
124
- //# sourceMappingURL=speechflow-util-webaudio-wt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"speechflow-util-webaudio-wt.js","sourceRoot":"","sources":["../src/speechflow-util-webaudio-wt.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- import { AudioContext, AudioWorkletNode } from "node-web-audio-api";
2
- export declare class WebAudio {
3
- sampleRate: number;
4
- channels: number;
5
- audioContext: AudioContext;
6
- sourceNode: AudioWorkletNode | null;
7
- captureNode: AudioWorkletNode | null;
8
- private pendingPromises;
9
- constructor(sampleRate: number, channels: number);
10
- setup(): Promise<void>;
11
- process(int16Array: Int16Array): Promise<Int16Array>;
12
- destroy(): Promise<void>;
13
- }
@@ -1,137 +0,0 @@
1
- "use strict";
2
- /*
3
- ** SpeechFlow - Speech Processing Flow Graph
4
- ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
5
- ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
6
- */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.WebAudio = void 0;
12
- /* standard dependencies */
13
- const node_path_1 = __importDefault(require("node:path"));
14
- /* external dependencies */
15
- const node_web_audio_api_1 = require("node-web-audio-api");
16
- class WebAudio {
17
- sampleRate;
18
- channels;
19
- /* internal state */
20
- audioContext;
21
- sourceNode = null;
22
- captureNode = null;
23
- pendingPromises = new Map();
24
- /* construct object */
25
- constructor(sampleRate, channels) {
26
- this.sampleRate = sampleRate;
27
- this.channels = channels;
28
- /* create new audio context */
29
- this.audioContext = new node_web_audio_api_1.AudioContext({
30
- sampleRate,
31
- latencyHint: "interactive"
32
- });
33
- }
34
- /* setup object */
35
- async setup() {
36
- /* ensure audio context is not suspended */
37
- if (this.audioContext.state === "suspended")
38
- await this.audioContext.resume();
39
- /* add audio worklet module */
40
- const url = node_path_1.default.resolve(__dirname, "speechflow-util-webaudio-wt.js");
41
- await this.audioContext.audioWorklet.addModule(url);
42
- /* create source node */
43
- this.sourceNode = new node_web_audio_api_1.AudioWorkletNode(this.audioContext, "source", {
44
- numberOfInputs: 0,
45
- numberOfOutputs: 1,
46
- outputChannelCount: [this.channels]
47
- });
48
- /* create capture node */
49
- this.captureNode = new node_web_audio_api_1.AudioWorkletNode(this.audioContext, "capture", {
50
- numberOfInputs: 1,
51
- numberOfOutputs: 0
52
- });
53
- this.captureNode.port.addEventListener("message", (event) => {
54
- const { type, chunkId, data } = event.data ?? {};
55
- if (type === "capture-complete") {
56
- const promise = this.pendingPromises.get(chunkId);
57
- if (promise) {
58
- clearTimeout(promise.timeout);
59
- this.pendingPromises.delete(chunkId);
60
- const int16Data = new Int16Array(data.length);
61
- for (let i = 0; i < data.length; i++)
62
- int16Data[i] = Math.max(-32768, Math.min(32767, Math.round(data[i] * 32767)));
63
- promise.resolve(int16Data);
64
- }
65
- }
66
- });
67
- /* start ports */
68
- this.sourceNode.port.start();
69
- this.captureNode.port.start();
70
- }
71
- /* process single audio chunk */
72
- async process(int16Array) {
73
- const chunkId = `chunk_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
74
- return new Promise((resolve, reject) => {
75
- const timeout = setTimeout(() => {
76
- this.pendingPromises.delete(chunkId);
77
- reject(new Error("processing timeout"));
78
- }, (int16Array.length / this.audioContext.sampleRate) * 1000 + 250);
79
- if (this.captureNode !== null)
80
- this.pendingPromises.set(chunkId, { resolve, reject, timeout });
81
- try {
82
- const float32Data = new Float32Array(int16Array.length);
83
- for (let i = 0; i < int16Array.length; i++)
84
- float32Data[i] = int16Array[i] / 32768.0;
85
- /* start capture first */
86
- if (this.captureNode !== null) {
87
- this.captureNode?.port.postMessage({
88
- type: "start-capture",
89
- chunkId,
90
- expectedSamples: int16Array.length
91
- });
92
- }
93
- /* small delay to ensure capture is ready before sending data */
94
- setTimeout(() => {
95
- /* send input to source node */
96
- this.sourceNode?.port.postMessage({
97
- type: "input-chunk",
98
- chunkId,
99
- data: { pcmData: float32Data, channels: this.channels }
100
- }, [float32Data.buffer]);
101
- }, 5);
102
- }
103
- catch (error) {
104
- clearTimeout(timeout);
105
- if (this.captureNode !== null)
106
- this.pendingPromises.delete(chunkId);
107
- reject(new Error(`failed to process chunk: ${error}`));
108
- }
109
- });
110
- }
111
- async destroy() {
112
- /* reject all pending promises */
113
- try {
114
- this.pendingPromises.forEach(({ reject, timeout }) => {
115
- clearTimeout(timeout);
116
- reject(new Error("WebAudio destroyed"));
117
- });
118
- this.pendingPromises.clear();
119
- }
120
- catch (_err) {
121
- /* ignored - cleanup during shutdown */
122
- }
123
- /* disconnect nodes */
124
- if (this.sourceNode !== null) {
125
- this.sourceNode.disconnect();
126
- this.sourceNode = null;
127
- }
128
- if (this.captureNode !== null) {
129
- this.captureNode.disconnect();
130
- this.captureNode = null;
131
- }
132
- /* stop context */
133
- await this.audioContext.close();
134
- }
135
- }
136
- exports.WebAudio = WebAudio;
137
- //# sourceMappingURL=speechflow-util-webaudio.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"speechflow-util-webaudio.js","sourceRoot":"","sources":["../src/speechflow-util-webaudio.ts"],"names":[],"mappings":";AAAA;;;;EAIE;;;;;;AAEF,6BAA6B;AAC7B,0DAA4B;AAE5B,6BAA6B;AAC7B,2DAAmE;AAEnE,MAAa,QAAQ;IAaN;IACA;IAbX,sBAAsB;IACf,YAAY,CAAc;IAC1B,UAAU,GAA8B,IAAI,CAAA;IAC5C,WAAW,GAA6B,IAAI,CAAA;IAC3C,eAAe,GAAG,IAAI,GAAG,EAI7B,CAAA;IAEJ,wBAAwB;IACxB,YACW,UAAkB,EAClB,QAAgB;QADhB,eAAU,GAAV,UAAU,CAAQ;QAClB,aAAQ,GAAR,QAAQ,CAAQ;QAEvB,gCAAgC;QAChC,IAAI,CAAC,YAAY,GAAG,IAAI,iCAAY,CAAC;YACjC,UAAU;YACV,WAAW,EAAE,aAAa;SAC7B,CAAC,CAAA;IACN,CAAC;IAED,oBAAoB;IACb,KAAK,CAAC,KAAK;QACd,6CAA6C;QAC7C,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,KAAK,WAAW;YACvC,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAA;QAEpC,gCAAgC;QAChC,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gCAAgC,CAAC,CAAA;QACrE,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAEnD,0BAA0B;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,qCAAgB,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE;YAChE,cAAc,EAAG,CAAC;YAClB,eAAe,EAAE,CAAC;YAClB,kBAAkB,EAAE,CAAE,IAAI,CAAC,QAAQ,CAAE;SACxC,CAAC,CAAA;QAEF,2BAA2B;QAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,qCAAgB,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE;YAClE,cAAc,EAAG,CAAC;YAClB,eAAe,EAAE,CAAC;SACrB,CAAC,CAAA;QACF,IAAI,CAAC,WAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACzD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAA;YAChD,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBACjD,IAAI,OAAO,EAAE,CAAC;oBACV,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;oBAC7B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;oBACpC,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;oBAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;wBAChC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;oBACjF,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;gBAC9B,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAA;QAEF,mBAAmB;QACnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;QAC5B,IAAI,CAAC,WAAY,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;IAClC,CAAC;IAED,kCAAkC;IAC3B,KAAK,CAAC,OAAO,CAAE,UAAsB;QACxC,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAA;QACpF,OAAO,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC/C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBACpC,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAA;YAC3C,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,CAAA;YACnE,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;gBACzB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;YACnE,IAAI,CAAC;gBACD,MAAM,WAAW,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;gBACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE;oBACtC,WAAW,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;gBAE5C,2BAA2B;gBAC3B,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;oBAC5B,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC;wBAC/B,IAAI,EAAE,eAAe;wBACrB,OAAO;wBACP,eAAe,EAAE,UAAU,CAAC,MAAM;qBACrC,CAAC,CAAA;gBACN,CAAC;gBAED,kEAAkE;gBAClE,UAAU,CAAC,GAAG,EAAE;oBACZ,iCAAiC;oBACjC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC;wBAC9B,IAAI,EAAE,aAAa;wBACnB,OAAO;wBACP,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;qBAC1D,EAAE,CAAE,WAAW,CAAC,MAAM,CAAE,CAAC,CAAA;gBAC9B,CAAC,EAAE,CAAC,CAAC,CAAA;YACT,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;gBACX,YAAY,CAAC,OAAO,CAAC,CAAA;gBACrB,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;oBACzB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBACxC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC,CAAA;YAC1D,CAAC;QACL,CAAC,CAAC,CAAA;IACN,CAAC;IAEM,KAAK,CAAC,OAAO;QAChB,mCAAmC;QACnC,IAAI,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;gBACjD,YAAY,CAAC,OAAO,CAAC,CAAA;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAA;YAC3C,CAAC,CAAC,CAAA;YACF,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;QAChC,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;YACV,uCAAuC;QAC3C,CAAC;QAED,wBAAwB;QACxB,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC3B,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAA;YAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QAC1B,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAA;YAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QAC3B,CAAC;QAED,oBAAoB;QACpB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;IACnC,CAAC;CACJ;AAtID,4BAsIC"}