@gitroll/tacitt-cli 0.6.12 → 0.6.14
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/{agent-setup-B12VbvN_.mjs → agent-setup-CEPQfjBv.mjs} +2 -2
- package/dist/agent-setup-worker.mjs +5 -5
- package/dist/cli.mjs +10 -10
- package/dist/codex-title-worker.mjs +1 -1
- package/dist/configured-preview-worker.mjs +5 -5
- package/dist/configured-session-worker.mjs +5 -5
- package/dist/{frame-B3He21G8.mjs → frame-CRm99088.mjs} +1 -1
- package/dist/{heap-Blrat--4.mjs → heap-Bh9tySJp.mjs} +12 -7
- package/dist/inspection-worker.mjs +4 -4
- package/dist/{job-CBuIMTQ0.mjs → job-CsWKWcM4.mjs} +135 -36
- package/dist/{locate-D-ZaHpI0.mjs → locate-CP2t26j2.mjs} +449 -244
- package/dist/{model-DR9odhWP.mjs → model-ChHuVKoB.mjs} +1 -1
- package/dist/operation-executor.mjs +3 -3
- package/dist/preview-worker.mjs +1 -1
- package/dist/privacy-validator.mjs +1 -1
- package/dist/{query-BYDcNKy2.mjs → query-D28k3XOr.mjs} +6044 -5706
- package/dist/{run-DQ9xyKSt.mjs → run-CiJmV__5.mjs} +6 -6
- package/dist/{src-Do-qzuMn.mjs → src-B3il9x5F.mjs} +617 -545
- package/dist/{src-CKQlTA2Z.mjs → src-CWMrGXJK.mjs} +180 -30
- package/dist/{src-DeNJ8vOD.mjs → src-CmvEJj46.mjs} +1806 -1690
- package/dist/store-database-worker.mjs +1 -1
- package/dist/web/assets/index-XdWDOC5H.js +172 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/skills/tacitt/INDEX.md +1 -1
- package/skills/tacitt/SKILL.md +5 -3
- package/skills/tacitt/references/INDEX.md +2 -2
- package/skills/tacitt/references/b-method.md +4 -2
- package/skills/tacitt/references/bootstrap.md +1 -1
- package/skills/tacitt/references/commands.md +23 -4
- package/skills/tacitt/references/journey.md +5 -3
- package/skills/tacitt/references/parallel-review.md +22 -9
- package/skills/tacitt/references/remote-workers.md +6 -2
- package/skills/tacitt/scripts/INDEX.md +5 -5
- package/skills/tacitt/scripts/answer.mjs +12 -1
- package/skills/tacitt/scripts/describe.mjs +3 -2
- package/skills/tacitt/scripts/journey-classification-tasks.mjs +2 -0
- package/skills/tacitt/scripts/journey-classification.mjs +1 -0
- package/skills/tacitt/scripts/journey-scan-timing.mjs +3 -2
- package/skills/tacitt/scripts/journey-state.d.mts +3 -0
- package/skills/tacitt/scripts/journey-state.mjs +8 -1
- package/skills/tacitt/scripts/journey.mjs +31 -1
- package/skills/tacitt/scripts/privacy-validator.mjs +160 -40
- package/skills/tacitt/scripts/review.d.mts +1 -0
- package/skills/tacitt/scripts/review.mjs +296 -35
- package/dist/web/assets/index-BgDdPL1c.js +0 -172
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
interruptedReviews,
|
|
13
13
|
isIncluded,
|
|
14
14
|
leftOutField,
|
|
15
|
+
accountFormationField,
|
|
15
16
|
activeTerms,
|
|
16
17
|
stageFingerprint,
|
|
17
18
|
procedureFor,
|
|
@@ -87,6 +88,27 @@ async function prepareInitialFreeze(run, journeyId, call, view) {
|
|
|
87
88
|
} catch (error) {
|
|
88
89
|
// A large first freeze can outlast one helper command; captured roots persist for the rerun.
|
|
89
90
|
if (error?.code === 'CLI_UNAVAILABLE') return { stage: 'freeze', status: 'running', startedAt }
|
|
91
|
+
// Every session is already on the profile or left out (ADR 0276): there is no Send.
|
|
92
|
+
if (error?.code === 'ACCOUNT_NOTHING_TO_SEND') {
|
|
93
|
+
const stopped = await call('journey.get', { journeyId })
|
|
94
|
+
return {
|
|
95
|
+
stage: 'freeze',
|
|
96
|
+
status: 'nothing-to-send',
|
|
97
|
+
startedAt,
|
|
98
|
+
...accountFormationField(stopped),
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (['ACCOUNT_WORKS_UNAVAILABLE', 'ACCOUNT_SIGNED_OUT'].includes(error?.code)) {
|
|
102
|
+
const stopped = await call('journey.get', { journeyId })
|
|
103
|
+
if (stopped.accountReadRecovery)
|
|
104
|
+
return {
|
|
105
|
+
stage: 'freeze',
|
|
106
|
+
status: 'blocked',
|
|
107
|
+
startedAt,
|
|
108
|
+
accountReadRecovery: stopped.accountReadRecovery,
|
|
109
|
+
next: 'journey.prepare',
|
|
110
|
+
}
|
|
111
|
+
}
|
|
90
112
|
throw error
|
|
91
113
|
}
|
|
92
114
|
const completed = await call('journey.get', { journeyId })
|
|
@@ -194,12 +216,16 @@ async function awaitDecision(run, journeyId, waitMs, call, sleep, ensureHost) {
|
|
|
194
216
|
command: 'await',
|
|
195
217
|
from,
|
|
196
218
|
phase,
|
|
219
|
+
...(view.accountReadRecovery
|
|
220
|
+
? { accountReadRecovery: view.accountReadRecovery, next: 'journey.prepare' }
|
|
221
|
+
: {}),
|
|
197
222
|
changed,
|
|
198
223
|
waitedMs: Date.now() - started,
|
|
199
224
|
revision: view.revision,
|
|
200
225
|
blockedWorks: blocked,
|
|
201
226
|
...(held.length ? { interruptedReviews: held } : {}),
|
|
202
227
|
...leftOutField(view),
|
|
228
|
+
...accountFormationField(view),
|
|
203
229
|
...(retried.length ? { retriedWorks: retried, next: 'journey.prepare' } : {}),
|
|
204
230
|
...(handoff ? { handoff: { panel: await ensureHost(), next: 'end-turn' } } : {}),
|
|
205
231
|
}
|
|
@@ -212,7 +238,7 @@ async function runPhaseCore(
|
|
|
212
238
|
{ run, journeyId, command, stage, refresh = false, limit = 3, waitMs = 0, sleep, ensureHost },
|
|
213
239
|
call,
|
|
214
240
|
) {
|
|
215
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit >
|
|
241
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 24) throw new Error('INVALID_ARGUMENTS')
|
|
216
242
|
// Append-batch consolidation uses immutable local drafts. No current journey view is
|
|
217
243
|
// needed until publication; retain write recovery and live value settlement on that path.
|
|
218
244
|
if (stage === 'cards' && !refresh && ['consolidate', 'ingest'].includes(command)) {
|
|
@@ -264,12 +290,16 @@ async function runPhaseCore(
|
|
|
264
290
|
? { classification: await classificationProgress(manifest) }
|
|
265
291
|
: {}),
|
|
266
292
|
phase: await currentPhase(run, view),
|
|
293
|
+
...(view.accountReadRecovery
|
|
294
|
+
? { accountReadRecovery: view.accountReadRecovery, next: 'journey.prepare' }
|
|
295
|
+
: {}),
|
|
267
296
|
revision: view.revision,
|
|
268
297
|
readingComplete: view.readingComplete,
|
|
269
298
|
pending: activeTerms(view).filter((term) => term.disposition === 'pending').length,
|
|
270
299
|
blockedWorks: blockedWorks(view),
|
|
271
300
|
...(interruptions.length ? { interruptedReviews: interruptions } : {}),
|
|
272
301
|
...leftOutField(view),
|
|
302
|
+
...accountFormationField(view),
|
|
273
303
|
answersRevision: view.privacy.answersRevision,
|
|
274
304
|
...packagingProgress(view),
|
|
275
305
|
coldElapsedMs,
|
|
@@ -5112,6 +5112,14 @@ function object(shape, params) {
|
|
|
5112
5112
|
};
|
|
5113
5113
|
return new ZodObject(def);
|
|
5114
5114
|
}
|
|
5115
|
+
function strictObject(shape, params) {
|
|
5116
|
+
return new ZodObject({
|
|
5117
|
+
type: "object",
|
|
5118
|
+
shape,
|
|
5119
|
+
catchall: never(),
|
|
5120
|
+
...normalizeParams(params)
|
|
5121
|
+
});
|
|
5122
|
+
}
|
|
5115
5123
|
function looseObject(shape, params) {
|
|
5116
5124
|
return new ZodObject({
|
|
5117
5125
|
type: "object",
|
|
@@ -5400,7 +5408,7 @@ const range = object({
|
|
|
5400
5408
|
start: number().int().nonnegative(),
|
|
5401
5409
|
end: number().int().nonnegative()
|
|
5402
5410
|
}).strict();
|
|
5403
|
-
const digest$
|
|
5411
|
+
const digest$4 = string().regex(/^[a-f0-9]{64}$/u);
|
|
5404
5412
|
/** Original static title mask provenance for keyword-only preview/packaging. */
|
|
5405
5413
|
const classificationTitleMaskSchema = object({
|
|
5406
5414
|
inputRange: range,
|
|
@@ -5417,14 +5425,66 @@ const classificationTitleMaskSchema = object({
|
|
|
5417
5425
|
originalPointer: string().nullable(),
|
|
5418
5426
|
outputPointer: string().nullable(),
|
|
5419
5427
|
sourceRange: range.nullable(),
|
|
5420
|
-
inputSha256: digest$
|
|
5421
|
-
outputSha256: digest$
|
|
5428
|
+
inputSha256: digest$4,
|
|
5429
|
+
outputSha256: digest$4,
|
|
5422
5430
|
context: object({
|
|
5423
5431
|
start: number().int().nonnegative(),
|
|
5424
5432
|
text: string()
|
|
5425
5433
|
}).strict()
|
|
5426
5434
|
}).strict();
|
|
5427
5435
|
//#endregion
|
|
5436
|
+
//#region packages/application/src/journey/account-works.ts
|
|
5437
|
+
const digest$3 = string().regex(/^[0-9a-f]{64}$/u);
|
|
5438
|
+
const stored = object({
|
|
5439
|
+
/** Wire field from issue #131; a formation reply without it is read as no stored metadata. */
|
|
5440
|
+
metadataSha256: digest$3.nullish().transform((value) => value ?? null),
|
|
5441
|
+
key: digest$3,
|
|
5442
|
+
sessionKey: string().regex(/^sess-pilot\/[^/]+\/[^/]+\/[^/]+$/u).nullable(),
|
|
5443
|
+
sha256: digest$3,
|
|
5444
|
+
byteLength: number().int().positive(),
|
|
5445
|
+
lastAt: datetime()
|
|
5446
|
+
});
|
|
5447
|
+
const access = _enum([
|
|
5448
|
+
"public",
|
|
5449
|
+
"private",
|
|
5450
|
+
"removed"
|
|
5451
|
+
]);
|
|
5452
|
+
const accountWorksInventorySchema = object({
|
|
5453
|
+
works: array(object({
|
|
5454
|
+
logicalWorkId: uuid(),
|
|
5455
|
+
title: string().min(1).max(300),
|
|
5456
|
+
access,
|
|
5457
|
+
unitAccess: access,
|
|
5458
|
+
sessions: array(stored)
|
|
5459
|
+
})),
|
|
5460
|
+
unassigned: array(stored.extend({ removedFromWork: uuid().nullish().transform((value) => value ?? null) }))
|
|
5461
|
+
});
|
|
5462
|
+
const accountWorksSchema = discriminatedUnion("status", [
|
|
5463
|
+
strictObject({
|
|
5464
|
+
status: literal("read"),
|
|
5465
|
+
subject: string().min(1).max(128),
|
|
5466
|
+
at: datetime(),
|
|
5467
|
+
inventory: accountWorksInventorySchema,
|
|
5468
|
+
/** Families with a key unassigned after its Work's removal: no Work, not sent (D4). */
|
|
5469
|
+
leftOut: array(strictObject({
|
|
5470
|
+
rootSessionId: string().min(1).max(128),
|
|
5471
|
+
removedWorkId: uuid()
|
|
5472
|
+
})).default([]),
|
|
5473
|
+
/** Families with a held key that are not cleanly placed: no Work, not sent (D9). */
|
|
5474
|
+
heldBack: array(string().min(1).max(128)).default([]),
|
|
5475
|
+
/** Every family was left out or held back: no Work and no snapshot (#129 review). */
|
|
5476
|
+
nothingToSend: literal(true).optional()
|
|
5477
|
+
}),
|
|
5478
|
+
strictObject({
|
|
5479
|
+
status: literal("signed-out"),
|
|
5480
|
+
at: datetime()
|
|
5481
|
+
}),
|
|
5482
|
+
strictObject({
|
|
5483
|
+
status: literal("unavailable"),
|
|
5484
|
+
at: datetime()
|
|
5485
|
+
})
|
|
5486
|
+
]);
|
|
5487
|
+
//#endregion
|
|
5428
5488
|
//#region packages/application/src/journey/profile.ts
|
|
5429
5489
|
/**
|
|
5430
5490
|
* Passport's own rules (talent-platform `profile-settings.ts`): 1 to 39 letters and digits with
|
|
@@ -9833,6 +9893,8 @@ const decisionCardSchema = decisionCardInputSchema.extend({ answer: object({
|
|
|
9833
9893
|
rule: string().max(4001),
|
|
9834
9894
|
additionalRule: string().max(2e3),
|
|
9835
9895
|
remember: boolean(),
|
|
9896
|
+
/** Where the answer came from; only the person's panel Hide is remembered (issue #126). */
|
|
9897
|
+
source: _enum(["conversation", "panel"]).optional(),
|
|
9836
9898
|
excludedTermKeys: array(string().min(1)).max(2e4).optional()
|
|
9837
9899
|
}).strict().nullable() }).strict();
|
|
9838
9900
|
const journeyPrivacySchema = object({
|
|
@@ -10165,7 +10227,8 @@ const reviewInterruptionSchema = object({
|
|
|
10165
10227
|
}).strict();
|
|
10166
10228
|
const journeyWorkSchema = object({
|
|
10167
10229
|
id: journeyIdSchema,
|
|
10168
|
-
title
|
|
10230
|
+
/** 240 characters; an `account` title holds the server's 300 (ADR 0276 D2). */
|
|
10231
|
+
title: string().trim().min(1).max(300),
|
|
10169
10232
|
/** Statically processed repository or folder name; the original stays in the private plan. */
|
|
10170
10233
|
projectName: label,
|
|
10171
10234
|
projectType: journeyWorkTypeSchema.nullable(),
|
|
@@ -10181,7 +10244,11 @@ const journeyWorkSchema = object({
|
|
|
10181
10244
|
description: string(),
|
|
10182
10245
|
reason: string()
|
|
10183
10246
|
}).strict().optional(),
|
|
10184
|
-
titleOrigin: _enum([
|
|
10247
|
+
titleOrigin: _enum([
|
|
10248
|
+
"model",
|
|
10249
|
+
"explicit",
|
|
10250
|
+
"account"
|
|
10251
|
+
]),
|
|
10185
10252
|
explicitTitleId: journeyIdSchema.nullable(),
|
|
10186
10253
|
accessOrigin: _enum([
|
|
10187
10254
|
"default",
|
|
@@ -10219,6 +10286,8 @@ const journeyWorkSchema = object({
|
|
|
10219
10286
|
inputRevision: count$1.min(1),
|
|
10220
10287
|
/** Placement created this Work (create-work or a sorting "new" decision): its name is generic. */
|
|
10221
10288
|
createdByPlacement: literal(true).optional(),
|
|
10289
|
+
/** Rebuilt at formation from the account Work with this id (ADR 0276 D1); never classified. */
|
|
10290
|
+
accountWork: literal(true).optional(),
|
|
10222
10291
|
/** Host-owned eligibility after removal-only regrouping; never authorizes output by itself. */
|
|
10223
10292
|
reviewReuseFrom: object({
|
|
10224
10293
|
inputRevision: count$1.min(1),
|
|
@@ -10274,7 +10343,7 @@ const journeyWorkSchema = object({
|
|
|
10274
10343
|
sentBundleId: journeyIdSchema.optional(),
|
|
10275
10344
|
sentAccess: _enum(["public", "private"]).optional()
|
|
10276
10345
|
}).strict().nullable()
|
|
10277
|
-
}).strict();
|
|
10346
|
+
}).strict().refine((work) => work.titleOrigin === "account" || work.title.length <= 240, { path: ["title"] });
|
|
10278
10347
|
const journeyConsentSchema = object({
|
|
10279
10348
|
provider: label,
|
|
10280
10349
|
allowedAt: datetime(),
|
|
@@ -10296,7 +10365,7 @@ const journeyExceptionSchema = object({
|
|
|
10296
10365
|
value: string().min(1).max(1024)
|
|
10297
10366
|
}).strict();
|
|
10298
10367
|
object({
|
|
10299
|
-
formatVersion: literal(10),
|
|
10368
|
+
formatVersion: literal([10, 11]),
|
|
10300
10369
|
outputVersion: number().int().positive().optional(),
|
|
10301
10370
|
classificationRevision: count$1.nullable(),
|
|
10302
10371
|
privacy: journeyPrivacySchema,
|
|
@@ -10340,6 +10409,11 @@ object({
|
|
|
10340
10409
|
/** ADR 0086: per-value Hide or Keep over the term types' answers; absent means none. */
|
|
10341
10410
|
valueOverrides: array(journeyValueOverrideSchema).max(1e4).optional(),
|
|
10342
10411
|
/**
|
|
10412
|
+
* Values the person hid in earlier journeys on this machine, frozen at formation (issue #126).
|
|
10413
|
+
* Private: never in a view, reader guidance or anything sent.
|
|
10414
|
+
*/
|
|
10415
|
+
rememberedHides: array(string().min(1).max(1024)).max(1e5).optional(),
|
|
10416
|
+
/**
|
|
10343
10417
|
* ADR 0086: the snapshot is read by dictionary review. A snapshot without it was read by B
|
|
10344
10418
|
* review, whose evidence this release no longer renders, so it is obsolete.
|
|
10345
10419
|
*/
|
|
@@ -10361,6 +10435,8 @@ object({
|
|
|
10361
10435
|
* confirmation and Retry set `read`; late classification records only a failure. Absent in a
|
|
10362
10436
|
* journey of an earlier version, which reads as not `read`.
|
|
10363
10437
|
*/
|
|
10438
|
+
/** Formation read only; never establishes access proof. */
|
|
10439
|
+
accountWorks: accountWorksSchema.optional(),
|
|
10364
10440
|
accountRead: object({
|
|
10365
10441
|
status: _enum([
|
|
10366
10442
|
"read",
|
|
@@ -10644,43 +10720,82 @@ object({
|
|
|
10644
10720
|
reviewBatchSchema.omit({ digest: true });
|
|
10645
10721
|
//#endregion
|
|
10646
10722
|
//#region packages/application/src/journey/terms/locate.ts
|
|
10647
|
-
/**
|
|
10648
|
-
|
|
10649
|
-
|
|
10723
|
+
/**
|
|
10724
|
+
* Issue #140: per batch and field, contiguous core and context chunks in offset order, never
|
|
10725
|
+
* joined across fields, field revisions or gaps. A core boundary maps to the NFC length of the
|
|
10726
|
+
* text before it.
|
|
10727
|
+
*/
|
|
10728
|
+
function* termSearchRuns(batches) {
|
|
10650
10729
|
for (const batch of batches) {
|
|
10651
|
-
const fields = Map.groupBy(batch.chunks
|
|
10652
|
-
for (const
|
|
10653
|
-
let
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10730
|
+
const fields = Map.groupBy(batch.chunks, (chunk) => JSON.stringify([chunk.fieldId, chunk.fieldHash]));
|
|
10731
|
+
for (const group of fields.values()) {
|
|
10732
|
+
let run = [];
|
|
10733
|
+
const runs = [run];
|
|
10734
|
+
for (const chunk of group.toSorted((a, b) => a.offset - b.offset)) {
|
|
10735
|
+
const last = run.at(-1);
|
|
10736
|
+
if (last && last.offset + last.text.length !== chunk.offset) runs.push(run = []);
|
|
10737
|
+
run.push(chunk);
|
|
10738
|
+
}
|
|
10739
|
+
for (const chunks of runs) {
|
|
10740
|
+
if (!chunks.some((chunk) => chunk.core)) continue;
|
|
10741
|
+
const raw = chunks.map((chunk) => chunk.text).join("");
|
|
10742
|
+
const text = raw.normalize("NFC");
|
|
10743
|
+
const at = (end) => Math.min(text.length, raw.slice(0, end).normalize("NFC").length);
|
|
10744
|
+
const cores = [];
|
|
10745
|
+
let offset = 0;
|
|
10746
|
+
for (const chunk of chunks) {
|
|
10747
|
+
const start = offset;
|
|
10748
|
+
offset += chunk.text.length;
|
|
10749
|
+
if (!chunk.core) continue;
|
|
10750
|
+
const last = cores.at(-1);
|
|
10751
|
+
if (last && last[1] === start) last[1] = offset;
|
|
10752
|
+
else cores.push([start, offset]);
|
|
10661
10753
|
}
|
|
10662
|
-
|
|
10663
|
-
|
|
10754
|
+
yield {
|
|
10755
|
+
batch,
|
|
10756
|
+
chunks,
|
|
10757
|
+
text,
|
|
10758
|
+
cores: cores.map(([start, end]) => [at(start), at(end)])
|
|
10759
|
+
};
|
|
10664
10760
|
}
|
|
10665
|
-
if (text) texts.push({
|
|
10666
|
-
workId: batch.workId,
|
|
10667
|
-
text: text.normalize("NFC")
|
|
10668
|
-
});
|
|
10669
10761
|
}
|
|
10670
10762
|
}
|
|
10671
|
-
return texts;
|
|
10672
10763
|
}
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10764
|
+
/**
|
|
10765
|
+
* Occurrences of `value` in a run: `owned` counts non-overlapping occurrences that start in a
|
|
10766
|
+
* core range; `first` is the first occurrence overlapping a core range, or -1. An occurrence that
|
|
10767
|
+
* starts outside the core is skipped by one position only, so it never hides an owned one.
|
|
10768
|
+
*/
|
|
10769
|
+
function runOccurrences(run, value) {
|
|
10770
|
+
let owned = 0, first = -1;
|
|
10771
|
+
if (!value) return {
|
|
10772
|
+
owned,
|
|
10773
|
+
first
|
|
10774
|
+
};
|
|
10775
|
+
for (let at = run.text.indexOf(value); at >= 0;) {
|
|
10776
|
+
const end = at + value.length;
|
|
10777
|
+
if (run.cores.some(([start, stop]) => at >= start && at < stop)) {
|
|
10778
|
+
owned++;
|
|
10779
|
+
if (first < 0) first = at;
|
|
10780
|
+
at = run.text.indexOf(value, end);
|
|
10781
|
+
continue;
|
|
10782
|
+
}
|
|
10783
|
+
if (first < 0 && run.cores.some(([start, stop]) => at < stop && end > start)) first = at;
|
|
10784
|
+
at = run.text.indexOf(value, at + 1);
|
|
10785
|
+
}
|
|
10786
|
+
return {
|
|
10787
|
+
owned,
|
|
10788
|
+
first
|
|
10789
|
+
};
|
|
10677
10790
|
}
|
|
10678
10791
|
/**
|
|
10679
|
-
* ADR 0086: a value is kept only if it occurs verbatim (NFC,
|
|
10680
|
-
*
|
|
10792
|
+
* ADR 0086, refined by issue #140: a value is kept only if it occurs verbatim (NFC,
|
|
10793
|
+
* case-sensitive) in a pack field's contiguous core and context text, overlapping a core chunk;
|
|
10794
|
+
* only occurrences that start in a core chunk are counted. Its complete admitted NFC value
|
|
10795
|
+
* becomes one dictionary entry (ADR 0088).
|
|
10681
10796
|
*/
|
|
10682
10797
|
function locateTerms(batches, terms) {
|
|
10683
|
-
const
|
|
10798
|
+
const runs = [...termSearchRuns(batches)];
|
|
10684
10799
|
const located = /* @__PURE__ */ new Map();
|
|
10685
10800
|
const unlocatedIndices = [];
|
|
10686
10801
|
let kept = 0, unlocated = 0;
|
|
@@ -10693,20 +10808,25 @@ function locateTerms(batches, terms) {
|
|
|
10693
10808
|
}];
|
|
10694
10809
|
}));
|
|
10695
10810
|
for (const { type, value, index } of unique.values()) {
|
|
10696
|
-
|
|
10811
|
+
let count = 0;
|
|
10812
|
+
let workId;
|
|
10813
|
+
if (!value.includes("█") && admitCustomTerm(value)?.value === value) for (const run of runs) {
|
|
10814
|
+
const { owned, first } = runOccurrences(run, value);
|
|
10815
|
+
if (first < 0) continue;
|
|
10816
|
+
count += owned;
|
|
10817
|
+
workId ??= run.batch.workId;
|
|
10818
|
+
}
|
|
10819
|
+
if (workId === void 0) {
|
|
10697
10820
|
unlocated++;
|
|
10698
10821
|
unlocatedIndices.push(index);
|
|
10699
10822
|
continue;
|
|
10700
10823
|
}
|
|
10701
10824
|
kept++;
|
|
10702
|
-
const holders = texts.filter((item) => item.text.includes(value));
|
|
10703
|
-
const first = holders[0];
|
|
10704
|
-
if (!first) continue;
|
|
10705
10825
|
located.set(JSON.stringify([type, value]), {
|
|
10706
10826
|
type,
|
|
10707
10827
|
value,
|
|
10708
|
-
count
|
|
10709
|
-
workId
|
|
10828
|
+
count,
|
|
10829
|
+
workId
|
|
10710
10830
|
});
|
|
10711
10831
|
}
|
|
10712
10832
|
return {
|