dsh-workbuddy-xdpool 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +83 -0
- package/README.en.md +112 -45
- package/README.md +104 -53
- package/assets/automation-panel.png +0 -0
- package/assets/settings-card.png +0 -0
- package/lib/bin.js +1700 -21
- package/lib/client.js +437 -86
- package/lib/index.d.ts +928 -17
- package/lib/index.js +1975 -44
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -28,6 +28,10 @@ window.__ModuleLoader__.load({
|
|
|
28
28
|
const POOL_RESET_COOLDOWN_PATH = "/plugins/dsh-workbuddy-xdpool/cooldowns/reset";
|
|
29
29
|
/** Plugin-owned daily check-in action endpoint (claim today's reward). */
|
|
30
30
|
const POOL_CHECKIN_PATH = "/plugins/dsh-workbuddy-xdpool/checkin";
|
|
31
|
+
/** Run one automation job immediately, so the card can verify it on demand. */
|
|
32
|
+
const POOL_AUTOMATION_RUN_PATH = "/plugins/dsh-workbuddy-xdpool/automation/run";
|
|
33
|
+
/** Set or clear one account's reserved-credit floor. */
|
|
34
|
+
const POOL_CREDIT_RESERVE_PATH = "/plugins/dsh-workbuddy-xdpool/accounts/credit-reserve";
|
|
31
35
|
//#endregion
|
|
32
36
|
//#region src/client/icon.ts
|
|
33
37
|
/**
|
|
@@ -116,13 +120,16 @@ window.__ModuleLoader__.load({
|
|
|
116
120
|
.dsm-workbuddy-xdpool-usage-dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto}
|
|
117
121
|
.dsm-workbuddy-xdpool-usage-hint{padding-left:19px;color:var(--dsw-alias-label-tertiary,#9aa0a8);font-size:12px;line-height:18px}
|
|
118
122
|
/* Distribution switch: priority (drain one) vs round-robin (spread). */
|
|
119
|
-
.dsm-workbuddy-xdpool-dist{display:flex;
|
|
123
|
+
.dsm-workbuddy-xdpool-dist{display:flex;flex-direction:column;gap:6px;padding-left:19px;margin-top:8px}
|
|
120
124
|
.dsm-workbuddy-xdpool-dist-title{color:var(--dsw-alias-label-tertiary,#9aa0a8);font-size:12px;line-height:18px}
|
|
121
|
-
.dsm-workbuddy-xdpool-dist-option{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2,#3a3d45);border-radius:
|
|
125
|
+
.dsm-workbuddy-xdpool-dist-option{appearance:none;font:inherit;cursor:pointer;text-align:left;display:flex;flex-direction:column;justify-content:center;gap:2px;min-height:44px;border:1px solid var(--dsw-alias-border-l2,#3a3d45);border-radius:8px;padding:6px 10px;background:transparent;color:var(--dsw-alias-label-tertiary,#9aa0a8);transition:color .16s,border-color .16s,background .16s}
|
|
122
126
|
.dsm-workbuddy-xdpool-dist-option:hover:not(:disabled):not(.dsm-workbuddy-xdpool-dist-option-active){color:var(--dsw-alias-label-primary,#e6e6e6);border-color:var(--dsw-alias-label-dimmed,#777)}
|
|
123
127
|
.dsm-workbuddy-xdpool-dist-option:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#5686fe);outline-offset:1px}
|
|
124
128
|
.dsm-workbuddy-xdpool-dist-option-active{background:var(--dsw-alias-state-success-subtle,rgba(34,160,107,.14));border-color:var(--dsw-alias-state-success-primary,#22a06b);color:var(--dsw-alias-state-success-primary,#22a06b)}
|
|
125
129
|
.dsm-workbuddy-xdpool-dist-option:disabled{cursor:default;opacity:.6}
|
|
130
|
+
.dsm-workbuddy-xdpool-dist-option-name{font-size:11px;line-height:16px;font-weight:600}
|
|
131
|
+
.dsm-workbuddy-xdpool-dist-option-hint{font-size:10px;line-height:14px;opacity:.8}
|
|
132
|
+
.dsm-workbuddy-xdpool-dist-options{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
|
|
126
133
|
.dsm-workbuddy-xdpool-usage-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
127
134
|
|
|
128
135
|
/* Account list (each account = a labeled subpanel, same as dingminhua). */
|
|
@@ -253,11 +260,34 @@ window.__ModuleLoader__.load({
|
|
|
253
260
|
.dsm-workbuddy-xdpool-auto-switch:disabled{opacity:.5;cursor:not-allowed}
|
|
254
261
|
.dsm-workbuddy-xdpool-auto-switch-on{border-color:#28c8b4;color:#28c8b4;background:rgba(40,200,180,.12)}
|
|
255
262
|
.dsm-workbuddy-xdpool-auto-hint{margin:6px 0 0;color:var(--dsw-alias-label-dimmed,#8a97b5);font-size:11px;line-height:1.5}
|
|
263
|
+
.dsm-workbuddy-xdpool-auto-total{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-top:8px;padding:6px 8px;border-radius:8px;background:rgba(40,200,180,.08);font-size:11px}
|
|
264
|
+
.dsm-workbuddy-xdpool-auto-total-label{color:var(--dsw-alias-label-dimmed,#8a97b5)}
|
|
265
|
+
.dsm-workbuddy-xdpool-auto-total{display:flex;flex-direction:column;gap:4px;margin-top:8px;padding:6px 8px;border-radius:8px;background:rgba(40,200,180,.08);font-size:11px}
|
|
266
|
+
.dsm-workbuddy-xdpool-auto-total-list{display:flex;flex-direction:column;gap:2px}
|
|
267
|
+
.dsm-workbuddy-xdpool-auto-total-row{color:#28c8b4;font-variant-numeric:tabular-nums}
|
|
268
|
+
.dsm-workbuddy-xdpool-earned{display:flex;flex-direction:column;gap:4px;margin-top:8px;padding-top:8px;border-top:1px dashed var(--dsw-alias-border-l2,#36373b);font-size:11px}
|
|
269
|
+
.dsm-workbuddy-xdpool-earned-label{color:var(--dsw-alias-label-dimmed,#8a97b5)}
|
|
270
|
+
.dsm-workbuddy-xdpool-earned-list{display:flex;flex-direction:column;gap:2px}
|
|
271
|
+
.dsm-workbuddy-xdpool-earned-row{color:#28c8b4;font-variant-numeric:tabular-nums}
|
|
272
|
+
.dsm-workbuddy-xdpool-earned-value{color:#28c8b4;font-weight:600;font-variant-numeric:tabular-nums}
|
|
256
273
|
.dsm-workbuddy-xdpool-auto-jobs{margin-top:8px;display:flex;flex-direction:column;gap:4px}
|
|
257
|
-
.dsm-workbuddy-xdpool-auto-job{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--dsw-alias-label-dimmed,#8a97b5)}
|
|
274
|
+
.dsm-workbuddy-xdpool-auto-job{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--dsw-alias-label-dimmed,#8a97b5)}
|
|
258
275
|
.dsm-workbuddy-xdpool-auto-job-name{flex:0 0 72px;color:var(--dsw-alias-label-primary,#e8e8ea)}
|
|
259
276
|
.dsm-workbuddy-xdpool-auto-job-when{flex:1 1 auto;font-variant-numeric:tabular-nums}
|
|
260
277
|
.dsm-workbuddy-xdpool-auto-job-last{flex:0 0 auto;text-align:right;font-variant-numeric:tabular-nums}
|
|
278
|
+
/* The job detail wraps to its own full-width line: it is a list of reward
|
|
279
|
+
titles, which needs the whole row rather than a cramped right-hand slot. */
|
|
280
|
+
.dsm-workbuddy-xdpool-auto-job-detail{flex:1 1 100%;color:var(--dsw-alias-label-secondary,#b8bcc4);line-height:1.5;word-break:break-word}
|
|
281
|
+
.dsm-workbuddy-xdpool-auto-job-note{flex:0 0 auto;color:var(--dsw-alias-label-secondary,#b8bcc4)}
|
|
282
|
+
.dsm-workbuddy-xdpool-auto-run{flex:0 0 auto;padding:2px 8px;font-size:10px;line-height:16px}
|
|
283
|
+
/* Reserved credits: one inline number field per account. */
|
|
284
|
+
.dsm-workbuddy-xdpool-reserve{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:8px;padding-top:8px;border-top:1px dashed var(--dsw-alias-border-l2,#36373b);font-size:11px;color:var(--dsw-alias-label-dimmed,#8a97b5)}
|
|
285
|
+
.dsm-workbuddy-xdpool-reserve-label{flex:0 0 auto}
|
|
286
|
+
.dsm-workbuddy-xdpool-reserve-input{width:76px;padding:2px 6px;border:1px solid var(--dsw-alias-border-l2,#36373b);border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary,#e8e8ea);font:inherit;font-variant-numeric:tabular-nums}
|
|
287
|
+
.dsm-workbuddy-xdpool-reserve-input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#5686fe);outline-offset:1px}
|
|
288
|
+
.dsm-workbuddy-xdpool-reserve-input:disabled{opacity:.6}
|
|
289
|
+
.dsm-workbuddy-xdpool-reserve-unit{flex:0 0 auto}
|
|
290
|
+
.dsm-workbuddy-xdpool-reserve-badge{flex:0 0 auto;padding:1px 7px;border-radius:999px;background:rgba(232,90,90,.14);color:#e85a5a;font-size:10px}
|
|
261
291
|
`.trim();
|
|
262
292
|
//#endregion
|
|
263
293
|
//#region src/client/PoolCard.tsx
|
|
@@ -326,11 +356,21 @@ window.__ModuleLoader__.load({
|
|
|
326
356
|
* matching hour list off the status document so the panel stays in step with
|
|
327
357
|
* whatever schedule the scheduler is actually running on.
|
|
328
358
|
*/
|
|
359
|
+
/**
|
|
360
|
+
* How long to watch a manual run before giving up on it.
|
|
361
|
+
*
|
|
362
|
+
* A pass runs one upstream call per account per job, so ~30s for a handful of
|
|
363
|
+
* accounts. The bound exists so a wedged run cannot spin the button forever;
|
|
364
|
+
* the run itself keeps going in the background either way.
|
|
365
|
+
*/
|
|
366
|
+
const AUTOMATION_POLL_MS = 2e3;
|
|
367
|
+
const AUTOMATION_POLL_ATTEMPTS = 90;
|
|
329
368
|
const AUTOMATION_JOBS = [
|
|
369
|
+
"checkin",
|
|
330
370
|
"report",
|
|
331
371
|
"tasks",
|
|
332
|
-
"
|
|
333
|
-
"
|
|
372
|
+
"streak",
|
|
373
|
+
"travel"
|
|
334
374
|
];
|
|
335
375
|
/** Read one job's configured hours off the status document. */
|
|
336
376
|
function automationHours(status, kind) {
|
|
@@ -341,6 +381,7 @@ window.__ModuleLoader__.load({
|
|
|
341
381
|
case "tasks": return automation.taskHours;
|
|
342
382
|
case "checkin": return automation.checkinHours;
|
|
343
383
|
case "streak": return automation.streakHours;
|
|
384
|
+
case "travel": return automation.travelHours;
|
|
344
385
|
}
|
|
345
386
|
}
|
|
346
387
|
/** Read one job's last-run record off the status document. */
|
|
@@ -433,10 +474,35 @@ window.__ModuleLoader__.load({
|
|
|
433
474
|
const [statusByRegion, setStatusByRegion] = (0, react.useState)({});
|
|
434
475
|
/** The document for the tab on screen; undefined until its first answer. */
|
|
435
476
|
const status = statusByRegion[activeRegion];
|
|
477
|
+
/**
|
|
478
|
+
* Today's automation take, summed across accounts.
|
|
479
|
+
*
|
|
480
|
+
* Summed from the per-account counters rather than kept separately, so the
|
|
481
|
+
* panel total and the per-account lines can never disagree.
|
|
482
|
+
*/
|
|
483
|
+
const automationTotals = Object.values(status?.automation?.earningsToday ?? {}).reduce((sum, entry) => ({
|
|
484
|
+
credit: sum.credit + entry.credit,
|
|
485
|
+
energy: sum.energy + entry.energy,
|
|
486
|
+
claimed: sum.claimed + entry.claimed,
|
|
487
|
+
checkinCredit: sum.checkinCredit + entry.checkinCredit,
|
|
488
|
+
bonusCredit: sum.bonusCredit + entry.bonusCredit,
|
|
489
|
+
travelCredit: sum.travelCredit + entry.travelCredit
|
|
490
|
+
}), {
|
|
491
|
+
credit: 0,
|
|
492
|
+
energy: 0,
|
|
493
|
+
claimed: 0,
|
|
494
|
+
checkinCredit: 0,
|
|
495
|
+
bonusCredit: 0,
|
|
496
|
+
travelCredit: 0
|
|
497
|
+
});
|
|
436
498
|
const [error, setError] = (0, react.useState)(void 0);
|
|
437
499
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
438
500
|
const [cooldownBusy, setCooldownBusy] = (0, react.useState)(false);
|
|
439
501
|
const [automationBusy, setAutomationBusy] = (0, react.useState)(false);
|
|
502
|
+
/** The automation job currently running from the card, if any. */
|
|
503
|
+
const [automationRun, setAutomationRun] = (0, react.useState)(void 0);
|
|
504
|
+
/** Account id whose reserved-credit floor is being saved, if any. */
|
|
505
|
+
const [reserveBusy, setReserveBusy] = (0, react.useState)(void 0);
|
|
440
506
|
const [flash, setFlash] = (0, react.useState)(void 0);
|
|
441
507
|
/** Account id whose daily claim is currently in flight. */
|
|
442
508
|
const [checkinBusyId, setCheckinBusyId] = (0, react.useState)(void 0);
|
|
@@ -490,8 +556,10 @@ window.__ModuleLoader__.load({
|
|
|
490
556
|
}));
|
|
491
557
|
setError(void 0);
|
|
492
558
|
}
|
|
559
|
+
return value;
|
|
493
560
|
} catch (cause) {
|
|
494
561
|
if (mounted.current && signal?.aborted !== true) setError(cause instanceof Error ? cause.message : String(cause));
|
|
562
|
+
return;
|
|
495
563
|
}
|
|
496
564
|
}, []);
|
|
497
565
|
(0, react.useEffect)(() => {
|
|
@@ -724,6 +792,83 @@ window.__ModuleLoader__.load({
|
|
|
724
792
|
if (mounted.current) setAutomationBusy(false);
|
|
725
793
|
}
|
|
726
794
|
};
|
|
795
|
+
/**
|
|
796
|
+
/**
|
|
797
|
+
* Run the whole automation pass now.
|
|
798
|
+
*
|
|
799
|
+
* The route only STARTS the pass: a full run takes tens of seconds, which is
|
|
800
|
+
* far too long to hold a request open. This watches the scheduler status until
|
|
801
|
+
* the run settles, so the panel can show "running" honestly and report the
|
|
802
|
+
* result when it lands.
|
|
803
|
+
*/
|
|
804
|
+
const runAutomationJob = async () => {
|
|
805
|
+
setAutomationRun("all");
|
|
806
|
+
setFlash(void 0);
|
|
807
|
+
try {
|
|
808
|
+
const response = await fetch(POOL_AUTOMATION_RUN_PATH, {
|
|
809
|
+
method: "POST",
|
|
810
|
+
headers: {
|
|
811
|
+
"accept": "application/json",
|
|
812
|
+
"content-type": "application/json"
|
|
813
|
+
},
|
|
814
|
+
credentials: "same-origin",
|
|
815
|
+
body: JSON.stringify({ job: "all" })
|
|
816
|
+
});
|
|
817
|
+
const body = await response.json();
|
|
818
|
+
if (!response.ok) throw new Error(body.error ?? `HTTP ${response.status}`);
|
|
819
|
+
if (body.started === false) {
|
|
820
|
+
if (mounted.current) setFlash(t?.("row.autoAlreadyRunning") ?? "A run is already in progress");
|
|
821
|
+
}
|
|
822
|
+
let settled = false;
|
|
823
|
+
for (let attempt = 0; attempt < AUTOMATION_POLL_ATTEMPTS; attempt += 1) {
|
|
824
|
+
await new Promise((resolve) => setTimeout(resolve, AUTOMATION_POLL_MS));
|
|
825
|
+
if (!mounted.current) return;
|
|
826
|
+
if ((await refresh(activeRegion))?.automation?.runInProgress === false) {
|
|
827
|
+
settled = true;
|
|
828
|
+
break;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
await refresh(activeRegion);
|
|
832
|
+
if (mounted.current) setFlash(settled ? t?.("row.autoRunDone") ?? "Automation pass finished" : t?.("row.autoRunTimeout") ?? "Still running; check back in a moment");
|
|
833
|
+
} catch (cause) {
|
|
834
|
+
if (mounted.current) setError(cause instanceof Error ? cause.message : String(cause));
|
|
835
|
+
} finally {
|
|
836
|
+
if (mounted.current) setAutomationRun(void 0);
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
/**
|
|
840
|
+
* Save one account reserved-credit floor.
|
|
841
|
+
*
|
|
842
|
+
* A reserve only protects credits if the pool knows the balance, so this
|
|
843
|
+
* also refreshes the account list afterwards: the reserve badge appears
|
|
844
|
+
* as soon as the reading crosses the floor.
|
|
845
|
+
*/
|
|
846
|
+
const saveCreditReserve = async (accountId, reserve) => {
|
|
847
|
+
setReserveBusy(accountId);
|
|
848
|
+
setFlash(void 0);
|
|
849
|
+
try {
|
|
850
|
+
const response = await fetch(POOL_CREDIT_RESERVE_PATH, {
|
|
851
|
+
method: "POST",
|
|
852
|
+
headers: {
|
|
853
|
+
"accept": "application/json",
|
|
854
|
+
"content-type": "application/json"
|
|
855
|
+
},
|
|
856
|
+
credentials: "same-origin",
|
|
857
|
+
body: JSON.stringify({
|
|
858
|
+
accountId,
|
|
859
|
+
reserve
|
|
860
|
+
})
|
|
861
|
+
});
|
|
862
|
+
const body = await response.json();
|
|
863
|
+
if (!response.ok) throw new Error(body.error ?? `HTTP ${response.status}`);
|
|
864
|
+
await refresh(activeRegion);
|
|
865
|
+
if (mounted.current) setFlash(reserve > 0 ? t?.("row.reserveSaved", { credits: reserve }) ?? `Keeping ${reserve} credits` : t?.("row.reserveCleared") ?? "Reserve cleared");
|
|
866
|
+
} catch (cause) {
|
|
867
|
+
if (mounted.current) setError(cause instanceof Error ? cause.message : String(cause));
|
|
868
|
+
} finally {
|
|
869
|
+
if (mounted.current) setReserveBusy(void 0);
|
|
870
|
+
}
|
|
871
|
+
};
|
|
727
872
|
const saveModels = async () => {
|
|
728
873
|
if (draft === void 0 || status === void 0) return;
|
|
729
874
|
if (enabledCount === 0) {
|
|
@@ -852,26 +997,35 @@ window.__ModuleLoader__.load({
|
|
|
852
997
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
853
998
|
className: "dsm-workbuddy-xdpool-dist-title",
|
|
854
999
|
children: t?.("row.distTitle") ?? "Account usage"
|
|
855
|
-
}),
|
|
856
|
-
"
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1000
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1001
|
+
className: "dsm-workbuddy-xdpool-dist-options",
|
|
1002
|
+
children: [
|
|
1003
|
+
"priority",
|
|
1004
|
+
"balanced",
|
|
1005
|
+
"round-robin"
|
|
1006
|
+
].map((option) => {
|
|
1007
|
+
const active = (status.distribution ?? "priority") === option;
|
|
1008
|
+
const label = option === "priority" ? t?.("row.distPriority") ?? "Priority" : option === "balanced" ? t?.("row.distBalanced") ?? "Balanced" : t?.("row.distRoundRobin") ?? "Round-robin";
|
|
1009
|
+
const hint = option === "priority" ? t?.("row.distPriorityHint") ?? "" : option === "balanced" ? t?.("row.distBalancedHint") ?? "" : t?.("row.distRoundRobinHint") ?? "";
|
|
1010
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1011
|
+
type: "button",
|
|
1012
|
+
role: "radio",
|
|
1013
|
+
"aria-checked": active,
|
|
1014
|
+
title: hint,
|
|
1015
|
+
disabled: !modelsEditable,
|
|
1016
|
+
className: "dsm-workbuddy-xdpool-dist-option" + (active ? " dsm-workbuddy-xdpool-dist-option-active" : ""),
|
|
1017
|
+
onClick: () => {
|
|
1018
|
+
setDistribution(option);
|
|
1019
|
+
},
|
|
1020
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1021
|
+
className: "dsm-workbuddy-xdpool-dist-option-name",
|
|
1022
|
+
children: label
|
|
1023
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1024
|
+
className: "dsm-workbuddy-xdpool-dist-option-hint",
|
|
1025
|
+
children: hint
|
|
1026
|
+
})]
|
|
1027
|
+
}, option);
|
|
1028
|
+
})
|
|
875
1029
|
})]
|
|
876
1030
|
})
|
|
877
1031
|
]
|
|
@@ -896,31 +1050,74 @@ window.__ModuleLoader__.load({
|
|
|
896
1050
|
}) : null]
|
|
897
1051
|
})]
|
|
898
1052
|
}),
|
|
899
|
-
status?.automation === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1053
|
+
activeRegion !== "cn" || status?.automation === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
900
1054
|
className: "dsm-workbuddy-xdpool-auto",
|
|
901
1055
|
"aria-label": t?.("row.autoTitle") ?? "Automation",
|
|
902
1056
|
children: [
|
|
903
1057
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
904
1058
|
className: "dsm-workbuddy-xdpool-auto-head",
|
|
905
|
-
children: [
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1059
|
+
children: [
|
|
1060
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1061
|
+
className: "dsm-workbuddy-xdpool-auto-title",
|
|
1062
|
+
children: t?.("row.autoTitle") ?? "Automation"
|
|
1063
|
+
}),
|
|
1064
|
+
!status.automation.enabled ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1065
|
+
type: "button",
|
|
1066
|
+
className: "dsm-btn dsm-btn-outline dsm-workbuddy-xdpool-auto-run",
|
|
1067
|
+
disabled: automationRun !== void 0,
|
|
1068
|
+
onClick: () => {
|
|
1069
|
+
runAutomationJob();
|
|
1070
|
+
},
|
|
1071
|
+
children: automationRun !== void 0 ? t?.("row.autoRunning") ?? "Running…" : t?.("row.autoRunAll") ?? "Run all now"
|
|
1072
|
+
}),
|
|
1073
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1074
|
+
type: "button",
|
|
1075
|
+
role: "switch",
|
|
1076
|
+
"aria-checked": status.automation.enabled,
|
|
1077
|
+
disabled: !settingsWritable || automationBusy,
|
|
1078
|
+
className: `dsm-workbuddy-xdpool-auto-switch${status.automation.enabled ? " dsm-workbuddy-xdpool-auto-switch-on" : ""}`,
|
|
1079
|
+
onClick: () => {
|
|
1080
|
+
setAutomationEnabled(!status.automation.enabled);
|
|
1081
|
+
},
|
|
1082
|
+
children: automationBusy ? t?.("row.autoBusy") ?? "Saving…" : status.automation.enabled ? t?.("row.autoOn") ?? "On" : t?.("row.autoOff") ?? "Off"
|
|
1083
|
+
})
|
|
1084
|
+
]
|
|
919
1085
|
}),
|
|
920
1086
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
921
1087
|
className: "dsm-workbuddy-xdpool-auto-hint",
|
|
922
1088
|
children: status.automation.enabled ? t?.("row.autoHintOn") ?? "Reports activity, claims task rewards and checks in once a day." : t?.("row.autoHintOff") ?? "Off: no background requests are made for you."
|
|
923
1089
|
}),
|
|
1090
|
+
automationTotals.credit === 0 && automationTotals.checkinCredit === 0 && automationTotals.bonusCredit === 0 && automationTotals.travelCredit === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1091
|
+
className: "dsm-workbuddy-xdpool-auto-total",
|
|
1092
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1093
|
+
className: "dsm-workbuddy-xdpool-auto-total-label",
|
|
1094
|
+
children: t?.("row.autoToday") ?? "Today"
|
|
1095
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1096
|
+
className: "dsm-workbuddy-xdpool-auto-total-list",
|
|
1097
|
+
children: [
|
|
1098
|
+
automationTotals.credit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1099
|
+
className: "dsm-workbuddy-xdpool-auto-total-row",
|
|
1100
|
+
children: t?.("row.autoFromTasks", {
|
|
1101
|
+
credit: automationTotals.credit,
|
|
1102
|
+
energy: automationTotals.energy,
|
|
1103
|
+
count: automationTotals.claimed
|
|
1104
|
+
}) ?? `Tasks +${automationTotals.credit}`
|
|
1105
|
+
}) : null,
|
|
1106
|
+
automationTotals.checkinCredit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1107
|
+
className: "dsm-workbuddy-xdpool-auto-total-row",
|
|
1108
|
+
children: t?.("row.autoFromCheckin", { credit: automationTotals.checkinCredit }) ?? `Check-in +${automationTotals.checkinCredit}`
|
|
1109
|
+
}) : null,
|
|
1110
|
+
automationTotals.bonusCredit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1111
|
+
className: "dsm-workbuddy-xdpool-auto-total-row",
|
|
1112
|
+
children: t?.("row.autoFromBonus", { credit: automationTotals.bonusCredit }) ?? `Streak +${automationTotals.bonusCredit}`
|
|
1113
|
+
}) : null,
|
|
1114
|
+
automationTotals.travelCredit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1115
|
+
className: "dsm-workbuddy-xdpool-auto-total-row",
|
|
1116
|
+
children: t?.("row.autoFromTravel", { credit: automationTotals.travelCredit }) ?? `Buddy +${automationTotals.travelCredit}`
|
|
1117
|
+
}) : null
|
|
1118
|
+
]
|
|
1119
|
+
})]
|
|
1120
|
+
}),
|
|
924
1121
|
status.automation.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
925
1122
|
className: "dsm-workbuddy-xdpool-auto-jobs",
|
|
926
1123
|
children: AUTOMATION_JOBS.map((kind) => {
|
|
@@ -941,6 +1138,14 @@ window.__ModuleLoader__.load({
|
|
|
941
1138
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
942
1139
|
className: "dsm-workbuddy-xdpool-auto-job-last",
|
|
943
1140
|
children: job?.lastRunDate === void 0 ? t?.("row.autoNever") ?? "not run yet" : `${job.lastRunDate} · ${job.ok}${job.failed > 0 ? `/${job.failed}` : ""}`
|
|
1141
|
+
}),
|
|
1142
|
+
job?.progress === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1143
|
+
className: "dsm-workbuddy-xdpool-auto-job-note",
|
|
1144
|
+
children: job.progress
|
|
1145
|
+
}),
|
|
1146
|
+
job?.detail === void 0 || job.detail.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1147
|
+
className: "dsm-workbuddy-xdpool-auto-job-detail",
|
|
1148
|
+
children: job.detail.join(" · ")
|
|
944
1149
|
})
|
|
945
1150
|
]
|
|
946
1151
|
}, kind);
|
|
@@ -1029,6 +1234,9 @@ window.__ModuleLoader__.load({
|
|
|
1029
1234
|
onClaimCheckin: (accountId) => {
|
|
1030
1235
|
claimCheckin(accountId);
|
|
1031
1236
|
},
|
|
1237
|
+
onSaveCreditReserve: (accountId, reserve) => {
|
|
1238
|
+
saveCreditReserve(accountId, reserve);
|
|
1239
|
+
},
|
|
1032
1240
|
onToggleDisabled: (accountId, disabled) => {
|
|
1033
1241
|
toggleAccountDisabled(accountId, disabled);
|
|
1034
1242
|
},
|
|
@@ -1094,7 +1302,7 @@ window.__ModuleLoader__.load({
|
|
|
1094
1302
|
});
|
|
1095
1303
|
}
|
|
1096
1304
|
/** One account block: label + status tag + meta + optional credit panels. */
|
|
1097
|
-
function AccountBlock({ account, t, checkinBusyId, onClaimCheckin, accountBusyId, onToggleDisabled }) {
|
|
1305
|
+
function AccountBlock({ account, t, checkinBusyId, onClaimCheckin, accountBusyId, onToggleDisabled, onSaveCreditReserve, reserveBusyId }) {
|
|
1098
1306
|
const isDisabled = account.disabled === true;
|
|
1099
1307
|
const isCooling = account.cooling === true;
|
|
1100
1308
|
const cooldownUntil = account.cooldownUntil !== void 0 ? Date.parse(account.cooldownUntil) : void 0;
|
|
@@ -1131,38 +1339,78 @@ window.__ModuleLoader__.load({
|
|
|
1131
1339
|
]
|
|
1132
1340
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1133
1341
|
className: "dsm-workbuddy-xdpool-account-body",
|
|
1134
|
-
children: [
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1342
|
+
children: [
|
|
1343
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1344
|
+
className: "dsm-workbuddy-xdpool-account-copy",
|
|
1345
|
+
children: [
|
|
1346
|
+
account.expiresAt !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1347
|
+
className: "dsm-workbuddy-xdpool-account-meta",
|
|
1348
|
+
children: t?.("row.tokenExpiry", { time: formatDateTime(account.expiresAt) }) ?? `token ${formatDateTime(account.expiresAt)}`
|
|
1349
|
+
}) : null,
|
|
1350
|
+
isCooling && cooldownUntil !== void 0 && !Number.isNaN(cooldownUntil) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1351
|
+
className: "dsm-workbuddy-xdpool-account-meta",
|
|
1352
|
+
children: [
|
|
1353
|
+
t?.("row.cooldownUntil", { time: formatTime(cooldownUntil) }) ?? `until ${formatTime(cooldownUntil)}`,
|
|
1354
|
+
" · ",
|
|
1355
|
+
t?.("row.cooldownHits", { hits: account.rateLimitHits ?? 0 }) ?? `${account.rateLimitHits ?? 0} hit(s)`
|
|
1356
|
+
]
|
|
1357
|
+
}) : null,
|
|
1358
|
+
modelCooldowns.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1359
|
+
className: "dsm-workbuddy-xdpool-account-modelcool",
|
|
1360
|
+
children: modelCooldowns.map((mc) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1361
|
+
className: "dsm-workbuddy-xdpool-account-modelcool-chip",
|
|
1362
|
+
children: t?.("row.modelCooling", {
|
|
1363
|
+
model: mc.modelId,
|
|
1364
|
+
time: formatDateTime(mc.until)
|
|
1365
|
+
}) ?? `${mc.modelId} cooling to ${formatDateTime(mc.until)}`
|
|
1366
|
+
}, mc.modelId))
|
|
1367
|
+
}) : null
|
|
1368
|
+
]
|
|
1369
|
+
}),
|
|
1370
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountStats, {
|
|
1371
|
+
account,
|
|
1372
|
+
t,
|
|
1373
|
+
checkinBusy: checkinBusyId === account.id,
|
|
1374
|
+
onClaim: onClaimCheckin
|
|
1375
|
+
}),
|
|
1376
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreditReserveRow, {
|
|
1377
|
+
account,
|
|
1378
|
+
t,
|
|
1379
|
+
busy: reserveBusyId === account.id,
|
|
1380
|
+
onSave: onSaveCreditReserve
|
|
1381
|
+
}),
|
|
1382
|
+
account.automationToday === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1383
|
+
className: "dsm-workbuddy-xdpool-earned",
|
|
1384
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1385
|
+
className: "dsm-workbuddy-xdpool-earned-label",
|
|
1386
|
+
children: t?.("row.autoEarned") ?? "Automation today"
|
|
1387
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1388
|
+
className: "dsm-workbuddy-xdpool-earned-list",
|
|
1143
1389
|
children: [
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1390
|
+
account.automationToday.credit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1391
|
+
className: "dsm-workbuddy-xdpool-earned-row",
|
|
1392
|
+
children: t?.("row.autoFromTasks", {
|
|
1393
|
+
credit: account.automationToday.credit,
|
|
1394
|
+
energy: account.automationToday.energy,
|
|
1395
|
+
count: account.automationToday.claimed
|
|
1396
|
+
}) ?? `Tasks +${account.automationToday.credit}`
|
|
1397
|
+
}) : null,
|
|
1398
|
+
account.automationToday.checkinCredit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1399
|
+
className: "dsm-workbuddy-xdpool-earned-row",
|
|
1400
|
+
children: t?.("row.autoFromCheckin", { credit: account.automationToday.checkinCredit }) ?? `Check-in +${account.automationToday.checkinCredit}`
|
|
1401
|
+
}) : null,
|
|
1402
|
+
account.automationToday.bonusCredit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1403
|
+
className: "dsm-workbuddy-xdpool-earned-row",
|
|
1404
|
+
children: t?.("row.autoFromBonus", { credit: account.automationToday.bonusCredit }) ?? `Streak +${account.automationToday.bonusCredit}`
|
|
1405
|
+
}) : null,
|
|
1406
|
+
account.automationToday.travelCredit > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1407
|
+
className: "dsm-workbuddy-xdpool-earned-row",
|
|
1408
|
+
children: t?.("row.autoFromTravel", { credit: account.automationToday.travelCredit }) ?? `Buddy +${account.automationToday.travelCredit}`
|
|
1409
|
+
}) : null
|
|
1147
1410
|
]
|
|
1148
|
-
})
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
children: modelCooldowns.map((mc) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1152
|
-
className: "dsm-workbuddy-xdpool-account-modelcool-chip",
|
|
1153
|
-
children: t?.("row.modelCooling", {
|
|
1154
|
-
model: mc.modelId,
|
|
1155
|
-
time: formatDateTime(mc.until)
|
|
1156
|
-
}) ?? `${mc.modelId} cooling to ${formatDateTime(mc.until)}`
|
|
1157
|
-
}, mc.modelId))
|
|
1158
|
-
}) : null
|
|
1159
|
-
]
|
|
1160
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountStats, {
|
|
1161
|
-
account,
|
|
1162
|
-
t,
|
|
1163
|
-
checkinBusy: checkinBusyId === account.id,
|
|
1164
|
-
onClaim: onClaimCheckin
|
|
1165
|
-
})]
|
|
1411
|
+
})]
|
|
1412
|
+
})
|
|
1413
|
+
]
|
|
1166
1414
|
})]
|
|
1167
1415
|
});
|
|
1168
1416
|
}
|
|
@@ -1177,6 +1425,61 @@ window.__ModuleLoader__.load({
|
|
|
1177
1425
|
* layout the LaoDing plugin family uses, so the numbers stay scannable and the
|
|
1178
1426
|
* claim button sits where the eye already is.
|
|
1179
1427
|
*/
|
|
1428
|
+
/**
|
|
1429
|
+
* Reserved-credit control for one account.
|
|
1430
|
+
*
|
|
1431
|
+
* The value is committed on blur or Enter rather than on every keystroke:
|
|
1432
|
+
* each save is a settings write plus a status refresh, and a per-character
|
|
1433
|
+
* save would hammer both.
|
|
1434
|
+
*/
|
|
1435
|
+
function CreditReserveRow({ account, t, busy, onSave }) {
|
|
1436
|
+
const [draft, setDraft] = (0, react.useState)(String(account.creditReserve ?? 0));
|
|
1437
|
+
(0, react.useEffect)(() => {
|
|
1438
|
+
setDraft(String(account.creditReserve ?? 0));
|
|
1439
|
+
}, [account.creditReserve]);
|
|
1440
|
+
const commit = () => {
|
|
1441
|
+
const parsed = Number.parseInt(draft, 10);
|
|
1442
|
+
const next = Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : 0;
|
|
1443
|
+
if (next === (account.creditReserve ?? 0)) {
|
|
1444
|
+
setDraft(String(next));
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
onSave(account.id, next);
|
|
1448
|
+
};
|
|
1449
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1450
|
+
className: "dsm-workbuddy-xdpool-reserve",
|
|
1451
|
+
children: [
|
|
1452
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1453
|
+
className: "dsm-workbuddy-xdpool-reserve-label",
|
|
1454
|
+
children: t?.("row.reserveTitle") ?? "Keep at least"
|
|
1455
|
+
}),
|
|
1456
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1457
|
+
type: "number",
|
|
1458
|
+
min: 0,
|
|
1459
|
+
step: 1,
|
|
1460
|
+
value: draft,
|
|
1461
|
+
disabled: busy,
|
|
1462
|
+
className: "dsm-workbuddy-xdpool-reserve-input",
|
|
1463
|
+
"aria-label": t?.("row.reserveTitle") ?? "Keep at least",
|
|
1464
|
+
onChange: (event) => {
|
|
1465
|
+
setDraft(event.target.value);
|
|
1466
|
+
},
|
|
1467
|
+
onBlur: commit,
|
|
1468
|
+
onKeyDown: (event) => {
|
|
1469
|
+
if (event.key === "Enter") event.target.blur();
|
|
1470
|
+
}
|
|
1471
|
+
}),
|
|
1472
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1473
|
+
className: "dsm-workbuddy-xdpool-reserve-unit",
|
|
1474
|
+
children: busy ? t?.("row.reserveSaving") ?? "Saving…" : t?.("row.reserveUnit") ?? "credits"
|
|
1475
|
+
}),
|
|
1476
|
+
account.reserved === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1477
|
+
className: "dsm-workbuddy-xdpool-reserve-badge",
|
|
1478
|
+
children: t?.("row.reserveHolding") ?? "Reserved: skipped"
|
|
1479
|
+
}) : null
|
|
1480
|
+
]
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1180
1483
|
function AccountStats({ account, t, checkinBusy, onClaim }) {
|
|
1181
1484
|
const credits = account.credits;
|
|
1182
1485
|
const checkin = account.checkin;
|
|
@@ -1461,14 +1764,14 @@ window.__ModuleLoader__.load({
|
|
|
1461
1764
|
"row.imageCapable": "image input",
|
|
1462
1765
|
"row.rate": "{rate}x credits",
|
|
1463
1766
|
"row.accountsRescan": "Detect accounts again",
|
|
1767
|
+
"row.accountsScanning": "Detecting…",
|
|
1464
1768
|
"row.distTitle": "Account usage",
|
|
1465
1769
|
"row.distPriority": "Priority",
|
|
1466
|
-
"row.distPriorityHint": "
|
|
1770
|
+
"row.distPriorityHint": "Use one account until it runs out, then move to the next",
|
|
1467
1771
|
"row.distRoundRobin": "Round-robin",
|
|
1468
|
-
"row.distRoundRobinHint": "
|
|
1772
|
+
"row.distRoundRobinHint": "Take turns in order, spreading the spend evenly",
|
|
1469
1773
|
"row.distBalanced": "Balanced",
|
|
1470
|
-
"row.distBalancedHint": "Draw
|
|
1471
|
-
"row.accountsScanning": "Detecting…",
|
|
1774
|
+
"row.distBalancedHint": "Draw at random, favouring the account idle longest",
|
|
1472
1775
|
"row.resetCooldowns": "Clear all cooldowns",
|
|
1473
1776
|
"row.resetCooldownsBusy": "Clearing…",
|
|
1474
1777
|
"row.resetCooldownsDone": "Cooldowns cleared",
|
|
@@ -1478,14 +1781,38 @@ window.__ModuleLoader__.load({
|
|
|
1478
1781
|
"row.autoOn": "On",
|
|
1479
1782
|
"row.autoOff": "Off",
|
|
1480
1783
|
"row.autoBusy": "Saving…",
|
|
1481
|
-
"row.autoHintOn": "
|
|
1784
|
+
"row.autoHintOn": "Checks in, reports activity, claims task and streak rewards, and runs the buddy trip — every day.",
|
|
1482
1785
|
"row.autoHintOff": "Off: no background requests are made for you.",
|
|
1483
1786
|
"row.autoJob_report": "Activity report",
|
|
1484
1787
|
"row.autoJob_tasks": "Task rewards",
|
|
1485
1788
|
"row.autoJob_checkin": "Daily check-in",
|
|
1486
1789
|
"row.autoJob_streak": "Streak bonus",
|
|
1487
|
-
"row.
|
|
1488
|
-
"row.
|
|
1790
|
+
"row.autoJob_travel": "Buddy trip",
|
|
1791
|
+
"row.autoHourNone": "skipped today",
|
|
1792
|
+
"row.autoNever": "not run yet",
|
|
1793
|
+
"row.autoRun": "Run now",
|
|
1794
|
+
"row.autoRunning": "Running…",
|
|
1795
|
+
"row.autoRan": "Done: {count} account(s) ok, {failed} failed",
|
|
1796
|
+
"row.autoRanTasks": "Done: {claimed} task(s) claimed, +{credit} credits, +{energy} energy",
|
|
1797
|
+
"row.reserveTitle": "Keep at least",
|
|
1798
|
+
"row.reserveUnit": "credits",
|
|
1799
|
+
"row.reserveSaving": "Saving…",
|
|
1800
|
+
"row.reserveHolding": "Reserved: skipped",
|
|
1801
|
+
"row.reserveSaved": "Keeping {credits} credits",
|
|
1802
|
+
"row.reserveCleared": "Reserve cleared",
|
|
1803
|
+
"row.autoToday": "Today",
|
|
1804
|
+
"row.autoEarned": "Automation today",
|
|
1805
|
+
"row.autoEnergy": "energy",
|
|
1806
|
+
"row.autoTasksClaimed": "{count} task(s)",
|
|
1807
|
+
"row.autoRunAll": "Run now",
|
|
1808
|
+
"row.autoRunDone": "Automation pass finished",
|
|
1809
|
+
"row.autoRunTimeout": "Still running; check back in a moment",
|
|
1810
|
+
"row.autoAlreadyRunning": "A run is already in progress",
|
|
1811
|
+
"row.autoRanAll": "Ran {jobs} job(s), {ok} ok, {failed} failed",
|
|
1812
|
+
"row.autoFromTasks": "Tasks +{credit} credits · +{energy} energy · {count} task(s)",
|
|
1813
|
+
"row.autoFromCheckin": "Check-in +{credit} credits",
|
|
1814
|
+
"row.autoFromBonus": "Streak bonus +{credit} credits",
|
|
1815
|
+
"row.autoFromTravel": "Buddy travel +{credit} credits"
|
|
1489
1816
|
};
|
|
1490
1817
|
const zh = {
|
|
1491
1818
|
"row.title": "WorkBuddy 池(dsh-workbuddy-xdpool)",
|
|
@@ -1566,14 +1893,14 @@ window.__ModuleLoader__.load({
|
|
|
1566
1893
|
"row.imageCapable": "图片输入",
|
|
1567
1894
|
"row.rate": "{rate}x 积分",
|
|
1568
1895
|
"row.accountsRescan": "重新检测账号",
|
|
1896
|
+
"row.accountsScanning": "正在检测…",
|
|
1569
1897
|
"row.distTitle": "账号使用方式",
|
|
1570
1898
|
"row.distPriority": "优先模式",
|
|
1571
|
-
"row.distPriorityHint": "
|
|
1899
|
+
"row.distPriorityHint": "先用完一个账号,用完再换下一个",
|
|
1572
1900
|
"row.distRoundRobin": "轮换模式",
|
|
1573
|
-
"row.distRoundRobinHint": "
|
|
1574
|
-
"row.distBalanced": "
|
|
1575
|
-
"row.distBalancedHint": "
|
|
1576
|
-
"row.accountsScanning": "正在检测…",
|
|
1901
|
+
"row.distRoundRobinHint": "按顺序轮流使用,积分均匀分摊",
|
|
1902
|
+
"row.distBalanced": "均衡模式",
|
|
1903
|
+
"row.distBalancedHint": "随机抽取,闲置越久的账号被选中概率越高",
|
|
1577
1904
|
"row.resetCooldowns": "清除所有冷却",
|
|
1578
1905
|
"row.resetCooldownsBusy": "正在清除…",
|
|
1579
1906
|
"row.resetCooldownsDone": "冷却已清除",
|
|
@@ -1583,14 +1910,38 @@ window.__ModuleLoader__.load({
|
|
|
1583
1910
|
"row.autoOn": "已开启",
|
|
1584
1911
|
"row.autoOff": "已关闭",
|
|
1585
1912
|
"row.autoBusy": "保存中…",
|
|
1586
|
-
"row.autoHintOn": "
|
|
1913
|
+
"row.autoHintOn": "每天自动签到、上报活跃、领取任务奖励与连登奖励,并照看猫猫旅行。",
|
|
1587
1914
|
"row.autoHintOff": "已关闭:不会替你发起任何后台请求。",
|
|
1588
1915
|
"row.autoJob_report": "活跃上报",
|
|
1589
1916
|
"row.autoJob_tasks": "任务奖励",
|
|
1590
1917
|
"row.autoJob_checkin": "每日签到",
|
|
1591
1918
|
"row.autoJob_streak": "连登奖励",
|
|
1592
|
-
"row.
|
|
1593
|
-
"row.
|
|
1919
|
+
"row.autoJob_travel": "猫猫旅行",
|
|
1920
|
+
"row.autoHourNone": "当天不跑",
|
|
1921
|
+
"row.autoNever": "还没跑过",
|
|
1922
|
+
"row.autoRun": "立即运行",
|
|
1923
|
+
"row.autoRunning": "运行中…",
|
|
1924
|
+
"row.autoRan": "完成:{count} 个账号正常,{failed} 个失败",
|
|
1925
|
+
"row.autoRanTasks": "完成:领取 {claimed} 个任务,+{credit} 积分,+{energy} 能量",
|
|
1926
|
+
"row.reserveTitle": "保留积分",
|
|
1927
|
+
"row.reserveUnit": "积分",
|
|
1928
|
+
"row.reserveSaving": "保存中…",
|
|
1929
|
+
"row.reserveHolding": "已保留·暂停使用",
|
|
1930
|
+
"row.reserveSaved": "已保留 {credits} 积分",
|
|
1931
|
+
"row.reserveCleared": "已取消保留",
|
|
1932
|
+
"row.autoToday": "今日自动化",
|
|
1933
|
+
"row.autoEarned": "今日自动化获得",
|
|
1934
|
+
"row.autoEnergy": "能量",
|
|
1935
|
+
"row.autoTasksClaimed": "{count} 个任务",
|
|
1936
|
+
"row.autoRunAll": "立即运行",
|
|
1937
|
+
"row.autoRunDone": "自动化已执行完成",
|
|
1938
|
+
"row.autoRunTimeout": "仍在执行中,稍后查看结果",
|
|
1939
|
+
"row.autoAlreadyRunning": "已有一次执行正在进行",
|
|
1940
|
+
"row.autoRanAll": "已运行 {jobs} 项,{ok} 个正常,{failed} 个失败",
|
|
1941
|
+
"row.autoFromTasks": "任务 +{credit} 积分 · +{energy} 能量 · {count} 个",
|
|
1942
|
+
"row.autoFromCheckin": "签到 +{credit} 积分",
|
|
1943
|
+
"row.autoFromBonus": "连登奖励 +{credit} 积分",
|
|
1944
|
+
"row.autoFromTravel": "猫猫旅行 +{credit} 积分"
|
|
1594
1945
|
};
|
|
1595
1946
|
//#endregion
|
|
1596
1947
|
//#region src/client/index.tsx
|