@openspecui/web 3.11.2 → 3.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/CanvasRenderer-CaB1iANG.js +1 -0
- package/dist/assets/WebGLRenderer-BQkM8hJI.js +1 -0
- package/dist/assets/WebGPURenderer-DL2luov0.js +1 -0
- package/dist/assets/audio-preview-EEAGPjut.js +1 -0
- package/dist/assets/browserAll-77yDI0Dz.js +1 -0
- package/dist/assets/common-Cv1DC55Y.js +22 -0
- package/dist/assets/common-tDRAnupk.css +1 -0
- package/dist/assets/{dist-wEqYYKag.js → dist-B85dtRfx.js} +1 -1
- package/dist/assets/dist-B8IUilny.js +1 -0
- package/dist/assets/{dist-DHhbIMeO.js → dist-BRxF7Jkf.js} +1 -1
- package/dist/assets/{dist-Drgp5ero.js → dist-BZECNWGg.js} +1 -1
- package/dist/assets/{dist-B9Ltz3Au.js → dist-BfZLQFwN.js} +1 -1
- package/dist/assets/{dist-HIi-Q3U-.js → dist-CbJQUXs0.js} +1 -1
- package/dist/assets/{dist-B_UFDOda.js → dist-CmKsGuOc.js} +1 -1
- package/dist/assets/{dist-j6cthCRX.js → dist-DiwHgET9.js} +1 -1
- package/dist/assets/dist-Djq8Qfgl.js +1 -0
- package/dist/assets/dist-DpKtO7Rd.js +1 -0
- package/dist/assets/{dist-DRc-odji.js → dist-SfwxOhmW.js} +1 -1
- package/dist/assets/{dist-BggZ7cyQ.js → dist-zpg9m3aC.js} +1 -1
- package/dist/assets/{image-preview-BvROjYK5.js → image-preview-D763uzFX.js} +1 -1
- package/dist/assets/{init-D41cyy2z.js → init-fMWSa5Px.js} +1 -1
- package/dist/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/assets/main-C9sK_hBV.js +1669 -0
- package/dist/assets/main-X9jaWXie.css +1 -0
- package/dist/assets/{media-preview-DWkSTGaX.js → media-preview-CKyl7d05.js} +1 -1
- package/dist/assets/{pdf-preview-C7gTFuZg.js → pdf-preview-CZGViMN9.js} +1 -1
- package/dist/assets/share-tech-mono-latin-400-normal-15MgdvEM.woff +0 -0
- package/dist/assets/share-tech-mono-latin-400-normal-CCqdbj5z.woff2 +0 -0
- package/dist/assets/trpc-CYA_MIjc.js +1 -0
- package/dist/assets/video-preview-zIpjT8bC.js +1 -0
- package/dist/assets/webworkerAll-BDQFYrM_.js +1 -0
- package/dist/audio-preview.html +4 -3
- package/dist/image-preview.html +3 -2
- package/dist/index.html +2 -29
- package/dist/pdf-preview.html +3 -2
- package/dist/video-preview.html +4 -3
- package/dist-ssg/client/.vite/ssr-manifest.json +8565 -1080
- package/dist-ssg/client/assets/CanvasRenderer-tPU4vV1i.js +1 -0
- package/dist-ssg/client/assets/WebGLRenderer-8XaEJZ8d.js +1 -0
- package/dist-ssg/client/assets/WebGPURenderer-D_U45dp8.js +1 -0
- package/dist-ssg/client/assets/browserAll-6a90eROj.js +1 -0
- package/dist-ssg/client/assets/{dist-CzScJNYz.js → dist-B6MkJ-H7.js} +1 -1
- package/dist-ssg/client/assets/{dist-nDBVtvCj.js → dist-B9IiVt9G.js} +1 -1
- package/dist-ssg/client/assets/{dist-BJ0zzLee.js → dist-BCjKNKOg.js} +1 -1
- package/dist-ssg/client/assets/dist-Bqpf_8HF.js +1 -0
- package/dist-ssg/client/assets/{dist-CrdkjkLH.js → dist-CFjNhfqM.js} +1 -1
- package/dist-ssg/client/assets/{dist-lNUMJW4A.js → dist-CIMwXheF.js} +1 -1
- package/dist-ssg/client/assets/{dist-CuFabXJ8.js → dist-CNLvbQSx.js} +1 -1
- package/dist-ssg/client/assets/dist-CWcubuXa.js +1 -0
- package/dist-ssg/client/assets/{dist-Bg-C799P.js → dist-Ch_E0jle.js} +1 -1
- package/dist-ssg/client/assets/{dist-BZ35ju6s.js → dist-CjF4SWnb.js} +1 -1
- package/dist-ssg/client/assets/dist-D2pHEmiw.js +1 -0
- package/dist-ssg/client/assets/{dist-xprslEpB.js → dist-DgYslwM5.js} +1 -1
- package/dist-ssg/client/assets/{ghostty-web-D9IXftv-.js → ghostty-web-BYk-wneR.js} +1 -1
- package/dist-ssg/client/assets/index-8OoZ339S.css +1 -0
- package/dist-ssg/client/assets/{index.ssg-L1BBuH-7.js → index.ssg-BWQbO3uy.js} +167 -152
- package/dist-ssg/client/assets/{init-C058TQcq.js → init-DnSi5N8V.js} +1 -1
- package/dist-ssg/client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist-ssg/client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist-ssg/client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist-ssg/client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist-ssg/client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist-ssg/client/assets/share-tech-mono-latin-400-normal-15MgdvEM.woff +0 -0
- package/dist-ssg/client/assets/share-tech-mono-latin-400-normal-CCqdbj5z.woff2 +0 -0
- package/dist-ssg/client/assets/trpc-BhXIjp-3.js +1 -0
- package/dist-ssg/client/assets/webworkerAll-Dp42RyhF.js +1 -0
- package/dist-ssg/client/index.ssg.html +2 -29
- package/dist-ssg/server/entry-server.js +897 -206
- package/package.json +6 -4
- package/dist/assets/CanvasRenderer-C0z1_uAq.js +0 -1
- package/dist/assets/WebGLRenderer-BgB0b-_m.js +0 -1
- package/dist/assets/WebGPURenderer-DUOyTSOY.js +0 -1
- package/dist/assets/audio-preview-DF-g2nKV.js +0 -1
- package/dist/assets/browserAll-DrkY7ahm.js +0 -1
- package/dist/assets/common-DiWYGJu_.js +0 -22
- package/dist/assets/dist-BLzDSe4i.js +0 -1
- package/dist/assets/dist-C2tzK2BJ.js +0 -1
- package/dist/assets/dist-LSzi3-xz.js +0 -1
- package/dist/assets/main-DpM-T-Pk.js +0 -1654
- package/dist/assets/main-fCQ7khWW.css +0 -1
- package/dist/assets/trpc-lJhbxi32.js +0 -1
- package/dist/assets/video-preview-CChWJOsP.js +0 -1
- package/dist/assets/webworkerAll-DXrA-UNG.js +0 -1
- package/dist-ssg/client/assets/CanvasRenderer-pScAgtDS.js +0 -1
- package/dist-ssg/client/assets/WebGLRenderer-BAJXWFrw.js +0 -1
- package/dist-ssg/client/assets/WebGPURenderer-BeNNGqxY.js +0 -1
- package/dist-ssg/client/assets/browserAll-CkiE7Jmg.js +0 -1
- package/dist-ssg/client/assets/dist-BJBQISim.js +0 -1
- package/dist-ssg/client/assets/dist-BPi1lJ-H.js +0 -1
- package/dist-ssg/client/assets/dist-CNPnfIVE.js +0 -1
- package/dist-ssg/client/assets/index-BtGAsAtP.css +0 -1
- package/dist-ssg/client/assets/trpc-BTuQHFNd.js +0 -1
- package/dist-ssg/client/assets/webworkerAll-ByOBLjhR.js +0 -1
|
@@ -28325,13 +28325,13 @@ function reduceKernel(state, event) {
|
|
|
28325
28325
|
persist: "none"
|
|
28326
28326
|
};
|
|
28327
28327
|
case "APPLY_LAYOUT": {
|
|
28328
|
-
|
|
28328
|
+
const merged = mergeLayout(event.layout);
|
|
28329
|
+
if (!(event.layout.updatedAt !== state.updatedAt || !areTabsEqual(state.mainTabs, merged.mainTabs) || !areTabsEqual(state.bottomTabs, merged.bottomTabs)) || !event.force && event.layout.updatedAt <= state.updatedAt) return {
|
|
28329
28330
|
nextState: state,
|
|
28330
28331
|
changed: false,
|
|
28331
28332
|
notify: [],
|
|
28332
28333
|
persist: "none"
|
|
28333
28334
|
};
|
|
28334
|
-
const merged = mergeLayout(event.layout);
|
|
28335
28335
|
return {
|
|
28336
28336
|
nextState: {
|
|
28337
28337
|
...state,
|
|
@@ -28688,14 +28688,11 @@ var NavController = class {
|
|
|
28688
28688
|
rebindProjectScopedLayout(storageKey) {
|
|
28689
28689
|
const scopedLocal = readLocalStorageByKey(storageKey);
|
|
28690
28690
|
if (scopedLocal) {
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
28695
|
-
bottomTabs: merged.bottomTabs,
|
|
28696
|
-
updatedAt: scopedLocal.updatedAt
|
|
28691
|
+
this.dispatch({
|
|
28692
|
+
type: "APPLY_LAYOUT",
|
|
28693
|
+
layout: scopedLocal,
|
|
28694
|
+
force: true
|
|
28697
28695
|
});
|
|
28698
|
-
this.normalizeUrl();
|
|
28699
28696
|
return;
|
|
28700
28697
|
}
|
|
28701
28698
|
this.state = normalizeState({
|
|
@@ -32292,21 +32289,141 @@ ZodOptional.create;
|
|
|
32292
32289
|
ZodNullable.create;
|
|
32293
32290
|
var preprocessType = ZodEffects.createWithPreprocess;
|
|
32294
32291
|
ZodPipeline.create;
|
|
32292
|
+
//#endregion
|
|
32293
|
+
//#region ../core/src/translation-task-control.ts
|
|
32294
|
+
var BATCH_TRANSLATION_ERROR_KINDS = [
|
|
32295
|
+
"timeout",
|
|
32296
|
+
"memory-limit",
|
|
32297
|
+
"runtime",
|
|
32298
|
+
"abort"
|
|
32299
|
+
];
|
|
32300
|
+
async function runControlledTranslationTask(task, options = {}) {
|
|
32301
|
+
const controller = new AbortController();
|
|
32302
|
+
const cleanupCallbacks = [];
|
|
32303
|
+
const parentSignal = options.signal;
|
|
32304
|
+
const timeoutMs = normalizeTimeoutMs(options.timeoutMs);
|
|
32305
|
+
if (parentSignal) if (parentSignal.aborted) controller.abort(parentSignal.reason);
|
|
32306
|
+
else {
|
|
32307
|
+
const onAbort = () => controller.abort(parentSignal.reason);
|
|
32308
|
+
parentSignal.addEventListener("abort", onAbort, { once: true });
|
|
32309
|
+
cleanupCallbacks.push(() => parentSignal.removeEventListener("abort", onAbort));
|
|
32310
|
+
}
|
|
32311
|
+
if (controller.signal.aborted) {
|
|
32312
|
+
cleanupCallbacks.forEach((callback) => callback());
|
|
32313
|
+
return {
|
|
32314
|
+
ok: false,
|
|
32315
|
+
error: normalizeBatchTranslationError(controller.signal.reason, parentSignal)
|
|
32316
|
+
};
|
|
32317
|
+
}
|
|
32318
|
+
let timer;
|
|
32319
|
+
let timeoutError;
|
|
32320
|
+
const taskPromise = Promise.resolve().then(() => task(controller.signal));
|
|
32321
|
+
taskPromise.catch(() => void 0);
|
|
32322
|
+
const races = [taskPromise];
|
|
32323
|
+
if (!controller.signal.aborted) races.push(new Promise((_, reject) => {
|
|
32324
|
+
const onAbort = () => reject(new DOMException("Translation cancelled.", "AbortError"));
|
|
32325
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
32326
|
+
cleanupCallbacks.push(() => controller.signal.removeEventListener("abort", onAbort));
|
|
32327
|
+
}));
|
|
32328
|
+
if (timeoutMs !== void 0) races.push(new Promise((_, reject) => {
|
|
32329
|
+
timer = setTimeout(() => {
|
|
32330
|
+
timeoutError = /* @__PURE__ */ new Error(`Translation task timed out after ${timeoutMs}ms.`);
|
|
32331
|
+
controller.abort(timeoutError);
|
|
32332
|
+
reject(timeoutError);
|
|
32333
|
+
}, timeoutMs);
|
|
32334
|
+
}));
|
|
32335
|
+
try {
|
|
32336
|
+
return {
|
|
32337
|
+
ok: true,
|
|
32338
|
+
value: await Promise.race(races)
|
|
32339
|
+
};
|
|
32340
|
+
} catch (error) {
|
|
32341
|
+
controller.abort(error);
|
|
32342
|
+
if (timeoutError && controller.signal.reason === timeoutError) return {
|
|
32343
|
+
ok: false,
|
|
32344
|
+
error: {
|
|
32345
|
+
kind: "timeout",
|
|
32346
|
+
message: timeoutError.message
|
|
32347
|
+
}
|
|
32348
|
+
};
|
|
32349
|
+
return {
|
|
32350
|
+
ok: false,
|
|
32351
|
+
error: normalizeBatchTranslationError(error, parentSignal)
|
|
32352
|
+
};
|
|
32353
|
+
} finally {
|
|
32354
|
+
if (timer) clearTimeout(timer);
|
|
32355
|
+
cleanupCallbacks.forEach((callback) => callback());
|
|
32356
|
+
}
|
|
32357
|
+
}
|
|
32358
|
+
function normalizeBatchTranslationError(error, parentSignal) {
|
|
32359
|
+
if (isBatchTranslationError(error)) return error;
|
|
32360
|
+
if (parentSignal?.aborted) return {
|
|
32361
|
+
kind: "abort",
|
|
32362
|
+
message: readAbortMessage(parentSignal.reason) ?? "Translation cancelled."
|
|
32363
|
+
};
|
|
32364
|
+
if (error instanceof DOMException && error.name === "AbortError") return {
|
|
32365
|
+
kind: "abort",
|
|
32366
|
+
message: readAbortMessage(error) ?? "Translation cancelled."
|
|
32367
|
+
};
|
|
32368
|
+
const message = getErrorMessage$2(error);
|
|
32369
|
+
if (isTimeoutMessage(message)) return {
|
|
32370
|
+
kind: "timeout",
|
|
32371
|
+
message
|
|
32372
|
+
};
|
|
32373
|
+
if (isMemoryLimitMessage(message)) return {
|
|
32374
|
+
kind: "memory-limit",
|
|
32375
|
+
message
|
|
32376
|
+
};
|
|
32377
|
+
return {
|
|
32378
|
+
kind: "runtime",
|
|
32379
|
+
message
|
|
32380
|
+
};
|
|
32381
|
+
}
|
|
32382
|
+
function normalizeTimeoutMs(timeoutMs) {
|
|
32383
|
+
return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? Math.floor(timeoutMs) : void 0;
|
|
32384
|
+
}
|
|
32385
|
+
function getErrorMessage$2(error) {
|
|
32386
|
+
if (error instanceof Error && error.message.trim().length > 0) return error.message;
|
|
32387
|
+
if (typeof error === "string" && error.trim().length > 0) return error;
|
|
32388
|
+
return "Translation failed.";
|
|
32389
|
+
}
|
|
32390
|
+
function readAbortMessage(reason) {
|
|
32391
|
+
if (reason instanceof Error && reason.message.trim().length > 0) return reason.message;
|
|
32392
|
+
if (typeof reason === "string" && reason.trim().length > 0) return reason;
|
|
32393
|
+
}
|
|
32394
|
+
function isTimeoutMessage(message) {
|
|
32395
|
+
return /\btime(?:d)?\s*out\b/i.test(message);
|
|
32396
|
+
}
|
|
32397
|
+
function isMemoryLimitMessage(message) {
|
|
32398
|
+
return /out of memory/i.test(message) || /memory limit/i.test(message) || /insufficient memory/i.test(message) || /ERR_WORKER_OUT_OF_MEMORY/i.test(message);
|
|
32399
|
+
}
|
|
32400
|
+
function isBatchTranslationError(value) {
|
|
32401
|
+
if (typeof value !== "object" || value === null) return false;
|
|
32402
|
+
const kind = Reflect.get(value, "kind");
|
|
32403
|
+
const message = Reflect.get(value, "message");
|
|
32404
|
+
return typeof kind === "string" && BATCH_TRANSLATION_ERROR_KINDS.includes(kind) && typeof message === "string" && message.length > 0;
|
|
32405
|
+
}
|
|
32295
32406
|
var TranslationEngineIdSchema = enumType([
|
|
32296
32407
|
"browser",
|
|
32297
32408
|
"local",
|
|
32298
32409
|
"local-ct2",
|
|
32410
|
+
"local-llama",
|
|
32299
32411
|
"openai"
|
|
32300
32412
|
]);
|
|
32301
32413
|
var DEFAULT_TRANSLATION_ENGINE_ID = "browser";
|
|
32302
32414
|
function isManagedLocalTranslationEngineId(engineId) {
|
|
32415
|
+
return engineId === "local" || engineId === "local-ct2" || engineId === "local-llama";
|
|
32416
|
+
}
|
|
32417
|
+
function isDirectionalManagedLocalTranslationEngineId(engineId) {
|
|
32303
32418
|
return engineId === "local" || engineId === "local-ct2";
|
|
32304
32419
|
}
|
|
32305
32420
|
enumType([
|
|
32306
32421
|
"local",
|
|
32307
32422
|
"local-ct2",
|
|
32423
|
+
"local-llama",
|
|
32308
32424
|
"openai"
|
|
32309
32425
|
]);
|
|
32426
|
+
var DEFAULT_BATCH_TRANSLATION_TIMEOUT_MS = 15e3;
|
|
32310
32427
|
var LocalModelDownloadStatusSchema = enumType([
|
|
32311
32428
|
"not-downloaded",
|
|
32312
32429
|
"queued",
|
|
@@ -32419,7 +32536,11 @@ var LocalModelProfileLoadStateSchema = objectType({
|
|
|
32419
32536
|
updatedAt: numberType().int().nonnegative().optional()
|
|
32420
32537
|
});
|
|
32421
32538
|
objectType({
|
|
32422
|
-
engineId: enumType([
|
|
32539
|
+
engineId: enumType([
|
|
32540
|
+
"local",
|
|
32541
|
+
"local-ct2",
|
|
32542
|
+
"local-llama"
|
|
32543
|
+
]),
|
|
32423
32544
|
modelId: stringType().min(1),
|
|
32424
32545
|
selectedGroupId: stringType().min(1).optional(),
|
|
32425
32546
|
groupId: stringType().min(1).optional(),
|
|
@@ -32468,6 +32589,11 @@ objectType({
|
|
|
32468
32589
|
downloadedBytes: numberType().int().nonnegative().optional()
|
|
32469
32590
|
})).default([])
|
|
32470
32591
|
});
|
|
32592
|
+
enumType([
|
|
32593
|
+
"local",
|
|
32594
|
+
"network",
|
|
32595
|
+
"recommended"
|
|
32596
|
+
]);
|
|
32471
32597
|
var TranslationEngineDependencyStateSchema = enumType([
|
|
32472
32598
|
"installed",
|
|
32473
32599
|
"installing",
|
|
@@ -32542,17 +32668,27 @@ var TranslationOpenAISettingsSchema = objectType({
|
|
|
32542
32668
|
var TranslationLocalSettingsSchema = objectType({
|
|
32543
32669
|
model: stringType().default("Xenova/nllb-200-distilled-600M"),
|
|
32544
32670
|
selectedGroupId: stringType().optional(),
|
|
32545
|
-
hfEndpoint: stringType().default("")
|
|
32671
|
+
hfEndpoint: stringType().default(""),
|
|
32672
|
+
memoryBudgetPercent: numberType().min(0).max(100).default(25)
|
|
32546
32673
|
});
|
|
32547
32674
|
var TranslationLocalCt2SettingsSchema = objectType({
|
|
32548
32675
|
model: stringType().default("ooeoeo/opus-mt-en-zh-ct2-float16"),
|
|
32549
32676
|
selectedGroupId: stringType().optional(),
|
|
32550
|
-
hfEndpoint: stringType().default("")
|
|
32677
|
+
hfEndpoint: stringType().default(""),
|
|
32678
|
+
memoryBudgetPercent: numberType().min(0).max(100).default(25)
|
|
32679
|
+
});
|
|
32680
|
+
var TranslationLocalLlamaSettingsSchema = objectType({
|
|
32681
|
+
model: stringType().default("bartowski/Qwen2.5-0.5B-Instruct-GGUF"),
|
|
32682
|
+
selectedGroupId: stringType().optional(),
|
|
32683
|
+
hfEndpoint: stringType().default(""),
|
|
32684
|
+
memoryBudgetPercent: numberType().min(0).max(100).default(25)
|
|
32551
32685
|
});
|
|
32552
32686
|
objectType({
|
|
32687
|
+
engineId: TranslationEngineIdSchema.default(DEFAULT_TRANSLATION_ENGINE_ID),
|
|
32553
32688
|
openai: TranslationOpenAISettingsSchema.default(TranslationOpenAISettingsSchema.parse({})),
|
|
32554
32689
|
local: TranslationLocalSettingsSchema.default(TranslationLocalSettingsSchema.parse({})),
|
|
32555
|
-
localCt2: TranslationLocalCt2SettingsSchema.default(TranslationLocalCt2SettingsSchema.parse({}))
|
|
32690
|
+
localCt2: TranslationLocalCt2SettingsSchema.default(TranslationLocalCt2SettingsSchema.parse({})),
|
|
32691
|
+
localLlama: TranslationLocalLlamaSettingsSchema.default(TranslationLocalLlamaSettingsSchema.parse({}))
|
|
32556
32692
|
});
|
|
32557
32693
|
objectType({
|
|
32558
32694
|
engineId: TranslationEngineIdSchema,
|
|
@@ -32562,11 +32698,16 @@ objectType({
|
|
|
32562
32698
|
selectedGroupId: stringType().min(1).optional(),
|
|
32563
32699
|
inputs: arrayType(stringType()).min(1),
|
|
32564
32700
|
instructions: stringType().optional(),
|
|
32565
|
-
context: stringType().optional()
|
|
32701
|
+
context: stringType().optional(),
|
|
32702
|
+
timeoutMs: numberType().int().positive().default(DEFAULT_BATCH_TRANSLATION_TIMEOUT_MS)
|
|
32566
32703
|
});
|
|
32567
32704
|
objectType({
|
|
32568
32705
|
index: numberType().int().nonnegative(),
|
|
32569
|
-
output: stringType()
|
|
32706
|
+
output: stringType().optional(),
|
|
32707
|
+
error: objectType({
|
|
32708
|
+
kind: enumType(BATCH_TRANSLATION_ERROR_KINDS),
|
|
32709
|
+
message: stringType().min(1)
|
|
32710
|
+
}).optional()
|
|
32570
32711
|
});
|
|
32571
32712
|
var DocumentTranslationDisplayModeSchema = enumType(["direct", "bilingual"]);
|
|
32572
32713
|
var TranslationEngineProjectSettingsSchema = objectType({
|
|
@@ -32578,6 +32719,10 @@ var TranslationEngineProjectSettingsSchema = objectType({
|
|
|
32578
32719
|
model: stringType().min(1).optional(),
|
|
32579
32720
|
selectedGroupId: stringType().min(1).optional()
|
|
32580
32721
|
}).default({}),
|
|
32722
|
+
localLlama: objectType({
|
|
32723
|
+
model: stringType().min(1).optional(),
|
|
32724
|
+
selectedGroupId: stringType().min(1).optional()
|
|
32725
|
+
}).default({}),
|
|
32581
32726
|
openai: objectType({ model: stringType().min(1).optional() }).default({})
|
|
32582
32727
|
}).default({});
|
|
32583
32728
|
var DocumentTranslationConfigSchema = objectType({
|
|
@@ -68037,6 +68182,25 @@ var InputPanel = class extends i {
|
|
|
68037
68182
|
}));
|
|
68038
68183
|
this.requestUpdate();
|
|
68039
68184
|
}
|
|
68185
|
+
_stopToolbarControlPointer(e) {
|
|
68186
|
+
e.stopPropagation();
|
|
68187
|
+
e.preventDefault();
|
|
68188
|
+
}
|
|
68189
|
+
_stopToolbarControlEvent(e) {
|
|
68190
|
+
e.stopPropagation();
|
|
68191
|
+
}
|
|
68192
|
+
_switchTabFromToolbar(e, tab) {
|
|
68193
|
+
this._stopToolbarControlEvent(e);
|
|
68194
|
+
this._switchTab(tab);
|
|
68195
|
+
}
|
|
68196
|
+
_toggleLayoutFromToolbar(e) {
|
|
68197
|
+
this._stopToolbarControlEvent(e);
|
|
68198
|
+
this._toggleLayout();
|
|
68199
|
+
}
|
|
68200
|
+
_closeFromToolbar(e) {
|
|
68201
|
+
this._stopToolbarControlEvent(e);
|
|
68202
|
+
this._close();
|
|
68203
|
+
}
|
|
68040
68204
|
_toggleLayout() {
|
|
68041
68205
|
this.layout = this.layout === "fixed" ? "floating" : "fixed";
|
|
68042
68206
|
if (this.layout === "fixed") this._closeFloatingDialog();
|
|
@@ -68273,17 +68437,32 @@ var InputPanel = class extends i {
|
|
|
68273
68437
|
class="tab-btn"
|
|
68274
68438
|
part="tab-btn"
|
|
68275
68439
|
?data-active=${this.activeTab === t.id}
|
|
68276
|
-
@
|
|
68440
|
+
@pointerdown=${(e) => this._stopToolbarControlPointer(e)}
|
|
68441
|
+
@mousedown=${(e) => this._stopToolbarControlPointer(e)}
|
|
68442
|
+
@click=${(e) => this._switchTabFromToolbar(e, t.id)}
|
|
68277
68443
|
>
|
|
68278
68444
|
${t.icon} ${this.activeTab === t.id ? t.label : ""}
|
|
68279
68445
|
</button>
|
|
68280
68446
|
`)}
|
|
68281
68447
|
</div>
|
|
68282
68448
|
<div class="action-group">
|
|
68283
|
-
<button
|
|
68449
|
+
<button
|
|
68450
|
+
class="icon-btn"
|
|
68451
|
+
@pointerdown=${(e) => this._stopToolbarControlPointer(e)}
|
|
68452
|
+
@mousedown=${(e) => this._stopToolbarControlPointer(e)}
|
|
68453
|
+
@click=${(e) => this._toggleLayoutFromToolbar(e)}
|
|
68454
|
+
title="Toggle layout mode"
|
|
68455
|
+
>
|
|
68284
68456
|
${this.layout === "fixed" ? iconPin(14) : iconPinOff(14)}
|
|
68285
68457
|
</button>
|
|
68286
|
-
<button
|
|
68458
|
+
<button
|
|
68459
|
+
class="icon-btn"
|
|
68460
|
+
part="close-btn"
|
|
68461
|
+
@pointerdown=${(e) => this._stopToolbarControlPointer(e)}
|
|
68462
|
+
@mousedown=${(e) => this._stopToolbarControlPointer(e)}
|
|
68463
|
+
@click=${(e) => this._closeFromToolbar(e)}
|
|
68464
|
+
title="Close panel"
|
|
68465
|
+
>
|
|
68287
68466
|
${iconX(14)}
|
|
68288
68467
|
</button>
|
|
68289
68468
|
</div>
|
|
@@ -90823,30 +91002,12 @@ var ShortcutTab = class extends i {
|
|
|
90823
91002
|
composed: true
|
|
90824
91003
|
}));
|
|
90825
91004
|
}
|
|
90826
|
-
|
|
90827
|
-
|
|
90828
|
-
|
|
90829
|
-
|
|
90830
|
-
|
|
90831
|
-
|
|
90832
|
-
} catch {
|
|
90833
|
-
document.execCommand("copy");
|
|
90834
|
-
}
|
|
90835
|
-
return;
|
|
90836
|
-
}
|
|
90837
|
-
if (command === "paste") {
|
|
90838
|
-
try {
|
|
90839
|
-
const text = await navigator.clipboard.readText();
|
|
90840
|
-
if (text) this._send(text);
|
|
90841
|
-
} catch {}
|
|
90842
|
-
return;
|
|
90843
|
-
}
|
|
90844
|
-
const active = document.activeElement;
|
|
90845
|
-
if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement) {
|
|
90846
|
-
active.select();
|
|
90847
|
-
return;
|
|
90848
|
-
}
|
|
90849
|
-
document.execCommand("selectAll");
|
|
91005
|
+
_handleCommand(command) {
|
|
91006
|
+
this.dispatchEvent(new CustomEvent("input-panel:command", {
|
|
91007
|
+
detail: { command },
|
|
91008
|
+
bubbles: true,
|
|
91009
|
+
composed: true
|
|
91010
|
+
}));
|
|
90850
91011
|
}
|
|
90851
91012
|
_dpadData(event, width, height, container) {
|
|
90852
91013
|
const local = container.toLocal(event.global);
|
|
@@ -90856,7 +91017,7 @@ var ShortcutTab = class extends i {
|
|
|
90856
91017
|
if (Math.abs(dx) > Math.abs(dy)) return dx < 0 ? "\x1B[D" : "\x1B[C";
|
|
90857
91018
|
return dy < 0 ? "\x1B[A" : "\x1B[B";
|
|
90858
91019
|
}
|
|
90859
|
-
|
|
91020
|
+
_activateShortcut(item, event, width, height, container) {
|
|
90860
91021
|
if (item.kind === "dpad") {
|
|
90861
91022
|
this._send(this._dpadData(event, width, height, container));
|
|
90862
91023
|
return;
|
|
@@ -90871,7 +91032,7 @@ var ShortcutTab = class extends i {
|
|
|
90871
91032
|
this._send(action.text);
|
|
90872
91033
|
return;
|
|
90873
91034
|
}
|
|
90874
|
-
|
|
91035
|
+
this._handleCommand(action.command);
|
|
90875
91036
|
}
|
|
90876
91037
|
_setActivePage(pageId) {
|
|
90877
91038
|
if (this.activePageId === pageId) return;
|
|
@@ -91420,8 +91581,11 @@ var VirtualKeyboardTab = class extends i {
|
|
|
91420
91581
|
this._activeKey = null;
|
|
91421
91582
|
this._activePointerId = null;
|
|
91422
91583
|
}
|
|
91584
|
+
_hostPlatform() {
|
|
91585
|
+
return this.platform === "windows" || this.platform === "macos" || this.platform === "common" ? this.platform : detectHostPlatform();
|
|
91586
|
+
}
|
|
91423
91587
|
getRows() {
|
|
91424
|
-
return LAYOUTS[this.
|
|
91588
|
+
return LAYOUTS[this._hostPlatform()];
|
|
91425
91589
|
}
|
|
91426
91590
|
async _initPixi() {
|
|
91427
91591
|
const host = this.shadowRoot?.querySelector(".pixi-host");
|
|
@@ -91767,14 +91931,44 @@ var VirtualKeyboardTab = class extends i {
|
|
|
91767
91931
|
if (this._isShifted(def, forceShift) && def.shift) return def.shift.data;
|
|
91768
91932
|
return def.data;
|
|
91769
91933
|
}
|
|
91770
|
-
|
|
91934
|
+
_resolveTerminalData(def, forceShift) {
|
|
91771
91935
|
let data = this._resolveOutputData(def, forceShift);
|
|
91772
|
-
if (!data) return;
|
|
91936
|
+
if (!data) return "";
|
|
91773
91937
|
if (this._modifiers.ctrl && data.length === 1) {
|
|
91774
91938
|
const code = data.toUpperCase().charCodeAt(0) - 64;
|
|
91775
91939
|
if (code > 0 && code < 32) data = String.fromCharCode(code);
|
|
91776
91940
|
}
|
|
91777
91941
|
if (this._modifiers.alt || this._modifiers.meta) data = `\x1b${data}`;
|
|
91942
|
+
return data;
|
|
91943
|
+
}
|
|
91944
|
+
_resolvePrimaryCommand(def) {
|
|
91945
|
+
if (this._modifiers.alt || this._modifiers.shift) return null;
|
|
91946
|
+
if (!(this._hostPlatform() === "macos" ? this._modifiers.meta && !this._modifiers.ctrl : this._modifiers.ctrl && !this._modifiers.meta)) return null;
|
|
91947
|
+
const key = def.data.toLowerCase();
|
|
91948
|
+
if (key === "c") return "copy";
|
|
91949
|
+
if (key === "v") return "paste";
|
|
91950
|
+
if (key === "a") return "select-all";
|
|
91951
|
+
return null;
|
|
91952
|
+
}
|
|
91953
|
+
_sendCommand(command, fallbackData) {
|
|
91954
|
+
this.dispatchEvent(new CustomEvent("input-panel:command", {
|
|
91955
|
+
detail: {
|
|
91956
|
+
command,
|
|
91957
|
+
fallbackData
|
|
91958
|
+
},
|
|
91959
|
+
bubbles: true,
|
|
91960
|
+
composed: true
|
|
91961
|
+
}));
|
|
91962
|
+
}
|
|
91963
|
+
_sendKey(def, forceShift) {
|
|
91964
|
+
const data = this._resolveTerminalData(def, forceShift);
|
|
91965
|
+
if (!data) return;
|
|
91966
|
+
const command = this._resolvePrimaryCommand(def);
|
|
91967
|
+
if (command) {
|
|
91968
|
+
const fallbackData = this._hostPlatform() === "macos" ? void 0 : data;
|
|
91969
|
+
this._sendCommand(command, fallbackData);
|
|
91970
|
+
return;
|
|
91971
|
+
}
|
|
91778
91972
|
this.dispatchEvent(new CustomEvent("input-panel:send", {
|
|
91779
91973
|
detail: { data },
|
|
91780
91974
|
bubbles: true,
|
|
@@ -92302,9 +92496,27 @@ var EDGE_SCROLL_OVERSHOOT = 15;
|
|
|
92302
92496
|
function isTouchDevice() {
|
|
92303
92497
|
return "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
92304
92498
|
}
|
|
92499
|
+
function isTerminalTouchMouseOverlay(element) {
|
|
92500
|
+
return element instanceof HTMLElement && element.classList.contains("terminal-touch-mouse-overlay");
|
|
92501
|
+
}
|
|
92502
|
+
function resolveTerminalPointerTarget(container, clientX, clientY) {
|
|
92503
|
+
let element = document.elementFromPoint(clientX, clientY);
|
|
92504
|
+
if (element && isTerminalTouchMouseOverlay(element)) {
|
|
92505
|
+
const overlayElement = element;
|
|
92506
|
+
const previousPointerEvents = overlayElement.style.pointerEvents;
|
|
92507
|
+
overlayElement.style.pointerEvents = "none";
|
|
92508
|
+
element = document.elementFromPoint(clientX, clientY);
|
|
92509
|
+
overlayElement.style.pointerEvents = previousPointerEvents;
|
|
92510
|
+
}
|
|
92511
|
+
if (element && container.contains(element) && !isTerminalTouchMouseOverlay(element)) return element;
|
|
92512
|
+
return container.querySelector(".xterm-screen") ?? container;
|
|
92513
|
+
}
|
|
92305
92514
|
function isInputPanelTab(value) {
|
|
92306
92515
|
return value === "input" || value === "keys" || value === "shortcuts" || value === "trackpad" || value === "settings";
|
|
92307
92516
|
}
|
|
92517
|
+
function isInputPanelCommand(value) {
|
|
92518
|
+
return value === "copy" || value === "paste" || value === "select-all";
|
|
92519
|
+
}
|
|
92308
92520
|
function isRecord$1(value) {
|
|
92309
92521
|
return typeof value === "object" && value !== null;
|
|
92310
92522
|
}
|
|
@@ -92551,6 +92763,7 @@ var InputPanelAddon = class InputPanelAddon {
|
|
|
92551
92763
|
_persistentCleanups = [];
|
|
92552
92764
|
_listenersAttached = false;
|
|
92553
92765
|
_onInput;
|
|
92766
|
+
_onCommand;
|
|
92554
92767
|
_onOpenCb;
|
|
92555
92768
|
_onCloseCb;
|
|
92556
92769
|
_getHistory;
|
|
@@ -92566,6 +92779,7 @@ var InputPanelAddon = class InputPanelAddon {
|
|
|
92566
92779
|
_hasOwnPersistedState;
|
|
92567
92780
|
constructor(opts) {
|
|
92568
92781
|
this._onInput = opts?.onInput ?? (() => {});
|
|
92782
|
+
this._onCommand = opts?.onCommand ?? null;
|
|
92569
92783
|
this._onOpenCb = opts?.onOpen ?? null;
|
|
92570
92784
|
this._onCloseCb = opts?.onClose ?? null;
|
|
92571
92785
|
this._getHistory = opts?.getHistory ?? null;
|
|
@@ -92601,6 +92815,9 @@ var InputPanelAddon = class InputPanelAddon {
|
|
|
92601
92815
|
set onInput(fn) {
|
|
92602
92816
|
this._onInput = fn;
|
|
92603
92817
|
}
|
|
92818
|
+
set onCommand(fn) {
|
|
92819
|
+
this._onCommand = fn;
|
|
92820
|
+
}
|
|
92604
92821
|
setPlatform(platform) {
|
|
92605
92822
|
this._platform = platform;
|
|
92606
92823
|
this._applyPlatformToPanel();
|
|
@@ -92757,6 +92974,18 @@ var InputPanelAddon = class InputPanelAddon {
|
|
|
92757
92974
|
}).catch(() => {});
|
|
92758
92975
|
}
|
|
92759
92976
|
});
|
|
92977
|
+
this._on(panel, "input-panel:command", (e) => {
|
|
92978
|
+
const detail = e.detail;
|
|
92979
|
+
if (!isRecord$1(detail)) return;
|
|
92980
|
+
const command = detail.command;
|
|
92981
|
+
if (!isInputPanelCommand(command)) return;
|
|
92982
|
+
const fallbackData = typeof detail.fallbackData === "string" ? detail.fallbackData : void 0;
|
|
92983
|
+
Promise.resolve(this._onCommand?.(command, { fallbackData }) ?? false).then((handled) => {
|
|
92984
|
+
if (!handled && fallbackData) this._onInput(fallbackData);
|
|
92985
|
+
}).catch(() => {
|
|
92986
|
+
if (fallbackData) this._onInput(fallbackData);
|
|
92987
|
+
});
|
|
92988
|
+
});
|
|
92760
92989
|
this._on(inputTab, "input-panel:input-change", (e) => {
|
|
92761
92990
|
const value = e.detail?.value;
|
|
92762
92991
|
if (typeof value === "string") {
|
|
@@ -92974,9 +93203,7 @@ var InputPanelAddon = class InputPanelAddon {
|
|
|
92974
93203
|
_resolveTarget(clientX, clientY) {
|
|
92975
93204
|
const container = this._getTerminalHostElement();
|
|
92976
93205
|
if (!container) return document.body;
|
|
92977
|
-
|
|
92978
|
-
if (el && container.contains(el)) return el;
|
|
92979
|
-
return container.querySelector(".xterm-screen") ?? container;
|
|
93206
|
+
return resolveTerminalPointerTarget(container, clientX, clientY);
|
|
92980
93207
|
}
|
|
92981
93208
|
_dispatchMouse(type, opts = {}) {
|
|
92982
93209
|
const coords = this._getClientCoords();
|
|
@@ -93131,6 +93358,55 @@ var InputPanelAddon = class InputPanelAddon {
|
|
|
93131
93358
|
}
|
|
93132
93359
|
};
|
|
93133
93360
|
//#endregion
|
|
93361
|
+
//#region src/lib/google-font-loader.ts
|
|
93362
|
+
function getPreferredGoogleFontsHosts(lang) {
|
|
93363
|
+
const useCnCdn = /^zh\b/i.test(lang);
|
|
93364
|
+
return {
|
|
93365
|
+
apiHost: useCnCdn ? "https://fonts.googleapis.cn" : "https://fonts.googleapis.com",
|
|
93366
|
+
staticHost: useCnCdn ? "https://fonts.gstatic.cn" : "https://fonts.gstatic.com"
|
|
93367
|
+
};
|
|
93368
|
+
}
|
|
93369
|
+
function encodeGoogleFontFamily(family) {
|
|
93370
|
+
return family.trim().replace(/ /g, "+");
|
|
93371
|
+
}
|
|
93372
|
+
function buildGoogleFontsStylesheetHref(options) {
|
|
93373
|
+
const families = options.families.map(encodeGoogleFontFamily).filter(Boolean);
|
|
93374
|
+
const { apiHost } = getPreferredGoogleFontsHosts(options.lang ?? "");
|
|
93375
|
+
const familyParams = families.map((family) => `family=${family}`);
|
|
93376
|
+
const displayParam = `display=${options.display ?? "swap"}`;
|
|
93377
|
+
return `${apiHost}/css2?${[...familyParams, displayParam].join("&")}`;
|
|
93378
|
+
}
|
|
93379
|
+
/**
|
|
93380
|
+
* Legacy Google Fonts loader retained for optional large CJK/JCK font families.
|
|
93381
|
+
* The app shell uses local @fontsource assets by default.
|
|
93382
|
+
*/
|
|
93383
|
+
function loadGoogleFontsStylesheet(options) {
|
|
93384
|
+
const documentRef = options.documentRef ?? (typeof document === "undefined" ? null : document);
|
|
93385
|
+
if (!documentRef || options.families.length === 0) return null;
|
|
93386
|
+
const lang = options.lang ?? (typeof navigator === "undefined" ? "" : navigator.languages && navigator.languages[0] || navigator.language || navigator.userLanguage || "");
|
|
93387
|
+
const hosts = getPreferredGoogleFontsHosts(lang);
|
|
93388
|
+
const href = buildGoogleFontsStylesheetHref({
|
|
93389
|
+
...options,
|
|
93390
|
+
lang
|
|
93391
|
+
});
|
|
93392
|
+
if (documentRef.head.querySelector(`link[href="${href}"]`)) return null;
|
|
93393
|
+
const preconnectApi = documentRef.createElement("link");
|
|
93394
|
+
preconnectApi.rel = "preconnect";
|
|
93395
|
+
preconnectApi.href = hosts.apiHost;
|
|
93396
|
+
preconnectApi.dataset.openspecGoogleFonts = "preconnect-api";
|
|
93397
|
+
const preconnectStatic = documentRef.createElement("link");
|
|
93398
|
+
preconnectStatic.rel = "preconnect";
|
|
93399
|
+
preconnectStatic.href = hosts.staticHost;
|
|
93400
|
+
preconnectStatic.crossOrigin = "anonymous";
|
|
93401
|
+
preconnectStatic.dataset.openspecGoogleFonts = "preconnect-static";
|
|
93402
|
+
const stylesheet = documentRef.createElement("link");
|
|
93403
|
+
stylesheet.rel = "stylesheet";
|
|
93404
|
+
stylesheet.href = href;
|
|
93405
|
+
stylesheet.dataset.openspecGoogleFonts = "stylesheet";
|
|
93406
|
+
documentRef.head.append(preconnectApi, preconnectStatic, stylesheet);
|
|
93407
|
+
return stylesheet;
|
|
93408
|
+
}
|
|
93409
|
+
//#endregion
|
|
93134
93410
|
//#region src/lib/user-gesture-audio-context.ts
|
|
93135
93411
|
var audioContext = null;
|
|
93136
93412
|
var audioContextPromise = null;
|
|
@@ -93534,6 +93810,146 @@ var TerminalInputHistoryStore = class {
|
|
|
93534
93810
|
}
|
|
93535
93811
|
};
|
|
93536
93812
|
//#endregion
|
|
93813
|
+
//#region src/lib/terminal-keybindings.ts
|
|
93814
|
+
function isKeydown(event) {
|
|
93815
|
+
return event.type === "keydown";
|
|
93816
|
+
}
|
|
93817
|
+
function keyEquals(event, key) {
|
|
93818
|
+
return event.key.toLowerCase() === key;
|
|
93819
|
+
}
|
|
93820
|
+
function hasPrimaryModifier(event) {
|
|
93821
|
+
return event.metaKey || event.ctrlKey;
|
|
93822
|
+
}
|
|
93823
|
+
function hasPlainPrimaryModifier(event) {
|
|
93824
|
+
return hasPrimaryModifier(event) && !event.altKey;
|
|
93825
|
+
}
|
|
93826
|
+
function resolveClipboard(context) {
|
|
93827
|
+
if (context.clipboard) return context.clipboard;
|
|
93828
|
+
if (typeof navigator === "undefined") return null;
|
|
93829
|
+
return navigator.clipboard ?? null;
|
|
93830
|
+
}
|
|
93831
|
+
function runAsync(task, context) {
|
|
93832
|
+
task.catch((error) => {
|
|
93833
|
+
context.onAsyncError?.(error);
|
|
93834
|
+
});
|
|
93835
|
+
}
|
|
93836
|
+
async function copySelection(context, selection) {
|
|
93837
|
+
const clipboard = resolveClipboard(context);
|
|
93838
|
+
if (!clipboard?.writeText) return;
|
|
93839
|
+
await clipboard.writeText(selection);
|
|
93840
|
+
}
|
|
93841
|
+
async function pasteClipboard(context) {
|
|
93842
|
+
const clipboard = resolveClipboard(context);
|
|
93843
|
+
if (!clipboard?.readText) return;
|
|
93844
|
+
const text = await clipboard.readText();
|
|
93845
|
+
if (!text) return;
|
|
93846
|
+
try {
|
|
93847
|
+
context.terminal.paste?.(text);
|
|
93848
|
+
if (context.terminal.paste) return;
|
|
93849
|
+
} catch {}
|
|
93850
|
+
context.writeInput(text);
|
|
93851
|
+
}
|
|
93852
|
+
var defaultTerminalKeybindings = [
|
|
93853
|
+
{
|
|
93854
|
+
id: "terminal.copy-selection",
|
|
93855
|
+
handle: (event, context) => {
|
|
93856
|
+
if (!isKeydown(event) || !hasPlainPrimaryModifier(event) || !keyEquals(event, "c")) return null;
|
|
93857
|
+
if (!context.terminal.hasSelection?.()) return "allow";
|
|
93858
|
+
return copySelectionCommand(context);
|
|
93859
|
+
}
|
|
93860
|
+
},
|
|
93861
|
+
{
|
|
93862
|
+
id: "terminal.paste-clipboard",
|
|
93863
|
+
handle: (event, context) => {
|
|
93864
|
+
if (!isKeydown(event) || !hasPlainPrimaryModifier(event) || !keyEquals(event, "v")) return null;
|
|
93865
|
+
return pasteClipboardCommand(context);
|
|
93866
|
+
}
|
|
93867
|
+
},
|
|
93868
|
+
{
|
|
93869
|
+
id: "terminal.select-all",
|
|
93870
|
+
handle: (event, context) => {
|
|
93871
|
+
if (!isKeydown(event) || !event.metaKey || event.ctrlKey || event.altKey) return null;
|
|
93872
|
+
if (!keyEquals(event, "a")) return null;
|
|
93873
|
+
return selectAllCommand(context);
|
|
93874
|
+
}
|
|
93875
|
+
},
|
|
93876
|
+
{
|
|
93877
|
+
id: "terminal.zoom-in",
|
|
93878
|
+
handle: (event, context) => {
|
|
93879
|
+
if (!isKeydown(event) || !hasPrimaryModifier(event)) return null;
|
|
93880
|
+
if (event.key !== "=" && event.key !== "+") return null;
|
|
93881
|
+
context.zoomFont(1);
|
|
93882
|
+
return "block";
|
|
93883
|
+
}
|
|
93884
|
+
},
|
|
93885
|
+
{
|
|
93886
|
+
id: "terminal.zoom-out",
|
|
93887
|
+
handle: (event, context) => {
|
|
93888
|
+
if (!isKeydown(event) || !hasPrimaryModifier(event) || event.key !== "-") return null;
|
|
93889
|
+
context.zoomFont(-1);
|
|
93890
|
+
return "block";
|
|
93891
|
+
}
|
|
93892
|
+
},
|
|
93893
|
+
{
|
|
93894
|
+
id: "terminal.zoom-reset",
|
|
93895
|
+
handle: (event, context) => {
|
|
93896
|
+
if (!isKeydown(event) || !hasPrimaryModifier(event) || event.key !== "0") return null;
|
|
93897
|
+
context.resetFontSize();
|
|
93898
|
+
return "block";
|
|
93899
|
+
}
|
|
93900
|
+
}
|
|
93901
|
+
];
|
|
93902
|
+
function copySelectionCommand(context) {
|
|
93903
|
+
if (!context.terminal.hasSelection?.()) return "allow";
|
|
93904
|
+
const selection = context.terminal.getSelection?.() ?? "";
|
|
93905
|
+
if (!selection) return "allow";
|
|
93906
|
+
runAsync(copySelection(context, selection), context);
|
|
93907
|
+
return "block";
|
|
93908
|
+
}
|
|
93909
|
+
function pasteClipboardCommand(context) {
|
|
93910
|
+
if (!resolveClipboard(context)?.readText) return "allow";
|
|
93911
|
+
runAsync(pasteClipboard(context), context);
|
|
93912
|
+
return "block";
|
|
93913
|
+
}
|
|
93914
|
+
function selectAllCommand(context) {
|
|
93915
|
+
if (!context.terminal.selectAll) return "allow";
|
|
93916
|
+
context.terminal.selectAll();
|
|
93917
|
+
return "block";
|
|
93918
|
+
}
|
|
93919
|
+
var defaultTerminalCommandBindings = [
|
|
93920
|
+
{
|
|
93921
|
+
id: "terminal.command.copy-selection",
|
|
93922
|
+
command: "copy",
|
|
93923
|
+
run: copySelectionCommand
|
|
93924
|
+
},
|
|
93925
|
+
{
|
|
93926
|
+
id: "terminal.command.paste-clipboard",
|
|
93927
|
+
command: "paste",
|
|
93928
|
+
run: pasteClipboardCommand
|
|
93929
|
+
},
|
|
93930
|
+
{
|
|
93931
|
+
id: "terminal.command.select-all",
|
|
93932
|
+
command: "select-all",
|
|
93933
|
+
run: selectAllCommand
|
|
93934
|
+
}
|
|
93935
|
+
];
|
|
93936
|
+
var TerminalKeybindingRegistry = class {
|
|
93937
|
+
constructor(bindings = defaultTerminalKeybindings, commandBindings = defaultTerminalCommandBindings) {
|
|
93938
|
+
this.bindings = bindings;
|
|
93939
|
+
this.commandBindings = commandBindings;
|
|
93940
|
+
}
|
|
93941
|
+
handleKeyEvent(event, context) {
|
|
93942
|
+
for (const binding of this.bindings) {
|
|
93943
|
+
const result = binding.handle(event, context);
|
|
93944
|
+
if (result) return result;
|
|
93945
|
+
}
|
|
93946
|
+
return "allow";
|
|
93947
|
+
}
|
|
93948
|
+
runCommand(command, context) {
|
|
93949
|
+
return this.commandBindings.find((item) => item.command === command)?.run(context) ?? "allow";
|
|
93950
|
+
}
|
|
93951
|
+
};
|
|
93952
|
+
//#endregion
|
|
93537
93953
|
//#region src/lib/terminal-theme.ts
|
|
93538
93954
|
var TERMINAL_THEME_REGISTRY = {
|
|
93539
93955
|
"default-light": {
|
|
@@ -93723,7 +94139,7 @@ function resolveTerminalTheme(input) {
|
|
|
93723
94139
|
}
|
|
93724
94140
|
//#endregion
|
|
93725
94141
|
//#region src/lib/terminal-controller.ts
|
|
93726
|
-
var DEFAULT_FONT_FAMILY = "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace";
|
|
94142
|
+
var DEFAULT_FONT_FAMILY = "\"JetBrains Mono Variable\", \"JetBrains Mono\", ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace";
|
|
93727
94143
|
var DEFAULT_TERMINAL_CONFIG = {
|
|
93728
94144
|
fontSize: 13,
|
|
93729
94145
|
fontFamily: "",
|
|
@@ -93772,6 +94188,10 @@ var GOOGLE_FONT_PRESETS = [
|
|
|
93772
94188
|
"Ubuntu Mono",
|
|
93773
94189
|
"Space Mono"
|
|
93774
94190
|
];
|
|
94191
|
+
var LOCAL_FONT_FAMILY_ALIASES = {
|
|
94192
|
+
"JetBrains Mono": "\"JetBrains Mono Variable\"",
|
|
94193
|
+
"Share Tech Mono": "\"Share Tech Mono\""
|
|
94194
|
+
};
|
|
93775
94195
|
/** Already-injected font sources, used for deduplication */
|
|
93776
94196
|
var loadedFontSources = /* @__PURE__ */ new Set();
|
|
93777
94197
|
/** Extract a font name from a URL pathname (strip extension, replace dashes with spaces) */
|
|
@@ -93820,13 +94240,8 @@ async function loadFontSource(source) {
|
|
|
93820
94240
|
function loadGoogleFont(fontName) {
|
|
93821
94241
|
const key = `google:${fontName}`;
|
|
93822
94242
|
if (loadedFontSources.has(key)) return;
|
|
93823
|
-
const
|
|
93824
|
-
|
|
93825
|
-
const link = document.createElement("link");
|
|
93826
|
-
link.rel = "stylesheet";
|
|
93827
|
-
link.href = `${apiHost}/css2?family=${fontName.replace(/ /g, "+")}&display=swap`;
|
|
93828
|
-
link.dataset.fontSrc = key;
|
|
93829
|
-
document.head.appendChild(link);
|
|
94243
|
+
const link = loadGoogleFontsStylesheet({ families: [fontName] });
|
|
94244
|
+
if (link) link.dataset.fontSrc = key;
|
|
93830
94245
|
loadedFontSources.add(key);
|
|
93831
94246
|
}
|
|
93832
94247
|
var TerminalController = class {
|
|
@@ -93838,6 +94253,7 @@ var TerminalController = class {
|
|
|
93838
94253
|
snapshotCache = null;
|
|
93839
94254
|
inputHistoryStore = new TerminalInputHistoryStore();
|
|
93840
94255
|
bellSoundEngine = new TerminalBellSoundEngine();
|
|
94256
|
+
keybindings = new TerminalKeybindingRegistry();
|
|
93841
94257
|
ghosttyModule = null;
|
|
93842
94258
|
ghosttyInitPromise = null;
|
|
93843
94259
|
appDarkMode = false;
|
|
@@ -94012,6 +94428,7 @@ var TerminalController = class {
|
|
|
94012
94428
|
createInputPanelAddon(sessionId, platform) {
|
|
94013
94429
|
return new InputPanelAddon({
|
|
94014
94430
|
onInput: (data) => this.writeToSession(sessionId, data),
|
|
94431
|
+
onCommand: (command) => this.runInputPanelCommand(sessionId, command),
|
|
94015
94432
|
getHistory: async () => this.inputHistoryStore.list(),
|
|
94016
94433
|
addHistory: async (text) => this.inputHistoryStore.add(text),
|
|
94017
94434
|
subscribeHistory: (listener) => this.inputHistoryStore.subscribe(listener),
|
|
@@ -94024,6 +94441,17 @@ var TerminalController = class {
|
|
|
94024
94441
|
}
|
|
94025
94442
|
});
|
|
94026
94443
|
}
|
|
94444
|
+
runInputPanelCommand(sessionId, command) {
|
|
94445
|
+
const instance = this.instances.get(sessionId);
|
|
94446
|
+
if (!instance) return false;
|
|
94447
|
+
return this.keybindings.runCommand(command, {
|
|
94448
|
+
terminal: instance.terminal,
|
|
94449
|
+
writeInput: (data) => this.writeToSession(sessionId, data),
|
|
94450
|
+
zoomFont: (delta) => this.zoomFont(delta),
|
|
94451
|
+
resetFontSize: () => this.resetFontSize(),
|
|
94452
|
+
onAsyncError: (error) => console.error("[terminal] input panel command failed:", error)
|
|
94453
|
+
}) === "block";
|
|
94454
|
+
}
|
|
94027
94455
|
applyGhosttyBackground(instance, container) {
|
|
94028
94456
|
if (instance.rendererEngine !== "ghostty") return;
|
|
94029
94457
|
const currentTheme = instance.terminal.options.theme ?? {};
|
|
@@ -94068,20 +94496,18 @@ var TerminalController = class {
|
|
|
94068
94496
|
}
|
|
94069
94497
|
const mod = event.metaKey || event.ctrlKey;
|
|
94070
94498
|
if (event.type !== "keydown" || !mod) return this.getKeyEventResult(engine, "allow");
|
|
94071
|
-
|
|
94072
|
-
|
|
94073
|
-
|
|
94074
|
-
|
|
94075
|
-
|
|
94076
|
-
|
|
94077
|
-
|
|
94078
|
-
|
|
94079
|
-
|
|
94080
|
-
|
|
94081
|
-
this.resetFontSize();
|
|
94082
|
-
handled = true;
|
|
94499
|
+
const keybindingResult = this.keybindings.handleKeyEvent(event, {
|
|
94500
|
+
terminal,
|
|
94501
|
+
writeInput,
|
|
94502
|
+
zoomFont: (delta) => this.zoomFont(delta),
|
|
94503
|
+
resetFontSize: () => this.resetFontSize(),
|
|
94504
|
+
onAsyncError: (error) => console.error("[terminal] keybinding failed:", error)
|
|
94505
|
+
});
|
|
94506
|
+
if (keybindingResult === "block") {
|
|
94507
|
+
event.preventDefault();
|
|
94508
|
+
event.stopPropagation();
|
|
94083
94509
|
}
|
|
94084
|
-
return this.getKeyEventResult(engine,
|
|
94510
|
+
return this.getKeyEventResult(engine, keybindingResult);
|
|
94085
94511
|
});
|
|
94086
94512
|
}
|
|
94087
94513
|
bindTerminalInput(instance) {
|
|
@@ -94359,12 +94785,16 @@ var TerminalController = class {
|
|
|
94359
94785
|
}
|
|
94360
94786
|
const entries = raw.split(/[,]+/).map((s) => s.trim()).filter(Boolean);
|
|
94361
94787
|
const resolved = [];
|
|
94362
|
-
for (const entry of entries)
|
|
94363
|
-
|
|
94364
|
-
resolved.push(
|
|
94365
|
-
|
|
94366
|
-
|
|
94367
|
-
|
|
94788
|
+
for (const entry of entries) {
|
|
94789
|
+
const localFontFamily = LOCAL_FONT_FAMILY_ALIASES[entry];
|
|
94790
|
+
if (localFontFamily) resolved.push(localFontFamily);
|
|
94791
|
+
else if (GOOGLE_FONT_PRESETS.includes(entry)) {
|
|
94792
|
+
loadGoogleFont(entry);
|
|
94793
|
+
resolved.push(entry);
|
|
94794
|
+
} else {
|
|
94795
|
+
const name = await loadFontSource(entry);
|
|
94796
|
+
if (name) resolved.push(name);
|
|
94797
|
+
}
|
|
94368
94798
|
}
|
|
94369
94799
|
resolved.push(DEFAULT_FONT_FAMILY);
|
|
94370
94800
|
this._setFontFamily(resolved.join(", "));
|
|
@@ -95352,7 +95782,7 @@ function Dialog({ open, title, headerActions, onClose, onDismissRequest, onClose
|
|
|
95352
95782
|
className: `flex h-full w-full items-center justify-center px-4 py-4 ${contentClassName} ${contentShellClassName}`,
|
|
95353
95783
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
95354
95784
|
ref: panelRef,
|
|
95355
|
-
className:
|
|
95785
|
+
className: `@container/dialog bg-background text-foreground relative flex h-fit w-[calc(100%-0.5rem)] max-w-2xl flex-col overflow-hidden rounded-[var(--openspec-dialog-radius,0.75rem)] border shadow-xl ${borderClass} ${className}`,
|
|
95356
95786
|
style: { maxHeight },
|
|
95357
95787
|
children: [
|
|
95358
95788
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -114686,85 +115116,6 @@ function navigateHashAnchor(anchorElement, hash) {
|
|
|
114686
115116
|
return true;
|
|
114687
115117
|
}
|
|
114688
115118
|
//#endregion
|
|
114689
|
-
//#region src/lib/document-translation-session-state.ts
|
|
114690
|
-
var DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY = "openspecui:document-translation:mode";
|
|
114691
|
-
var DEFAULT_ACTIVATION = "source";
|
|
114692
|
-
var ACTIVATION_STORAGE_EVENT = "openspecui:document-translation-session-change";
|
|
114693
|
-
function isDocumentTranslationActivation(value) {
|
|
114694
|
-
return value === "source" || value === "translated";
|
|
114695
|
-
}
|
|
114696
|
-
function readDocumentTranslationActivation() {
|
|
114697
|
-
if (typeof window === "undefined") return DEFAULT_ACTIVATION;
|
|
114698
|
-
try {
|
|
114699
|
-
const value = window.sessionStorage.getItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY);
|
|
114700
|
-
return isDocumentTranslationActivation(value) ? value : DEFAULT_ACTIVATION;
|
|
114701
|
-
} catch {
|
|
114702
|
-
return DEFAULT_ACTIVATION;
|
|
114703
|
-
}
|
|
114704
|
-
}
|
|
114705
|
-
function writeDocumentTranslationActivation(value) {
|
|
114706
|
-
if (typeof window === "undefined") return;
|
|
114707
|
-
try {
|
|
114708
|
-
window.sessionStorage.setItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY, value);
|
|
114709
|
-
} catch {
|
|
114710
|
-
return;
|
|
114711
|
-
}
|
|
114712
|
-
window.dispatchEvent(new CustomEvent(ACTIVATION_STORAGE_EVENT, { detail: value }));
|
|
114713
|
-
}
|
|
114714
|
-
function useDocumentTranslationActivation() {
|
|
114715
|
-
const [activation, setActivationState] = (0, import_react.useState)(readDocumentTranslationActivation);
|
|
114716
|
-
(0, import_react.useEffect)(() => {
|
|
114717
|
-
const handleActivationChange = () => {
|
|
114718
|
-
setActivationState(readDocumentTranslationActivation());
|
|
114719
|
-
};
|
|
114720
|
-
window.addEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
|
|
114721
|
-
window.addEventListener("storage", handleActivationChange);
|
|
114722
|
-
return () => {
|
|
114723
|
-
window.removeEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
|
|
114724
|
-
window.removeEventListener("storage", handleActivationChange);
|
|
114725
|
-
};
|
|
114726
|
-
}, []);
|
|
114727
|
-
return {
|
|
114728
|
-
activation,
|
|
114729
|
-
setActivation: (0, import_react.useCallback)((value) => {
|
|
114730
|
-
writeDocumentTranslationActivation(value);
|
|
114731
|
-
setActivationState(value);
|
|
114732
|
-
}, [])
|
|
114733
|
-
};
|
|
114734
|
-
}
|
|
114735
|
-
//#endregion
|
|
114736
|
-
//#region src/lib/resolve-document-translation-config.ts
|
|
114737
|
-
function resolveDocumentTranslationConfig(translationConfig, globalSettings) {
|
|
114738
|
-
if (!translationConfig) return void 0;
|
|
114739
|
-
const local = translationConfig.engines?.local ?? {};
|
|
114740
|
-
const localCt2 = translationConfig.engines?.localCt2 ?? {};
|
|
114741
|
-
const openai = translationConfig.engines?.openai ?? {};
|
|
114742
|
-
const resolvedLocalModel = local.model ?? globalSettings?.translationEngines.local?.model;
|
|
114743
|
-
const resolvedLocalSelectedGroupId = local.selectedGroupId ?? globalSettings?.translationEngines.local?.selectedGroupId;
|
|
114744
|
-
const resolvedLocalCt2Model = localCt2.model ?? globalSettings?.translationEngines.localCt2?.model;
|
|
114745
|
-
const resolvedLocalCt2SelectedGroupId = localCt2.selectedGroupId ?? globalSettings?.translationEngines.localCt2?.selectedGroupId;
|
|
114746
|
-
const resolvedOpenAIModel = openai.model ?? globalSettings?.translationEngines.openai?.model;
|
|
114747
|
-
return {
|
|
114748
|
-
...translationConfig,
|
|
114749
|
-
engines: {
|
|
114750
|
-
local: {
|
|
114751
|
-
...local,
|
|
114752
|
-
...resolvedLocalModel ? { model: resolvedLocalModel } : {},
|
|
114753
|
-
...resolvedLocalSelectedGroupId ? { selectedGroupId: resolvedLocalSelectedGroupId } : {}
|
|
114754
|
-
},
|
|
114755
|
-
localCt2: {
|
|
114756
|
-
...localCt2,
|
|
114757
|
-
...resolvedLocalCt2Model ? { model: resolvedLocalCt2Model } : {},
|
|
114758
|
-
...resolvedLocalCt2SelectedGroupId ? { selectedGroupId: resolvedLocalCt2SelectedGroupId } : {}
|
|
114759
|
-
},
|
|
114760
|
-
openai: {
|
|
114761
|
-
...openai,
|
|
114762
|
-
...resolvedOpenAIModel ? { model: resolvedOpenAIModel } : {}
|
|
114763
|
-
}
|
|
114764
|
-
}
|
|
114765
|
-
};
|
|
114766
|
-
}
|
|
114767
|
-
//#endregion
|
|
114768
115119
|
//#region ../browser-translator/dist/index.mjs
|
|
114769
115120
|
async function scanBrowserTranslationSupportTable(options) {
|
|
114770
115121
|
const translator = (options.win ?? window).Translator;
|
|
@@ -114838,10 +115189,20 @@ var BrowserTranslatorFactory = class {
|
|
|
114838
115189
|
}), options.signal);
|
|
114839
115190
|
return {
|
|
114840
115191
|
async *batchTranslate(inputs, batchOptions) {
|
|
114841
|
-
for (const [index, input] of inputs.entries())
|
|
114842
|
-
|
|
114843
|
-
|
|
114844
|
-
|
|
115192
|
+
for (const [index, input] of inputs.entries()) {
|
|
115193
|
+
const controlled = await runControlledTranslationTask((signal) => native.translate(input, { signal }), batchOptions);
|
|
115194
|
+
if (controlled.ok) {
|
|
115195
|
+
yield {
|
|
115196
|
+
index,
|
|
115197
|
+
output: controlled.value
|
|
115198
|
+
};
|
|
115199
|
+
continue;
|
|
115200
|
+
}
|
|
115201
|
+
yield {
|
|
115202
|
+
index,
|
|
115203
|
+
error: controlled.error
|
|
115204
|
+
};
|
|
115205
|
+
}
|
|
114845
115206
|
},
|
|
114846
115207
|
destroy() {
|
|
114847
115208
|
native.destroy?.();
|
|
@@ -136508,6 +136869,23 @@ buildSearchIndex(SUPPORTED_TRANSLATION_LANGUAGES.map((language) => ({
|
|
|
136508
136869
|
//#endregion
|
|
136509
136870
|
//#region src/lib/browser-translation.ts
|
|
136510
136871
|
var browserSupportTableCache = /* @__PURE__ */ new Map();
|
|
136872
|
+
function isFiniteTranslationOffset(value) {
|
|
136873
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
136874
|
+
}
|
|
136875
|
+
function isTranslationSegmentKind(value) {
|
|
136876
|
+
return value === "heading" || value === "listItem" || value === "paragraph" || value === "blockquote" || value === "text";
|
|
136877
|
+
}
|
|
136878
|
+
function isRenderableTranslationSegment(segment) {
|
|
136879
|
+
if (typeof segment !== "object" || segment === null || Array.isArray(segment)) return false;
|
|
136880
|
+
const id = Reflect.get(segment, "id");
|
|
136881
|
+
const sourceStartOffset = Reflect.get(segment, "sourceStartOffset");
|
|
136882
|
+
const sourceEndOffset = Reflect.get(segment, "sourceEndOffset");
|
|
136883
|
+
const sourceKind = Reflect.get(segment, "sourceKind");
|
|
136884
|
+
const source = Reflect.get(segment, "source");
|
|
136885
|
+
const translatorInput = Reflect.get(segment, "translatorInput");
|
|
136886
|
+
const kind = Reflect.get(segment, "kind");
|
|
136887
|
+
return typeof id === "string" && isFiniteTranslationOffset(sourceStartOffset) && isFiniteTranslationOffset(sourceEndOffset) && typeof sourceKind === "string" && typeof source === "string" && typeof translatorInput === "string" && isTranslationSegmentKind(kind);
|
|
136888
|
+
}
|
|
136511
136889
|
function createBrowserTranslationExecution() {
|
|
136512
136890
|
return {
|
|
136513
136891
|
factory: createBrowserTranslatorFactory(),
|
|
@@ -136834,13 +137212,14 @@ async function translateMarkdownDocumentProgressively(args, onPatch) {
|
|
|
136834
137212
|
sourceLanguage,
|
|
136835
137213
|
targetLanguage: args.targetLanguage,
|
|
136836
137214
|
signal: args.signal,
|
|
137215
|
+
timeoutMs: args.timeoutMs,
|
|
136837
137216
|
cache: args.cache,
|
|
136838
137217
|
jobs,
|
|
136839
137218
|
translatedSegments,
|
|
136840
137219
|
onPatch
|
|
136841
137220
|
})));
|
|
136842
137221
|
return {
|
|
136843
|
-
segments: translatedSegments,
|
|
137222
|
+
segments: normalizeTranslationSegments(translatedSegments),
|
|
136844
137223
|
displayMode: args.displayMode,
|
|
136845
137224
|
sourceLanguage: languageDetection.documentLanguage,
|
|
136846
137225
|
targetLanguage: args.targetLanguage
|
|
@@ -136919,9 +137298,25 @@ async function translatePendingJobsBySourceLanguage(input) {
|
|
|
136919
137298
|
startWorkersToDesired();
|
|
136920
137299
|
}
|
|
136921
137300
|
};
|
|
136922
|
-
const applyBatchResult = async (batch,
|
|
137301
|
+
const applyBatchResult = async (batch, result) => {
|
|
136923
137302
|
for (const [offset, job] of batch.jobs.entries()) {
|
|
136924
|
-
const
|
|
137303
|
+
const error = result.errors.get(offset);
|
|
137304
|
+
if (error) {
|
|
137305
|
+
const failedSegment = {
|
|
137306
|
+
...job.segment,
|
|
137307
|
+
sourceLanguage: job.sourceLanguage,
|
|
137308
|
+
targetLanguage: input.targetLanguage,
|
|
137309
|
+
status: "error",
|
|
137310
|
+
error
|
|
137311
|
+
};
|
|
137312
|
+
input.translatedSegments[job.segmentIndex] = failedSegment;
|
|
137313
|
+
input.onPatch({
|
|
137314
|
+
segmentIndex: job.segmentIndex,
|
|
137315
|
+
segment: failedSegment
|
|
137316
|
+
});
|
|
137317
|
+
continue;
|
|
137318
|
+
}
|
|
137319
|
+
const target = result.outputs.get(offset) ?? "";
|
|
136925
137320
|
const restoredTarget = job.segment.placeholderProtocol ? restoreTranslatedPlaceholderFragment(target, job.segment.placeholderProtocol) : { target: job.protectedInput.restore(target).trim() };
|
|
136926
137321
|
const translatedSegment = {
|
|
136927
137322
|
...job.segment,
|
|
@@ -136960,7 +137355,10 @@ async function translatePendingJobsBySourceLanguage(input) {
|
|
|
136960
137355
|
const batch = batches[batchIndex];
|
|
136961
137356
|
const startedAt = getCurrentTimeMs();
|
|
136962
137357
|
try {
|
|
136963
|
-
await applyBatchResult(batch, await collectBatchTranslationOutputs(translator.batchTranslate(batch.jobs.map((job) => job.protectedInput.text), {
|
|
137358
|
+
await applyBatchResult(batch, await collectBatchTranslationOutputs(translator.batchTranslate(batch.jobs.map((job) => job.protectedInput.text), {
|
|
137359
|
+
signal: input.signal,
|
|
137360
|
+
timeoutMs: input.timeoutMs ?? 15e3
|
|
137361
|
+
}), batch.jobs.length));
|
|
136964
137362
|
completedBatches += 1;
|
|
136965
137363
|
const elapsedMs = Math.max(1, getCurrentTimeMs() - startedAt);
|
|
136966
137364
|
appendTranslationAdaptiveConcurrencyLog({
|
|
@@ -137000,8 +137398,85 @@ async function translatePendingJobsBySourceLanguage(input) {
|
|
|
137000
137398
|
startWorkersToDesired();
|
|
137001
137399
|
while (workerPromises.size > 0) await Promise.race(workerPromises);
|
|
137002
137400
|
}
|
|
137401
|
+
async function retryTranslationSegment(input) {
|
|
137402
|
+
const engine = input.engine ?? createBrowserTranslationExecution();
|
|
137403
|
+
const sourceLanguage = input.sourceLanguage ?? input.segment.sourceLanguage ?? DEFAULT_SOURCE_LANGUAGE;
|
|
137404
|
+
if (areEquivalentTranslationLanguages(sourceLanguage, input.targetLanguage)) return {
|
|
137405
|
+
...input.segment,
|
|
137406
|
+
target: input.segment.source,
|
|
137407
|
+
sourceLanguage,
|
|
137408
|
+
targetLanguage: input.targetLanguage,
|
|
137409
|
+
status: "translated",
|
|
137410
|
+
error: void 0
|
|
137411
|
+
};
|
|
137412
|
+
const unsupportedLanguagePairMessage = getUnsupportedEngineLanguagePairMessage({
|
|
137413
|
+
engine,
|
|
137414
|
+
sourceLanguage,
|
|
137415
|
+
targetLanguage: input.targetLanguage
|
|
137416
|
+
});
|
|
137417
|
+
if (unsupportedLanguagePairMessage) return {
|
|
137418
|
+
...input.segment,
|
|
137419
|
+
sourceLanguage,
|
|
137420
|
+
targetLanguage: input.targetLanguage,
|
|
137421
|
+
status: "error",
|
|
137422
|
+
error: unsupportedLanguagePairMessage
|
|
137423
|
+
};
|
|
137424
|
+
const cacheKey = createSegmentCacheKey(input.segment, sourceLanguage, input.targetLanguage, engine.cacheIdentity);
|
|
137425
|
+
const cachedSegment = cacheKey ? await readCachedTranslationSegment(input.cache, cacheKey, input.segment, {
|
|
137426
|
+
sourceLanguage,
|
|
137427
|
+
targetLanguage: input.targetLanguage
|
|
137428
|
+
}) : null;
|
|
137429
|
+
if (cachedSegment) return cachedSegment;
|
|
137430
|
+
const protectedInput = input.segment.placeholderProtocol ? {
|
|
137431
|
+
text: input.segment.translatorInput,
|
|
137432
|
+
restore: (output) => output
|
|
137433
|
+
} : protectTranslatorInput(input.segment.translatorInput);
|
|
137434
|
+
let translator = null;
|
|
137435
|
+
try {
|
|
137436
|
+
translator = await engine.factory.create({
|
|
137437
|
+
sourceLanguage,
|
|
137438
|
+
targetLanguage: input.targetLanguage,
|
|
137439
|
+
signal: input.signal
|
|
137440
|
+
});
|
|
137441
|
+
const result = await collectBatchTranslationOutputs(translator.batchTranslate([protectedInput.text], {
|
|
137442
|
+
signal: input.signal,
|
|
137443
|
+
timeoutMs: input.timeoutMs ?? 15e3
|
|
137444
|
+
}), 1);
|
|
137445
|
+
const error = result.errors.get(0);
|
|
137446
|
+
if (error) return {
|
|
137447
|
+
...input.segment,
|
|
137448
|
+
sourceLanguage,
|
|
137449
|
+
targetLanguage: input.targetLanguage,
|
|
137450
|
+
status: "error",
|
|
137451
|
+
error
|
|
137452
|
+
};
|
|
137453
|
+
const target = result.outputs.get(0) ?? "";
|
|
137454
|
+
const restoredTarget = input.segment.placeholderProtocol ? restoreTranslatedPlaceholderFragment(target, input.segment.placeholderProtocol) : { target: protectedInput.restore(target).trim() };
|
|
137455
|
+
const translatedSegment = {
|
|
137456
|
+
...input.segment,
|
|
137457
|
+
...restoredTarget,
|
|
137458
|
+
sourceLanguage,
|
|
137459
|
+
targetLanguage: input.targetLanguage,
|
|
137460
|
+
status: "translated",
|
|
137461
|
+
error: void 0
|
|
137462
|
+
};
|
|
137463
|
+
if (cacheKey) writeCachedTranslationSegment(input.cache, cacheKey, translatedSegment);
|
|
137464
|
+
return translatedSegment;
|
|
137465
|
+
} catch (error) {
|
|
137466
|
+
if (input.signal.aborted) throw error;
|
|
137467
|
+
return {
|
|
137468
|
+
...input.segment,
|
|
137469
|
+
sourceLanguage,
|
|
137470
|
+
targetLanguage: input.targetLanguage,
|
|
137471
|
+
status: "error",
|
|
137472
|
+
error: getErrorMessage(error)
|
|
137473
|
+
};
|
|
137474
|
+
} finally {
|
|
137475
|
+
translator?.destroy?.();
|
|
137476
|
+
}
|
|
137477
|
+
}
|
|
137003
137478
|
function getUnsupportedEngineLanguagePairMessage(input) {
|
|
137004
|
-
if (!
|
|
137479
|
+
if (!isDirectionalManagedLocalTranslationEngineId(input.engine.cacheIdentity.engineId)) return null;
|
|
137005
137480
|
const directionCheck = checkLocalDirectionalModelLanguagePair({
|
|
137006
137481
|
model: input.engine.cacheIdentity.model,
|
|
137007
137482
|
sourceLanguage: input.sourceLanguage,
|
|
@@ -137010,6 +137485,9 @@ function getUnsupportedEngineLanguagePairMessage(input) {
|
|
|
137010
137485
|
if (directionCheck.supported) return null;
|
|
137011
137486
|
return directionCheck.message ?? "Selected local model does not support the detected translation direction.";
|
|
137012
137487
|
}
|
|
137488
|
+
function normalizeTranslationSegments(segments) {
|
|
137489
|
+
return segments.filter(isRenderableTranslationSegment);
|
|
137490
|
+
}
|
|
137013
137491
|
function summarizeTranslationLogThroughput(logs) {
|
|
137014
137492
|
if (logs.length === 0) return 0;
|
|
137015
137493
|
const totalTokens = logs.reduce((total, log) => total + log.estimatedTokens, 0);
|
|
@@ -137061,12 +137539,17 @@ function packTranslationJobs(jobs) {
|
|
|
137061
137539
|
}
|
|
137062
137540
|
async function collectBatchTranslationOutputs(stream, expectedCount) {
|
|
137063
137541
|
const outputs = /* @__PURE__ */ new Map();
|
|
137542
|
+
const errors = /* @__PURE__ */ new Map();
|
|
137064
137543
|
for await (const item of stream) {
|
|
137065
137544
|
if (item.index < 0 || item.index >= expectedCount) throw new Error(`Translator yielded output for unexpected index ${item.index}.`);
|
|
137066
|
-
if (!outputs.has(item.index)) outputs.set(item.index, item.output);
|
|
137545
|
+
if (item.output !== void 0 && !outputs.has(item.index)) outputs.set(item.index, item.output);
|
|
137546
|
+
if (item.error && !errors.has(item.index)) errors.set(item.index, item.error.message);
|
|
137067
137547
|
}
|
|
137068
|
-
if (outputs.size !== expectedCount) throw new Error(`Translator returned ${outputs.size}
|
|
137069
|
-
return
|
|
137548
|
+
if (outputs.size + errors.size !== expectedCount) throw new Error(`Translator returned ${outputs.size + errors.size} results for ${expectedCount} inputs.`);
|
|
137549
|
+
return {
|
|
137550
|
+
outputs,
|
|
137551
|
+
errors
|
|
137552
|
+
};
|
|
137070
137553
|
}
|
|
137071
137554
|
function estimateTranslationTokens(input) {
|
|
137072
137555
|
const trimmed = input.trim();
|
|
@@ -137562,6 +138045,104 @@ function getErrorMessage(error) {
|
|
|
137562
138045
|
return error instanceof Error ? error.message : "Unknown translation error.";
|
|
137563
138046
|
}
|
|
137564
138047
|
//#endregion
|
|
138048
|
+
//#region src/lib/document-translation-session-state.ts
|
|
138049
|
+
var DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY = "openspecui:document-translation:mode";
|
|
138050
|
+
var DEFAULT_ACTIVATION = "source";
|
|
138051
|
+
var ACTIVATION_STORAGE_EVENT = "openspecui:document-translation-session-change";
|
|
138052
|
+
function isDocumentTranslationActivation(value) {
|
|
138053
|
+
return value === "source" || value === "translated";
|
|
138054
|
+
}
|
|
138055
|
+
function readDocumentTranslationActivation() {
|
|
138056
|
+
if (typeof window === "undefined") return DEFAULT_ACTIVATION;
|
|
138057
|
+
try {
|
|
138058
|
+
const value = window.sessionStorage.getItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY);
|
|
138059
|
+
return isDocumentTranslationActivation(value) ? value : DEFAULT_ACTIVATION;
|
|
138060
|
+
} catch {
|
|
138061
|
+
return DEFAULT_ACTIVATION;
|
|
138062
|
+
}
|
|
138063
|
+
}
|
|
138064
|
+
function writeDocumentTranslationActivation(value) {
|
|
138065
|
+
if (typeof window === "undefined") return;
|
|
138066
|
+
try {
|
|
138067
|
+
window.sessionStorage.setItem(DOCUMENT_TRANSLATION_SESSION_STORAGE_KEY, value);
|
|
138068
|
+
} catch {
|
|
138069
|
+
return;
|
|
138070
|
+
}
|
|
138071
|
+
window.dispatchEvent(new CustomEvent(ACTIVATION_STORAGE_EVENT, { detail: value }));
|
|
138072
|
+
}
|
|
138073
|
+
function useDocumentTranslationActivation() {
|
|
138074
|
+
const [activation, setActivationState] = (0, import_react.useState)(readDocumentTranslationActivation);
|
|
138075
|
+
(0, import_react.useEffect)(() => {
|
|
138076
|
+
const handleActivationChange = () => {
|
|
138077
|
+
setActivationState(readDocumentTranslationActivation());
|
|
138078
|
+
};
|
|
138079
|
+
window.addEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
|
|
138080
|
+
window.addEventListener("storage", handleActivationChange);
|
|
138081
|
+
return () => {
|
|
138082
|
+
window.removeEventListener(ACTIVATION_STORAGE_EVENT, handleActivationChange);
|
|
138083
|
+
window.removeEventListener("storage", handleActivationChange);
|
|
138084
|
+
};
|
|
138085
|
+
}, []);
|
|
138086
|
+
return {
|
|
138087
|
+
activation,
|
|
138088
|
+
setActivation: (0, import_react.useCallback)((value) => {
|
|
138089
|
+
writeDocumentTranslationActivation(value);
|
|
138090
|
+
setActivationState(value);
|
|
138091
|
+
}, [])
|
|
138092
|
+
};
|
|
138093
|
+
}
|
|
138094
|
+
//#endregion
|
|
138095
|
+
//#region src/lib/resolve-document-translation-config.ts
|
|
138096
|
+
function resolveDocumentTranslationConfig(translationConfig, globalSettings, configPresence) {
|
|
138097
|
+
if (!translationConfig) return void 0;
|
|
138098
|
+
const translationPresence = configPresence?.translation;
|
|
138099
|
+
const projectOwnsEnabled = translationPresence?.enabled ?? false;
|
|
138100
|
+
const projectOwnsTargetLanguage = translationPresence?.targetLanguage ?? false;
|
|
138101
|
+
const projectOwnsDisplayMode = translationPresence?.displayMode ?? false;
|
|
138102
|
+
const projectOwnsCacheEnabled = translationPresence?.cacheEnabled ?? false;
|
|
138103
|
+
const projectOwnsEngineId = translationPresence?.engineId ?? false;
|
|
138104
|
+
const local = translationConfig.engines?.local ?? {};
|
|
138105
|
+
const localCt2 = translationConfig.engines?.localCt2 ?? {};
|
|
138106
|
+
const localLlama = translationConfig.engines?.localLlama ?? {};
|
|
138107
|
+
const openai = translationConfig.engines?.openai ?? {};
|
|
138108
|
+
const resolvedLocalModel = local.model ?? globalSettings?.translationEngines.local?.model;
|
|
138109
|
+
const resolvedLocalSelectedGroupId = local.selectedGroupId ?? globalSettings?.translationEngines.local?.selectedGroupId;
|
|
138110
|
+
const resolvedLocalCt2Model = localCt2.model ?? globalSettings?.translationEngines.localCt2?.model;
|
|
138111
|
+
const resolvedLocalCt2SelectedGroupId = localCt2.selectedGroupId ?? globalSettings?.translationEngines.localCt2?.selectedGroupId;
|
|
138112
|
+
const resolvedLocalLlamaModel = localLlama.model ?? globalSettings?.translationEngines.localLlama?.model;
|
|
138113
|
+
const resolvedLocalLlamaSelectedGroupId = localLlama.selectedGroupId ?? globalSettings?.translationEngines.localLlama?.selectedGroupId;
|
|
138114
|
+
const resolvedOpenAIModel = openai.model ?? globalSettings?.translationEngines.openai?.model;
|
|
138115
|
+
return {
|
|
138116
|
+
...translationConfig,
|
|
138117
|
+
enabled: projectOwnsEnabled ? translationConfig.enabled : globalSettings?.translation?.enabled ?? translationConfig.enabled,
|
|
138118
|
+
targetLanguage: projectOwnsTargetLanguage ? translationConfig.targetLanguage : globalSettings?.translation?.targetLanguage ?? translationConfig.targetLanguage,
|
|
138119
|
+
displayMode: projectOwnsDisplayMode ? translationConfig.displayMode : globalSettings?.translation?.displayMode ?? translationConfig.displayMode,
|
|
138120
|
+
cacheEnabled: projectOwnsCacheEnabled ? translationConfig.cacheEnabled : globalSettings?.translation?.cacheEnabled ?? translationConfig.cacheEnabled,
|
|
138121
|
+
engineId: projectOwnsEngineId ? translationConfig.engineId : globalSettings?.translationEngines.engineId ?? translationConfig.engineId,
|
|
138122
|
+
engines: {
|
|
138123
|
+
local: {
|
|
138124
|
+
...local,
|
|
138125
|
+
...resolvedLocalModel ? { model: resolvedLocalModel } : {},
|
|
138126
|
+
...resolvedLocalSelectedGroupId ? { selectedGroupId: resolvedLocalSelectedGroupId } : {}
|
|
138127
|
+
},
|
|
138128
|
+
localCt2: {
|
|
138129
|
+
...localCt2,
|
|
138130
|
+
...resolvedLocalCt2Model ? { model: resolvedLocalCt2Model } : {},
|
|
138131
|
+
...resolvedLocalCt2SelectedGroupId ? { selectedGroupId: resolvedLocalCt2SelectedGroupId } : {}
|
|
138132
|
+
},
|
|
138133
|
+
localLlama: {
|
|
138134
|
+
...localLlama,
|
|
138135
|
+
...resolvedLocalLlamaModel ? { model: resolvedLocalLlamaModel } : {},
|
|
138136
|
+
...resolvedLocalLlamaSelectedGroupId ? { selectedGroupId: resolvedLocalLlamaSelectedGroupId } : {}
|
|
138137
|
+
},
|
|
138138
|
+
openai: {
|
|
138139
|
+
...openai,
|
|
138140
|
+
...resolvedOpenAIModel ? { model: resolvedOpenAIModel } : {}
|
|
138141
|
+
}
|
|
138142
|
+
}
|
|
138143
|
+
};
|
|
138144
|
+
}
|
|
138145
|
+
//#endregion
|
|
137565
138146
|
//#region ../core/src/local-download-profiles.ts
|
|
137566
138147
|
function selectLocalDownloadGroup(plan, selectedGroupId) {
|
|
137567
138148
|
if (!plan?.groups?.length) return null;
|
|
@@ -137635,6 +138216,11 @@ function projectTranslateServiceStatus(input) {
|
|
|
137635
138216
|
engineId: input.engineId,
|
|
137636
138217
|
message: getTranslationEngineLifecycleMessage(input.engineLifecycle) ?? "Translation engine runtime is not ready."
|
|
137637
138218
|
};
|
|
138219
|
+
if (input.engineLifecycle.assets.state === "error") return {
|
|
138220
|
+
state: "unavailable",
|
|
138221
|
+
engineId: input.engineId,
|
|
138222
|
+
message: input.engineLifecycle.assets.message ?? input.engineLifecycle.assets.error ?? "Selected local model is incompatible with the current translation runtime."
|
|
138223
|
+
};
|
|
137638
138224
|
}
|
|
137639
138225
|
if (isManagedLocalTranslationEngineId(input.engineId)) {
|
|
137640
138226
|
if (!input.localModel?.trim()) return {
|
|
@@ -137719,15 +138305,17 @@ async function resolveTranslateServiceState(input) {
|
|
|
137719
138305
|
localModel: model,
|
|
137720
138306
|
localSelectedGroupId: localEngineConfig.selectedGroupId
|
|
137721
138307
|
}) });
|
|
137722
|
-
|
|
137723
|
-
|
|
137724
|
-
|
|
137725
|
-
|
|
137726
|
-
|
|
137727
|
-
|
|
137728
|
-
|
|
137729
|
-
|
|
137730
|
-
|
|
138308
|
+
if (isDirectionalManagedLocalTranslationEngineId(config.engineId)) {
|
|
138309
|
+
const directionCheck = checkLocalDirectionalModelLanguagePair({
|
|
138310
|
+
model,
|
|
138311
|
+
targetLanguage: config.targetLanguage
|
|
138312
|
+
});
|
|
138313
|
+
if (!directionCheck.supported) return emitTranslateServiceState(input.onUpdate, { status: {
|
|
138314
|
+
state: "unavailable",
|
|
138315
|
+
engineId: config.engineId,
|
|
138316
|
+
message: directionCheck.message ?? "Selected local model does not support the configured target language."
|
|
138317
|
+
} });
|
|
138318
|
+
}
|
|
137731
138319
|
input.onUpdate?.(createTranslateServiceState({ status: projectTranslateServiceStatus({
|
|
137732
138320
|
enabled: config.enabled,
|
|
137733
138321
|
hasSource: input.hasSource,
|
|
@@ -137897,13 +138485,16 @@ function getManagedLocalEngineConfig(config) {
|
|
|
137897
138485
|
return config.engineId === "local-ct2" ? {
|
|
137898
138486
|
model: config.engines.localCt2.model,
|
|
137899
138487
|
selectedGroupId: config.engines.localCt2.selectedGroupId
|
|
138488
|
+
} : config.engineId === "local-llama" ? {
|
|
138489
|
+
model: config.engines.localLlama.model,
|
|
138490
|
+
selectedGroupId: config.engines.localLlama.selectedGroupId
|
|
137900
138491
|
} : {
|
|
137901
138492
|
model: config.engines.local.model,
|
|
137902
138493
|
selectedGroupId: config.engines.local.selectedGroupId
|
|
137903
138494
|
};
|
|
137904
138495
|
}
|
|
137905
138496
|
async function queryManagedLocalPanelState(engineId, input) {
|
|
137906
|
-
return engineId === "local" ? trpcClient.localModels.panelState.query(input) : trpcClient.localCt2Models.panelState.query(input);
|
|
138497
|
+
return engineId === "local" ? trpcClient.localModels.panelState.query(input) : engineId === "local-ct2" ? trpcClient.localCt2Models.panelState.query(input) : trpcClient.localLlamaModels.panelState.query(input);
|
|
137907
138498
|
}
|
|
137908
138499
|
var TrpcTranslator = class {
|
|
137909
138500
|
constructor(options) {
|
|
@@ -137922,7 +138513,8 @@ var TrpcTranslator = class {
|
|
|
137922
138513
|
selectedGroupId: this.options.selectedGroupId,
|
|
137923
138514
|
inputs,
|
|
137924
138515
|
instructions: options?.instructions,
|
|
137925
|
-
context: options?.context
|
|
138516
|
+
context: options?.context,
|
|
138517
|
+
timeoutMs: options?.timeoutMs ?? 15e3
|
|
137926
138518
|
}, {
|
|
137927
138519
|
onData(event) {
|
|
137928
138520
|
queue.push(event);
|
|
@@ -137978,11 +138570,13 @@ function useDocumentTranslation(markdown, config) {
|
|
|
137978
138570
|
const abortRef = (0, import_react.useRef)(null);
|
|
137979
138571
|
const generationRef = (0, import_react.useRef)(0);
|
|
137980
138572
|
const latestStartRef = (0, import_react.useRef)(null);
|
|
138573
|
+
const segmentPatchMapRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
137981
138574
|
const { activation } = useDocumentTranslationActivation();
|
|
137982
138575
|
const cancel = (0, import_react.useCallback)(() => {
|
|
137983
138576
|
generationRef.current += 1;
|
|
137984
138577
|
abortRef.current?.abort();
|
|
137985
138578
|
abortRef.current = null;
|
|
138579
|
+
segmentPatchMapRef.current.clear();
|
|
137986
138580
|
setStatus("source");
|
|
137987
138581
|
setResult(null);
|
|
137988
138582
|
setError(null);
|
|
@@ -137991,6 +138585,7 @@ function useDocumentTranslation(markdown, config) {
|
|
|
137991
138585
|
generationRef.current += 1;
|
|
137992
138586
|
abortRef.current?.abort();
|
|
137993
138587
|
abortRef.current = null;
|
|
138588
|
+
segmentPatchMapRef.current.clear();
|
|
137994
138589
|
setStatus("source");
|
|
137995
138590
|
setResult(null);
|
|
137996
138591
|
setError(null);
|
|
@@ -138000,6 +138595,7 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138000
138595
|
generationRef.current += 1;
|
|
138001
138596
|
setCapability(null);
|
|
138002
138597
|
setBrowserSupportTable(null);
|
|
138598
|
+
segmentPatchMapRef.current.clear();
|
|
138003
138599
|
setResult(null);
|
|
138004
138600
|
setStatus("source");
|
|
138005
138601
|
setError(null);
|
|
@@ -138012,6 +138608,8 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138012
138608
|
config?.engines.local.selectedGroupId,
|
|
138013
138609
|
config?.engines.localCt2.model,
|
|
138014
138610
|
config?.engines.localCt2.selectedGroupId,
|
|
138611
|
+
config?.engines.localLlama.model,
|
|
138612
|
+
config?.engines.localLlama.selectedGroupId,
|
|
138015
138613
|
config?.engines.openai.model,
|
|
138016
138614
|
config?.targetLanguage
|
|
138017
138615
|
]);
|
|
@@ -138054,6 +138652,8 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138054
138652
|
config?.engines.local.selectedGroupId,
|
|
138055
138653
|
config?.engines.localCt2.model,
|
|
138056
138654
|
config?.engines.localCt2.selectedGroupId,
|
|
138655
|
+
config?.engines.localLlama.model,
|
|
138656
|
+
config?.engines.localLlama.selectedGroupId,
|
|
138057
138657
|
config?.targetLanguage,
|
|
138058
138658
|
markdown.length
|
|
138059
138659
|
]);
|
|
@@ -138064,6 +138664,7 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138064
138664
|
const generationId = generationRef.current + 1;
|
|
138065
138665
|
generationRef.current = generationId;
|
|
138066
138666
|
abortRef.current = controller;
|
|
138667
|
+
segmentPatchMapRef.current.clear();
|
|
138067
138668
|
setError(null);
|
|
138068
138669
|
setStatus("initializing");
|
|
138069
138670
|
try {
|
|
@@ -138098,6 +138699,7 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138098
138699
|
targetLanguage: config.targetLanguage,
|
|
138099
138700
|
displayMode: config.displayMode,
|
|
138100
138701
|
signal: controller.signal,
|
|
138702
|
+
timeoutMs: DEFAULT_BATCH_TRANSLATION_TIMEOUT_MS,
|
|
138101
138703
|
engine: createTranslationEngineExecution(config),
|
|
138102
138704
|
cache: config.cacheEnabled && !isStaticMode() ? {
|
|
138103
138705
|
read: (keyHash) => trpcClient.translationCache.read.query({ keyHash }),
|
|
@@ -138108,11 +138710,11 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138108
138710
|
setResult((current) => applyDocumentTranslationPatch(current, patch, {
|
|
138109
138711
|
displayMode: config.displayMode,
|
|
138110
138712
|
targetLanguage: config.targetLanguage
|
|
138111
|
-
}));
|
|
138713
|
+
}, segmentPatchMapRef.current));
|
|
138112
138714
|
});
|
|
138113
138715
|
if (controller.signal.aborted || abortRef.current !== controller || generationRef.current !== generationId) return;
|
|
138114
138716
|
const documentFailure = getDocumentTranslationFailureMessage(nextResult);
|
|
138115
|
-
setResult(nextResult);
|
|
138717
|
+
setResult(normalizeDocumentTranslationResult(nextResult));
|
|
138116
138718
|
if (documentFailure) {
|
|
138117
138719
|
setError(documentFailure);
|
|
138118
138720
|
setStatus("error");
|
|
@@ -138138,9 +138740,62 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138138
138740
|
config?.engines.local.selectedGroupId,
|
|
138139
138741
|
config?.engines.localCt2.model,
|
|
138140
138742
|
config?.engines.localCt2.selectedGroupId,
|
|
138743
|
+
config?.engines.localLlama.model,
|
|
138744
|
+
config?.engines.localLlama.selectedGroupId,
|
|
138141
138745
|
markdown,
|
|
138142
138746
|
serviceStatus
|
|
138143
138747
|
]);
|
|
138748
|
+
const retrySegment = (0, import_react.useCallback)(async (segmentId) => {
|
|
138749
|
+
if (!config?.enabled || !result) return;
|
|
138750
|
+
const segmentIndex = result.segments.findIndex((segment) => segment.id === segmentId);
|
|
138751
|
+
const segment = result.segments[segmentIndex];
|
|
138752
|
+
if (segmentIndex < 0 || !segment || segment.status !== "error") return;
|
|
138753
|
+
const controller = new AbortController();
|
|
138754
|
+
const retryingSegment = {
|
|
138755
|
+
...segment,
|
|
138756
|
+
error: void 0,
|
|
138757
|
+
status: "pending"
|
|
138758
|
+
};
|
|
138759
|
+
setResult((current) => current ? {
|
|
138760
|
+
...current,
|
|
138761
|
+
segments: current.segments.map((entry, index) => index === segmentIndex ? retryingSegment : entry)
|
|
138762
|
+
} : current);
|
|
138763
|
+
try {
|
|
138764
|
+
const nextSegment = await retryTranslationSegment({
|
|
138765
|
+
segment,
|
|
138766
|
+
sourceLanguage: segment.sourceLanguage,
|
|
138767
|
+
targetLanguage: config.targetLanguage,
|
|
138768
|
+
signal: controller.signal,
|
|
138769
|
+
timeoutMs: DEFAULT_BATCH_TRANSLATION_TIMEOUT_MS,
|
|
138770
|
+
engine: createTranslationEngineExecution(config),
|
|
138771
|
+
cache: config.cacheEnabled && !isStaticMode() ? {
|
|
138772
|
+
read: (keyHash) => trpcClient.translationCache.read.query({ keyHash }),
|
|
138773
|
+
write: (input) => trpcClient.translationCache.write.mutate(input)
|
|
138774
|
+
} : void 0
|
|
138775
|
+
});
|
|
138776
|
+
setResult((current) => current ? {
|
|
138777
|
+
...current,
|
|
138778
|
+
segments: current.segments.map((entry, index) => index === segmentIndex ? nextSegment : entry)
|
|
138779
|
+
} : current);
|
|
138780
|
+
setError((current) => {
|
|
138781
|
+
if (nextSegment.status === "error") return nextSegment.error ?? current;
|
|
138782
|
+
return getDocumentTranslationFailureMessage(buildRetriedDocumentResult(result, segmentIndex, nextSegment));
|
|
138783
|
+
});
|
|
138784
|
+
setStatus((current) => {
|
|
138785
|
+
if (nextSegment.status === "error") return current === "translated" ? "translated" : "error";
|
|
138786
|
+
return getDocumentTranslationFailureMessage(buildRetriedDocumentResult(result, segmentIndex, nextSegment)) ? "error" : "translated";
|
|
138787
|
+
});
|
|
138788
|
+
} catch (retryError) {
|
|
138789
|
+
setResult((current) => current ? {
|
|
138790
|
+
...current,
|
|
138791
|
+
segments: current.segments.map((entry, index) => index === segmentIndex ? {
|
|
138792
|
+
...segment,
|
|
138793
|
+
status: "error",
|
|
138794
|
+
error: retryError instanceof Error ? retryError.message : "Translation retry failed."
|
|
138795
|
+
} : entry)
|
|
138796
|
+
} : current);
|
|
138797
|
+
}
|
|
138798
|
+
}, [config, result]);
|
|
138144
138799
|
(0, import_react.useEffect)(() => {
|
|
138145
138800
|
latestStartRef.current = start;
|
|
138146
138801
|
}, [start]);
|
|
@@ -138163,28 +138818,46 @@ function useDocumentTranslation(markdown, config) {
|
|
|
138163
138818
|
error,
|
|
138164
138819
|
result,
|
|
138165
138820
|
start,
|
|
138821
|
+
retrySegment,
|
|
138166
138822
|
cancel,
|
|
138167
138823
|
reset
|
|
138168
138824
|
};
|
|
138169
138825
|
}
|
|
138826
|
+
function isDocumentTranslationSegment(segment) {
|
|
138827
|
+
return isRenderableTranslationSegment(segment);
|
|
138828
|
+
}
|
|
138170
138829
|
function getDocumentTranslationFailureMessage(result) {
|
|
138171
|
-
const segments = (Array.isArray(result.segments) ? result.segments : []).filter(
|
|
138830
|
+
const segments = (Array.isArray(result.segments) ? result.segments : []).filter(isDocumentTranslationSegment);
|
|
138172
138831
|
if (segments.length === 0) return null;
|
|
138173
138832
|
if (segments.some((segment) => segment.status !== "error" && typeof segment.target === "string")) return null;
|
|
138174
138833
|
const errors = segments.map((segment) => segment.status === "error" ? segment.error : void 0).filter((message) => typeof message === "string" && message.length > 0);
|
|
138175
138834
|
if (errors.length === 0) return null;
|
|
138176
138835
|
return errors[0] ?? "Translation failed.";
|
|
138177
138836
|
}
|
|
138178
|
-
function applyDocumentTranslationPatch(current, patch, fallback) {
|
|
138179
|
-
|
|
138180
|
-
|
|
138181
|
-
|
|
138837
|
+
function applyDocumentTranslationPatch(current, patch, fallback, patchMap) {
|
|
138838
|
+
patchMap.set(patch.segmentIndex, patch.segment);
|
|
138839
|
+
return buildPatchedDocumentTranslationResult(current, fallback, patchMap);
|
|
138840
|
+
}
|
|
138841
|
+
function buildPatchedDocumentTranslationResult(current, fallback, patchMap) {
|
|
138842
|
+
return normalizeDocumentTranslationResult({
|
|
138182
138843
|
displayMode: current?.displayMode ?? fallback.displayMode,
|
|
138183
138844
|
sourceLanguage: current?.sourceLanguage,
|
|
138184
138845
|
targetLanguage: current?.targetLanguage ?? fallback.targetLanguage,
|
|
138185
|
-
segments
|
|
138846
|
+
segments: [...patchMap.entries()].sort((left, right) => left[0] - right[0]).map(([, segment]) => segment)
|
|
138847
|
+
});
|
|
138848
|
+
}
|
|
138849
|
+
function normalizeDocumentTranslationResult(result) {
|
|
138850
|
+
return {
|
|
138851
|
+
...result,
|
|
138852
|
+
segments: (Array.isArray(result.segments) ? result.segments : []).filter(isDocumentTranslationSegment)
|
|
138186
138853
|
};
|
|
138187
138854
|
}
|
|
138855
|
+
function buildRetriedDocumentResult(current, segmentIndex, nextSegment) {
|
|
138856
|
+
return normalizeDocumentTranslationResult({
|
|
138857
|
+
...current,
|
|
138858
|
+
segments: current.segments.map((entry, index) => index === segmentIndex ? nextSegment : entry)
|
|
138859
|
+
});
|
|
138860
|
+
}
|
|
138188
138861
|
//#endregion
|
|
138189
138862
|
//#region ../../node_modules/.pnpm/comma-separated-tokens@2.0.3/node_modules/comma-separated-tokens/index.js
|
|
138190
138863
|
/**
|
|
@@ -148790,8 +149463,9 @@ function transformSafeMarkdownUrl(value) {
|
|
|
148790
149463
|
}
|
|
148791
149464
|
//#endregion
|
|
148792
149465
|
//#region src/components/document-translation-segment-render.tsx
|
|
148793
|
-
function renderTranslationSegmentChildren({ sourceChildren, segment, displayMode, targetChildren, className }) {
|
|
149466
|
+
function renderTranslationSegmentChildren({ sourceChildren, segment, displayMode, targetChildren, className, onRetry }) {
|
|
148794
149467
|
const target = segment.target ?? "";
|
|
149468
|
+
const showRetry = segment.status === "error" && typeof onRetry === "function";
|
|
148795
149469
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
148796
149470
|
className: mergeClassName$1("document-translation-segment", className),
|
|
148797
149471
|
children: [displayMode === "bilingual" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
@@ -148804,7 +149478,19 @@ function renderTranslationSegmentChildren({ sourceChildren, segment, displayMode
|
|
|
148804
149478
|
title: displayMode === "direct" ? segment.source : void 0,
|
|
148805
149479
|
lang: segment.targetLanguage,
|
|
148806
149480
|
"data-translation-target": "",
|
|
148807
|
-
children:
|
|
149481
|
+
children: showRetry ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
149482
|
+
className: "inline-flex items-center gap-2",
|
|
149483
|
+
children: [displayMode === "direct" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
149484
|
+
className: "text-muted-foreground",
|
|
149485
|
+
children: segment.source
|
|
149486
|
+
}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
|
|
149487
|
+
size: "sm",
|
|
149488
|
+
variant: "secondary",
|
|
149489
|
+
"aria-label": "Retry translation",
|
|
149490
|
+
onClick: () => onRetry(segment.id),
|
|
149491
|
+
children: "Retry"
|
|
149492
|
+
})]
|
|
149493
|
+
}) : targetChildren ?? (segment.targetNodes ? renderTranslatedHastNodes(segment.targetNodes) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MarkdownInlineContent, { markdown: target }))
|
|
148808
149494
|
})]
|
|
148809
149495
|
});
|
|
148810
149496
|
}
|
|
@@ -148829,13 +149515,13 @@ var OPENSPEC_SECTION_TARGET_LABELS = {
|
|
|
148829
149515
|
overview: "目的",
|
|
148830
149516
|
requirements: "需求"
|
|
148831
149517
|
};
|
|
148832
|
-
function createTranslatedOpenSpecHeadingProjection(input, segment, displayMode) {
|
|
149518
|
+
function createTranslatedOpenSpecHeadingProjection(input, segment, displayMode, onRetry) {
|
|
148833
149519
|
const kind = getCurrentDataAttribute(input, "data-openspec-kind");
|
|
148834
|
-
if (kind === "section") return createTranslatedOpenSpecSectionHeadingProjection(input, segment, displayMode);
|
|
149520
|
+
if (kind === "section") return createTranslatedOpenSpecSectionHeadingProjection(input, segment, displayMode, onRetry);
|
|
148835
149521
|
if (kind !== "requirement" && kind !== "scenario") return void 0;
|
|
148836
|
-
return createTranslatedOpenSpecStructureHeadingProjection(input, segment, displayMode, kind);
|
|
149522
|
+
return createTranslatedOpenSpecStructureHeadingProjection(input, segment, displayMode, kind, onRetry);
|
|
148837
149523
|
}
|
|
148838
|
-
function createTranslatedOpenSpecSectionHeadingProjection(input, segment, displayMode) {
|
|
149524
|
+
function createTranslatedOpenSpecSectionHeadingProjection(input, segment, displayMode, onRetry) {
|
|
148839
149525
|
const sectionKind = getCurrentDataAttribute(input, "data-openspec-section-kind");
|
|
148840
149526
|
if (!sectionKind) return void 0;
|
|
148841
149527
|
const targetTitle = OPENSPEC_SECTION_TARGET_LABELS[sectionKind];
|
|
@@ -148853,11 +149539,12 @@ function createTranslatedOpenSpecSectionHeadingProjection(input, segment, displa
|
|
|
148853
149539
|
},
|
|
148854
149540
|
displayMode,
|
|
148855
149541
|
targetChildren: targetTitle,
|
|
148856
|
-
className: "document-translation-heading-segment"
|
|
149542
|
+
className: "document-translation-heading-segment",
|
|
149543
|
+
onRetry
|
|
148857
149544
|
})
|
|
148858
149545
|
};
|
|
148859
149546
|
}
|
|
148860
|
-
function createTranslatedOpenSpecStructureHeadingProjection(input, segment, displayMode, kind) {
|
|
149547
|
+
function createTranslatedOpenSpecStructureHeadingProjection(input, segment, displayMode, kind, onRetry) {
|
|
148861
149548
|
const sourceParts = splitOpenSpecHeadingText(segment.source, kind);
|
|
148862
149549
|
const targetParts = splitOpenSpecHeadingText(segment.target ?? "", kind);
|
|
148863
149550
|
const visualLabel = getCurrentDataAttribute(input, "data-openspec-visual-label") ?? getCurrentDataAttribute(input, "data-openspec-label");
|
|
@@ -148902,7 +149589,8 @@ function createTranslatedOpenSpecStructureHeadingProjection(input, segment, disp
|
|
|
148902
149589
|
segment: titleSegment,
|
|
148903
149590
|
displayMode,
|
|
148904
149591
|
targetChildren: targetNodes ? renderTranslatedHastNodes(targetNodes) : void 0,
|
|
148905
|
-
className: "document-translation-heading-segment"
|
|
149592
|
+
className: "document-translation-heading-segment",
|
|
149593
|
+
onRetry
|
|
148906
149594
|
})
|
|
148907
149595
|
})] }),
|
|
148908
149596
|
target: targetTitle
|
|
@@ -148963,7 +149651,7 @@ function useDocumentTranslationRenderPlugin({ markdown, translationConfig }) {
|
|
|
148963
149651
|
const resolvedTranslationConfig = (0, import_react.useMemo)(() => translationConfig === void 0 ? void 0 : DocumentTranslationConfigSchema.parse(resolveDocumentTranslationConfig(translationConfig, globalSettings)), [globalSettings, translationConfig]);
|
|
148964
149652
|
const session = useDocumentTranslation(markdown ?? "", resolvedTranslationConfig);
|
|
148965
149653
|
const canTranslate = resolvedTranslationConfig !== void 0 && typeof markdown === "string" && markdown.length > 0;
|
|
148966
|
-
const translationProjection = (0, import_react.useMemo)(() => createTranslationProjection(session.result), [session.result]);
|
|
149654
|
+
const translationProjection = (0, import_react.useMemo)(() => createTranslationProjection(session.result, session.retrySegment), [session.result, session.retrySegment]);
|
|
148967
149655
|
const translationAction = (0, import_react.useMemo)(() => canTranslate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DocumentTranslationAction, {
|
|
148968
149656
|
enabled: resolvedTranslationConfig?.enabled ?? false,
|
|
148969
149657
|
session
|
|
@@ -149034,7 +149722,7 @@ function hashString(value) {
|
|
|
149034
149722
|
for (let index = 0; index < value.length; index++) hash = hash * 31 + value.charCodeAt(index) | 0;
|
|
149035
149723
|
return hash.toString(36);
|
|
149036
149724
|
}
|
|
149037
|
-
function createTranslationProjection(result) {
|
|
149725
|
+
function createTranslationProjection(result, onRetrySegment) {
|
|
149038
149726
|
if (!result) return { blockAnnotations: [] };
|
|
149039
149727
|
const segments = getRenderableTranslationSegments(result);
|
|
149040
149728
|
const segmentByOffset = new Map(segments.filter((segment) => segment.target).map((segment) => [segment.sourceStartOffset, segment]));
|
|
@@ -149056,7 +149744,7 @@ function createTranslationProjection(result) {
|
|
|
149056
149744
|
transformHeading(input) {
|
|
149057
149745
|
const segment = input.sourceStartOffset === void 0 ? void 0 : segmentByOffset.get(input.sourceStartOffset);
|
|
149058
149746
|
if (!segment?.target || segment.kind !== "heading") return void 0;
|
|
149059
|
-
return createTranslatedHeadingTransform(input, segment, result.displayMode);
|
|
149747
|
+
return createTranslatedHeadingTransform(input, segment, result.displayMode, onRetrySegment);
|
|
149060
149748
|
}
|
|
149061
149749
|
},
|
|
149062
149750
|
blockAnnotations: segments.filter((segment) => segment.target && segment.kind !== "heading").map((segment) => ({
|
|
@@ -149075,17 +149763,18 @@ function createTranslationProjection(result) {
|
|
|
149075
149763
|
renderChildren: (children) => segment.targetNodes && result.displayMode === "direct" ? children : renderTranslationSegmentChildren({
|
|
149076
149764
|
sourceChildren: children,
|
|
149077
149765
|
segment,
|
|
149078
|
-
displayMode: result.displayMode
|
|
149766
|
+
displayMode: result.displayMode,
|
|
149767
|
+
onRetry: onRetrySegment
|
|
149079
149768
|
})
|
|
149080
149769
|
}))
|
|
149081
149770
|
};
|
|
149082
149771
|
}
|
|
149083
149772
|
function getRenderableTranslationSegments(result) {
|
|
149084
|
-
return (Array.isArray(result.segments) ? result.segments : []).filter(
|
|
149773
|
+
return (Array.isArray(result.segments) ? result.segments : []).filter(isRenderableTranslationSegment);
|
|
149085
149774
|
}
|
|
149086
|
-
function createTranslatedHeadingTransform(input, segment, displayMode) {
|
|
149775
|
+
function createTranslatedHeadingTransform(input, segment, displayMode, onRetrySegment) {
|
|
149087
149776
|
const projectedTarget = segment.target ?? "";
|
|
149088
|
-
const openSpecHeading = createTranslatedOpenSpecHeadingProjection(input, segment, displayMode);
|
|
149777
|
+
const openSpecHeading = createTranslatedOpenSpecHeadingProjection(input, segment, displayMode, onRetrySegment);
|
|
149089
149778
|
if (openSpecHeading) return {
|
|
149090
149779
|
tocDataLabel: displayMode === "direct" ? openSpecHeading.tocDataLabel : input.current?.tocLabel ?? input.text,
|
|
149091
149780
|
children: openSpecHeading.children,
|
|
@@ -149100,7 +149789,8 @@ function createTranslatedHeadingTransform(input, segment, displayMode) {
|
|
|
149100
149789
|
segment,
|
|
149101
149790
|
displayMode,
|
|
149102
149791
|
targetChildren,
|
|
149103
|
-
className: "document-translation-heading-segment"
|
|
149792
|
+
className: "document-translation-heading-segment",
|
|
149793
|
+
onRetry: onRetrySegment
|
|
149104
149794
|
}),
|
|
149105
149795
|
dataAttributes: createTranslationDataAttributes(segment, projectedTarget, displayMode)
|
|
149106
149796
|
};
|
|
@@ -149111,7 +149801,8 @@ function createTranslatedHeadingTransform(input, segment, displayMode) {
|
|
|
149111
149801
|
segment,
|
|
149112
149802
|
displayMode,
|
|
149113
149803
|
targetChildren,
|
|
149114
|
-
className: "document-translation-heading-segment"
|
|
149804
|
+
className: "document-translation-heading-segment",
|
|
149805
|
+
onRetry: onRetrySegment
|
|
149115
149806
|
}),
|
|
149116
149807
|
dataAttributes: createTranslationDataAttributes(segment, projectedTarget, displayMode)
|
|
149117
149808
|
};
|