@yu_robotics/remote-cli 1.6.169 → 1.6.173

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 (49) hide show
  1. package/README.md +21 -2
  2. package/dist/client/GoalCommand.d.ts +15 -0
  3. package/dist/client/GoalCommand.d.ts.map +1 -0
  4. package/dist/client/GoalCommand.js +59 -0
  5. package/dist/client/GoalCommand.js.map +1 -0
  6. package/dist/client/MessageHandler.d.ts +3 -0
  7. package/dist/client/MessageHandler.d.ts.map +1 -1
  8. package/dist/client/MessageHandler.js +167 -43
  9. package/dist/client/MessageHandler.js.map +1 -1
  10. package/dist/client/TaskRecovery.d.ts +3 -1
  11. package/dist/client/TaskRecovery.d.ts.map +1 -1
  12. package/dist/client/TaskRecovery.js +9 -4
  13. package/dist/client/TaskRecovery.js.map +1 -1
  14. package/dist/client/WebSocketClient.d.ts +2 -1
  15. package/dist/client/WebSocketClient.d.ts.map +1 -1
  16. package/dist/client/WebSocketClient.js +8 -1
  17. package/dist/client/WebSocketClient.js.map +1 -1
  18. package/dist/executor/CodexAppServerClient.d.ts +1 -0
  19. package/dist/executor/CodexAppServerClient.d.ts.map +1 -1
  20. package/dist/executor/CodexAppServerClient.js +12 -4
  21. package/dist/executor/CodexAppServerClient.js.map +1 -1
  22. package/dist/executor/CodexAppServerExecutor.d.ts +28 -2
  23. package/dist/executor/CodexAppServerExecutor.d.ts.map +1 -1
  24. package/dist/executor/CodexAppServerExecutor.js +517 -30
  25. package/dist/executor/CodexAppServerExecutor.js.map +1 -1
  26. package/dist/executor/IExecutor.d.ts +24 -0
  27. package/dist/executor/IExecutor.d.ts.map +1 -1
  28. package/dist/executor/codex/CodexGoals.d.ts +6 -0
  29. package/dist/executor/codex/CodexGoals.d.ts.map +1 -0
  30. package/dist/executor/codex/CodexGoals.js +49 -0
  31. package/dist/executor/codex/CodexGoals.js.map +1 -0
  32. package/dist/executor/codex/CodexImages.d.ts +22 -0
  33. package/dist/executor/codex/CodexImages.d.ts.map +1 -0
  34. package/dist/executor/codex/CodexImages.js +201 -0
  35. package/dist/executor/codex/CodexImages.js.map +1 -0
  36. package/dist/maintenance/release-notes.json +1 -1
  37. package/dist/utils/ImageDelivery.d.ts +67 -0
  38. package/dist/utils/ImageDelivery.d.ts.map +1 -0
  39. package/dist/utils/ImageDelivery.js +270 -0
  40. package/dist/utils/ImageDelivery.js.map +1 -0
  41. package/dist/utils/ImageValidation.d.ts +11 -0
  42. package/dist/utils/ImageValidation.d.ts.map +1 -0
  43. package/dist/utils/ImageValidation.js +62 -0
  44. package/dist/utils/ImageValidation.js.map +1 -0
  45. package/dist/utils/LocalImageDetector.d.ts +12 -3
  46. package/dist/utils/LocalImageDetector.d.ts.map +1 -1
  47. package/dist/utils/LocalImageDetector.js +153 -55
  48. package/dist/utils/LocalImageDetector.js.map +1 -1
  49. package/package.json +1 -1
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageDelivery = exports.ImageReadPool = exports.IMAGE_DELIVERY_LIMITS = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const LocalImageDetector_1 = require("./LocalImageDetector");
6
+ const ImageValidation_1 = require("./ImageValidation");
7
+ exports.IMAGE_DELIVERY_LIMITS = {
8
+ images: 8,
9
+ candidates: 32,
10
+ pathLength: 4096,
11
+ scanLength: 512 * 1024,
12
+ readTimeoutMs: 15_000,
13
+ drainTimeoutMs: 30_000,
14
+ };
15
+ /** Bound queued read jobs; the filesystem reader separately owns its actual I/O permits. */
16
+ class ImageReadPool {
17
+ concurrency;
18
+ queuedLimit;
19
+ active = 0;
20
+ queue = [];
21
+ constructor(concurrency = 4, queuedLimit = 32) {
22
+ this.concurrency = concurrency;
23
+ this.queuedLimit = queuedLimit;
24
+ }
25
+ submit(run) {
26
+ if (this.active >= this.concurrency && this.queue.length >= this.queuedLimit)
27
+ return undefined;
28
+ const job = { run, started: false };
29
+ this.queue.push(job);
30
+ this.pump();
31
+ return () => {
32
+ if (job.started)
33
+ return;
34
+ const index = this.queue.indexOf(job);
35
+ if (index >= 0)
36
+ this.queue.splice(index, 1);
37
+ job.run = undefined;
38
+ };
39
+ }
40
+ pump() {
41
+ while (this.active < this.concurrency && this.queue.length) {
42
+ const job = this.queue.shift();
43
+ const run = job.run;
44
+ job.run = undefined;
45
+ if (!run)
46
+ continue;
47
+ job.started = true;
48
+ this.active++;
49
+ // Collector timeout does not release this job's permit. The filesystem
50
+ // reader also retains its I/O permit if its own deadline wins first.
51
+ void Promise.resolve().then(run).catch(() => { }).finally(() => {
52
+ this.active--;
53
+ this.pump();
54
+ });
55
+ }
56
+ }
57
+ }
58
+ exports.ImageReadPool = ImageReadPool;
59
+ const sharedReads = new ImageReadPool();
60
+ /** One logical reply owns deduplication and accepted asynchronous image reads. */
61
+ class ImageDelivery {
62
+ options;
63
+ attempts = 0;
64
+ omitted = 0;
65
+ closed = false;
66
+ cancelled = false;
67
+ hashes = new Set();
68
+ pending = new Set();
69
+ reasons = new Set();
70
+ streamText = '';
71
+ streamEligible = () => true;
72
+ streamPaths = new Set();
73
+ scanLimited = false;
74
+ constructor(options) {
75
+ this.options = options;
76
+ }
77
+ offerImage(image, eligible = () => true) {
78
+ if (!this.admit(eligible))
79
+ return;
80
+ this.deliver(image, eligible);
81
+ }
82
+ offerText(text, eligible = () => true) {
83
+ if (typeof text !== 'string' || !text || !this.current(eligible) || this.closed)
84
+ return;
85
+ // Do not retain transcripts or allocate an unbounded candidate collection.
86
+ const bounded = text.slice(0, exports.IMAGE_DELIVERY_LIMITS.scanLength);
87
+ if (text.length > bounded.length)
88
+ this.scanLimited = true;
89
+ const paths = (0, LocalImageDetector_1.extractLocalImagePaths)(bounded);
90
+ for (const filePath of paths)
91
+ this.offerFile(filePath, eligible);
92
+ }
93
+ /** Keep a bounded window, preserving a path-sized overlap at chunk boundaries. */
94
+ offerStream(chunk, eligible = () => true) {
95
+ if (!chunk || this.closed || !this.current(eligible))
96
+ return;
97
+ if (!this.streamEligible())
98
+ this.resetStream();
99
+ this.streamEligible = eligible;
100
+ let offset = 0;
101
+ while (offset < chunk.length) {
102
+ const take = Math.min(exports.IMAGE_DELIVERY_LIMITS.scanLength - this.streamText.length, chunk.length - offset);
103
+ this.streamText += chunk.slice(offset, offset + take);
104
+ offset += take;
105
+ if (this.streamText.length === exports.IMAGE_DELIVERY_LIMITS.scanLength) {
106
+ this.scanStream();
107
+ this.streamText = this.streamText.slice(-exports.IMAGE_DELIVERY_LIMITS.pathLength);
108
+ }
109
+ }
110
+ }
111
+ flushStream() {
112
+ this.scanStream();
113
+ this.streamText = '';
114
+ }
115
+ resetStream() {
116
+ this.streamText = '';
117
+ this.streamPaths.clear();
118
+ }
119
+ scanStream() {
120
+ if (!this.current(this.streamEligible))
121
+ return;
122
+ for (const filePath of (0, LocalImageDetector_1.extractLocalImagePaths)(this.streamText)) {
123
+ if (this.streamPaths.has(filePath))
124
+ continue;
125
+ if (this.streamPaths.size < exports.IMAGE_DELIVERY_LIMITS.candidates)
126
+ this.streamPaths.add(filePath);
127
+ this.offerFile(filePath, this.streamEligible);
128
+ }
129
+ }
130
+ offerFile(filePath, eligible = () => true) {
131
+ if (!this.admit(eligible))
132
+ return;
133
+ if (typeof filePath !== 'string' || !filePath || filePath.length > exports.IMAGE_DELIVERY_LIMITS.pathLength) {
134
+ this.omit('invalid image reference');
135
+ return;
136
+ }
137
+ let live = true;
138
+ let resolve;
139
+ let cancelQueued;
140
+ const done = new Promise(complete => { resolve = complete; });
141
+ const settle = () => {
142
+ if (!live)
143
+ return;
144
+ live = false;
145
+ clearTimeout(timer);
146
+ this.pending.delete(pending);
147
+ resolve();
148
+ };
149
+ const pending = { done, stop: () => { cancelQueued?.(); settle(); } };
150
+ const timer = setTimeout(() => {
151
+ if (live && this.current(eligible))
152
+ this.omit('image read timed out');
153
+ pending.stop();
154
+ }, this.options.readTimeoutMs ?? exports.IMAGE_DELIVERY_LIMITS.readTimeoutMs);
155
+ this.pending.add(pending);
156
+ cancelQueued = (this.options.pool ?? sharedReads).submit(async () => {
157
+ try {
158
+ if (!live || !this.current(eligible))
159
+ return;
160
+ const image = await this.options.readFile(filePath);
161
+ if (!live || !this.current(eligible))
162
+ return;
163
+ if (image)
164
+ this.deliver({ type: 'image', data: image.data, mimeType: image.mimeType }, eligible);
165
+ else
166
+ this.omit('image unavailable or outside the allowed directories');
167
+ }
168
+ catch {
169
+ if (live && this.current(eligible))
170
+ this.omit('image could not be read');
171
+ }
172
+ finally {
173
+ settle();
174
+ }
175
+ });
176
+ if (!cancelQueued) {
177
+ this.omit('image read capacity reached');
178
+ settle();
179
+ }
180
+ }
181
+ /** Drain a fixed prefix without closing admission for a managed continuation. */
182
+ async drain() {
183
+ const prefix = [...this.pending];
184
+ if (!prefix.length)
185
+ return;
186
+ let timer;
187
+ await Promise.race([
188
+ Promise.all(prefix.map(job => job.done)),
189
+ new Promise(resolve => {
190
+ timer = setTimeout(() => {
191
+ for (const job of prefix) {
192
+ if (!this.pending.has(job))
193
+ continue;
194
+ if (this.current())
195
+ this.omit('image delivery timed out');
196
+ job.stop();
197
+ }
198
+ resolve();
199
+ }, this.options.drainTimeoutMs ?? exports.IMAGE_DELIVERY_LIMITS.drainTimeoutMs);
200
+ }),
201
+ ]);
202
+ if (timer)
203
+ clearTimeout(timer);
204
+ }
205
+ async finish() {
206
+ this.flushStream();
207
+ this.closed = true;
208
+ await this.drain();
209
+ if (this.omitted && this.current()) {
210
+ this.options.notice(`\nImages omitted: ${this.omitted} (${[...this.reasons].join('; ')}).\n`);
211
+ }
212
+ if (this.scanLimited && this.current()) {
213
+ this.options.notice('\nImage link scanning reached its text limit; some references may not have been inspected.\n');
214
+ }
215
+ this.cancel();
216
+ }
217
+ cancel() {
218
+ this.closed = true;
219
+ this.cancelled = true;
220
+ this.invalidatePending();
221
+ }
222
+ /** Discard disconnected work while allowing newly emitted images after recovery. */
223
+ invalidatePending() {
224
+ this.resetStream();
225
+ for (const job of [...this.pending])
226
+ job.stop();
227
+ }
228
+ current(eligible = () => true) {
229
+ return !this.cancelled && this.options.isCurrent() && eligible();
230
+ }
231
+ admit(eligible) {
232
+ if (this.closed || !this.current(eligible))
233
+ return false;
234
+ if (this.attempts >= exports.IMAGE_DELIVERY_LIMITS.candidates) {
235
+ this.omit('image candidate limit reached');
236
+ return false;
237
+ }
238
+ this.attempts++;
239
+ return true;
240
+ }
241
+ deliver(candidate, eligible) {
242
+ if (!this.current(eligible))
243
+ return;
244
+ const image = (0, ImageValidation_1.validateImageBlock)(candidate);
245
+ if (!image) {
246
+ this.omit('invalid or oversized image');
247
+ return;
248
+ }
249
+ const hash = (0, crypto_1.createHash)('sha256').update(Buffer.from(image.data, 'base64')).digest('hex');
250
+ if (this.hashes.has(hash))
251
+ return;
252
+ if (this.hashes.size >= exports.IMAGE_DELIVERY_LIMITS.images) {
253
+ this.omit('image count limit reached');
254
+ return;
255
+ }
256
+ try {
257
+ this.options.publish(image);
258
+ this.hashes.add(hash);
259
+ }
260
+ catch {
261
+ this.omit('image could not be sent');
262
+ }
263
+ }
264
+ omit(reason) {
265
+ this.omitted = Math.min(Number.MAX_SAFE_INTEGER, this.omitted + 1);
266
+ this.reasons.add(reason);
267
+ }
268
+ }
269
+ exports.ImageDelivery = ImageDelivery;
270
+ //# sourceMappingURL=ImageDelivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageDelivery.js","sourceRoot":"","sources":["../../src/utils/ImageDelivery.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;AAEpC,6DAA8D;AAC9D,uDAAuD;AAE1C,QAAA,qBAAqB,GAAG;IACnC,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,EAAE;IACd,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,GAAG,GAAG,IAAI;IACtB,aAAa,EAAE,MAAM;IACrB,cAAc,EAAE,MAAM;CACd,CAAC;AAOX,4FAA4F;AAC5F,MAAa,aAAa;IAIK;IAAkC;IAHvD,MAAM,GAAG,CAAC,CAAC;IACF,KAAK,GAAc,EAAE,CAAC;IAEvC,YAA6B,cAAc,CAAC,EAAmB,cAAc,EAAE;QAAlD,gBAAW,GAAX,WAAW,CAAI;QAAmB,gBAAW,GAAX,WAAW,CAAK;IAAG,CAAC;IAEnF,MAAM,CAAC,GAAwB;QAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,SAAS,CAAC;QAC/F,MAAM,GAAG,GAAY,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,GAAG,EAAE;YACV,IAAI,GAAG,CAAC,OAAO;gBAAE,OAAO;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,KAAK,IAAI,CAAC;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC;QACtB,CAAC,CAAC;IACJ,CAAC;IAEO,IAAI;QACV,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;YAChC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;YACpB,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC;YACpB,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,uEAAuE;YACvE,qEAAqE;YACrE,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF;AAnCD,sCAmCC;AAED,MAAM,WAAW,GAAG,IAAI,aAAa,EAAE,CAAC;AAiBxC,kFAAkF;AAClF,MAAa,aAAa;IAaK;IAZrB,QAAQ,GAAG,CAAC,CAAC;IACb,OAAO,GAAG,CAAC,CAAC;IACZ,MAAM,GAAG,KAAK,CAAC;IACf,SAAS,GAAG,KAAK,CAAC;IACT,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3B,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IACjC,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,UAAU,GAAG,EAAE,CAAC;IAChB,cAAc,GAAkB,GAAG,EAAE,CAAC,IAAI,CAAC;IAClC,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,WAAW,GAAG,KAAK,CAAC;IAE5B,YAA6B,OAA6B;QAA7B,YAAO,GAAP,OAAO,CAAsB;IAAG,CAAC;IAE9D,UAAU,CAAC,KAAiB,EAAE,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI;QACjD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,OAAO;QAClC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,CAAC,IAAa,EAAE,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI;QAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxF,2EAA2E;QAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,6BAAqB,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1D,MAAM,KAAK,GAAG,IAAA,2CAAsB,EAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,MAAM,QAAQ,IAAI,KAAK;YAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnE,CAAC;IAED,kFAAkF;IAClF,WAAW,CAAC,KAAa,EAAE,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI;QAC9C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO;QAC7D,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YAAE,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/C,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;QAC/B,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,6BAAqB,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;YACxG,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;YACtD,MAAM,IAAI,IAAI,CAAC;YACf,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,6BAAqB,CAAC,UAAU,EAAE,CAAC;gBAChE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,6BAAqB,CAAC,UAAU,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACvB,CAAC;IAED,WAAW;QACT,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEO,UAAU;QAChB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC;YAAE,OAAO;QAC/C,KAAK,MAAM,QAAQ,IAAI,IAAA,2CAAsB,EAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC7C,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,6BAAqB,CAAC,UAAU;gBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7F,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,SAAS,CAAC,QAAgB,EAAE,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI;QAC/C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,OAAO;QAClC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,6BAAqB,CAAC,UAAU,EAAE,CAAC;YACpG,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QACD,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,IAAI,OAAoB,CAAC;QACzB,IAAI,YAAsC,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,QAAQ,CAAC,EAAE,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,GAAG,KAAK,CAAC;YACb,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,MAAM,OAAO,GAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,6BAAqB,CAAC,aAAa,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1B,YAAY,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;YAClE,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;oBAAE,OAAO;gBAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACpD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;oBAAE,OAAO;gBAC7C,IAAI,KAAK;oBAAE,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;;oBAC5F,IAAI,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;YACzE,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YAC3E,CAAC;oBAAS,CAAC;gBAAC,MAAM,EAAE,CAAC;YAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YACzC,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,KAAK;QACT,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO;QAC3B,IAAI,KAAgD,CAAC;QACrD,MAAM,OAAO,CAAC,IAAI,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;gBAC1B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACtB,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;wBACzB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;4BAAE,SAAS;wBACrC,IAAI,IAAI,CAAC,OAAO,EAAE;4BAAE,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;wBAC1D,GAAG,CAAC,IAAI,EAAE,CAAC;oBACb,CAAC;oBACD,OAAO,EAAE,CAAC;gBACZ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,6BAAqB,CAAC,cAAc,CAAC,CAAC;YAC1E,CAAC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,qBAAqB,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChG,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,8FAA8F,CAAC,CAAC;QACtH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAED,oFAAoF;IACpF,iBAAiB;QACf,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YAAE,GAAG,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IAEO,OAAO,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI;QACnC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,QAAQ,EAAE,CAAC;IACnE,CAAC;IAEO,KAAK,CAAC,QAAuB;QACnC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACzD,IAAI,IAAI,CAAC,QAAQ,IAAI,6BAAqB,CAAC,UAAU,EAAE,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,OAAO,CAAC,SAAqB,EAAE,QAAuB;QAC5D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO;QACpC,MAAM,KAAK,GAAG,IAAA,oCAAkB,EAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAChE,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1F,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAClC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,6BAAqB,CAAC,MAAM,EAAE,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACzG,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAAC,CAAC;IACnD,CAAC;IAEO,IAAI,CAAC,MAAc;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;CACF;AAtLD,sCAsLC"}
@@ -0,0 +1,11 @@
1
+ import type { ImageBlock } from '../types';
2
+ export declare const MAX_IMAGE_BYTES: number;
3
+ /** Identify supported signatures, without claiming to decode or sanitize the image. */
4
+ export declare function sniffImageMime(bytes: Buffer): string | null;
5
+ /**
6
+ * Accept only canonical, padded base64 within the decoded size limit. The declared
7
+ * MIME must agree with the signature (including common BMP/ICO/JPEG aliases).
8
+ * Return only wire fields, with MIME derived from bytes; never forward metadata.
9
+ */
10
+ export declare function validateImageBlock(image: unknown): ImageBlock | null;
11
+ //# sourceMappingURL=ImageValidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageValidation.d.ts","sourceRoot":"","sources":["../../src/utils/ImageValidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,eAAe,QAAkB,CAAC;AAG/C,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAoBpE"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_IMAGE_BYTES = void 0;
4
+ exports.sniffImageMime = sniffImageMime;
5
+ exports.validateImageBlock = validateImageBlock;
6
+ exports.MAX_IMAGE_BYTES = 2 * 1024 * 1024;
7
+ const MAX_ENCODED_BYTES = 4 * Math.ceil(exports.MAX_IMAGE_BYTES / 3);
8
+ /** Identify supported signatures, without claiming to decode or sanitize the image. */
9
+ function sniffImageMime(bytes) {
10
+ if (!Buffer.isBuffer(bytes))
11
+ return null;
12
+ if (bytes.length >= 8 && bytes.subarray(0, 8).equals(Buffer.from('89504e470d0a1a0a', 'hex')))
13
+ return 'image/png';
14
+ if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff)
15
+ return 'image/jpeg';
16
+ if (bytes.length >= 12 && bytes.toString('latin1', 0, 4) === 'RIFF'
17
+ && bytes.toString('latin1', 8, 12) === 'WEBP')
18
+ return 'image/webp';
19
+ if (bytes.length >= 6 && ['GIF87a', 'GIF89a'].includes(bytes.toString('latin1', 0, 6)))
20
+ return 'image/gif';
21
+ if (bytes.length >= 4 && ['49492a00', '4d4d002a'].includes(bytes.subarray(0, 4).toString('hex')))
22
+ return 'image/tiff';
23
+ if (bytes.length >= 14 && bytes[0] === 0x42 && bytes[1] === 0x4d)
24
+ return 'image/bmp';
25
+ if (bytes.length >= 6 && bytes.readUInt32LE(0) === 0x00010000 && bytes.readUInt16LE(4) > 0)
26
+ return 'image/x-icon';
27
+ return null;
28
+ }
29
+ /**
30
+ * Accept only canonical, padded base64 within the decoded size limit. The declared
31
+ * MIME must agree with the signature (including common BMP/ICO/JPEG aliases).
32
+ * Return only wire fields, with MIME derived from bytes; never forward metadata.
33
+ */
34
+ function validateImageBlock(image) {
35
+ if (!image || typeof image !== 'object')
36
+ return null;
37
+ const candidate = image;
38
+ if (candidate.type !== 'image' || typeof candidate.data !== 'string' || typeof candidate.mimeType !== 'string')
39
+ return null;
40
+ const data = candidate.data;
41
+ if (!data.length || data.length > MAX_ENCODED_BYTES || data.length % 4 !== 0)
42
+ return null;
43
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(data))
44
+ return null;
45
+ const decodedSize = data.length / 4 * 3 - (data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0);
46
+ if (decodedSize <= 0 || decodedSize > exports.MAX_IMAGE_BYTES)
47
+ return null;
48
+ const bytes = Buffer.from(data, 'base64');
49
+ if (bytes.length !== decodedSize || bytes.toString('base64') !== data)
50
+ return null;
51
+ const mimeType = sniffImageMime(bytes);
52
+ const aliases = {
53
+ 'image/jpg': 'image/jpeg',
54
+ 'image/x-ms-bmp': 'image/bmp',
55
+ 'image/vnd.microsoft.icon': 'image/x-icon',
56
+ };
57
+ const declared = candidate.mimeType.trim().toLowerCase();
58
+ if (!mimeType || (aliases[declared] ?? declared) !== mimeType)
59
+ return null;
60
+ return { type: 'image', data, mimeType };
61
+ }
62
+ //# sourceMappingURL=ImageValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageValidation.js","sourceRoot":"","sources":["../../src/utils/ImageValidation.ts"],"names":[],"mappings":";;;AAMA,wCAWC;AAOD,gDAoBC;AA1CY,QAAA,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC/C,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAe,GAAG,CAAC,CAAC,CAAC;AAE7D,uFAAuF;AACvF,SAAgB,cAAc,CAAC,KAAa;IAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAAE,OAAO,WAAW,CAAC;IACjH,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IAC1G,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM;WAC9D,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,YAAY,CAAC;IACrE,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,WAAW,CAAC;IAC3G,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,YAAY,CAAC;IACtH,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,WAAW,CAAC;IACrF,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC;QAAE,OAAO,cAAc,CAAC;IAClH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,KAAc;IAC/C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,SAAS,GAAG,KAA4B,CAAC;IAC/C,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,SAAS,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5H,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,iBAAiB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1F,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjG,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,GAAG,uBAAe;QAAE,OAAO,IAAI,CAAC;IACnE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnF,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,OAAO,GAA2B;QACtC,WAAW,EAAE,YAAY;QACzB,gBAAgB,EAAE,WAAW;QAC7B,0BAA0B,EAAE,cAAc;KAC3C,CAAC;IACF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzD,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC3C,CAAC"}
@@ -1,10 +1,19 @@
1
+ import type { DirectoryGuard } from '../security/DirectoryGuard';
2
+ export { MAX_IMAGE_BYTES } from './ImageValidation';
1
3
  export interface LocalImage {
2
4
  path: string;
3
5
  data: string;
4
6
  mimeType: string;
5
7
  }
6
- /** Extract standard Markdown image destinations and plain local image paths. */
8
+ export type DetectedLocalImage = LocalImage;
9
+ type ImagePolicy = DirectoryGuard | ((candidate: string, cwd: string) => boolean);
10
+ /** Extract at most 32 candidate attempts, including invalid and duplicate destinations. */
7
11
  export declare function extractLocalImagePaths(text: unknown): string[];
8
- /** Read detected images that are allowed by the caller's directory policy. */
9
- export declare function readLocalImages(text: unknown, cwd: string, isAllowed: (candidate: string, cwd: string) => boolean): Promise<LocalImage[]>;
12
+ /** Read exactly one native saved path. No text parsing or extension inference. */
13
+ export declare function readLocalImagePath(filePath: string, cwd: string, directoryGuard: DirectoryGuard): Promise<DetectedLocalImage | null>;
14
+ /**
15
+ * Read detected images using a guard or the existing callback API. Prefer the
16
+ * guard to resolve allowed-root aliases. These checks are not an OS sandbox.
17
+ */
18
+ export declare function readLocalImages(text: unknown, cwd: string, isAllowed: ImagePolicy): Promise<LocalImage[]>;
10
19
  //# sourceMappingURL=LocalImageDetector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocalImageDetector.d.ts","sourceRoot":"","sources":["../../src/utils/LocalImageDetector.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAiCD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAyC9D;AAED,8EAA8E;AAC9E,wBAAsB,eAAe,CACnC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,GACrD,OAAO,CAAC,UAAU,EAAE,CAAC,CAsBvB"}
1
+ {"version":3,"file":"LocalImageDetector.d.ts","sourceRoot":"","sources":["../../src/utils/LocalImageDetector.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAO5C,KAAK,WAAW,GAAG,cAAc,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;AAyBlF,2FAA2F;AAC3F,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CA+B9D;AAyFD,kFAAkF;AAClF,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,GAC5D,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAEpC;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,WAAW,GACrB,OAAO,CAAC,UAAU,EAAE,CAAC,CAcvB"}