@g1cloud/bpmn-modeler-next 5.0.0-beta.4 → 5.0.0-beta.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/adapter/annotationImportDocking.d.ts +28 -0
  2. package/dist/adapter/i18n.d.ts +38 -6
  3. package/dist/adapter/i18nBackfill.d.ts +64 -0
  4. package/dist/adapter/translationLocaleCopy.d.ts +11 -0
  5. package/dist/adapter/translationLocaleRestore.d.ts +86 -0
  6. package/dist/agent/agentBatch.d.ts +7 -1
  7. package/dist/agent/describeProcess.d.ts +29 -2
  8. package/dist/agent/geometryAudit.d.ts +14 -0
  9. package/dist/agent/resolver/documentIndex.d.ts +12 -0
  10. package/dist/agent/resolver/index.d.ts +25 -2
  11. package/dist/agent/resolver/issues.d.ts +53 -0
  12. package/dist/agent/resolver/localeTexts.d.ts +24 -0
  13. package/dist/agent/resolver/lower.d.ts +29 -4
  14. package/dist/agent/resolver/routeRepair.d.ts +64 -0
  15. package/dist/agent/resolver/validate.d.ts +10 -1
  16. package/dist/agent/symbolicOp.d.ts +20 -2
  17. package/dist/bpmn-modeler-next.css +1 -1
  18. package/dist/bpmn-modeler.js +15595 -13484
  19. package/dist/bpmn-modeler.umd.cjs +104 -104
  20. package/dist/command/commandSeam.d.ts +2 -1
  21. package/dist/command/setTranslations.d.ts +42 -0
  22. package/dist/command/translationCommands.d.ts +11 -0
  23. package/dist/command/updateTranslation.d.ts +31 -0
  24. package/dist/core/hints.d.ts +29 -0
  25. package/dist/core/ir.d.ts +48 -1
  26. package/dist/editor/controller.d.ts +33 -1
  27. package/dist/editor/editLock.d.ts +9 -0
  28. package/dist/headless/modeler.d.ts +16 -2
  29. package/dist/index.d.ts +7 -0
  30. package/dist/view/BpmnDisplayLocaleSwitcher.vue.d.ts +6 -0
  31. package/dist/view/BpmnModelerView.vue.d.ts +7 -0
  32. package/dist/view/i18nDisplay.d.ts +87 -0
  33. package/dist/view/minimap.d.ts +25 -0
  34. package/package.json +3 -2
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 주석 연관선의 가져오기 도킹 원점 (B-139) — 주석 쪽 끝점의 `original` 이 **주석 밖**이면 주석 중심으로 옮긴다.
3
+ *
4
+ * bpmn-js `ImportDockingFix` 는 가져올 때 연결선 끝점마다 `original`(도형이 움직일 때 끝점이 따라갈 기준)을
5
+ * 「끝 구간 연장선 × 도형 중심 십자선」 교점 중 중심에 가까운 쪽으로 잡는다. 납작한 주석(높이 30 안팎)에 얕은
6
+ * 사선 연관이 닿으면 그 교점이 **주석 밖**이고(이관 레거시 연관 끝점 ≈ 25%), 주석이나 앵커를 옮기면 끝점이 그
7
+ * 상대 위치를 따라가 주석 밖에 남는다 = 연관선이 주석에서 떨어진다(`edge-endpoint-detached`).
8
+ *
9
+ * 🔴 **resolver 가 아니라 가져오기에 건다** — 에이전트 하강의 안전망(B-98 재도킹)은 반려될 수 있고, **GUI 이동에는
10
+ * 안전망이 아예 없다**(표본 125 = 도구가 주석을 옮겨 연관이 얕아진 문서를 사람이 GUI 로 옮기다 끊었다). 캔버스 ·
11
+ * 헤드리스 양쪽 가져오기에 등록한다. 중심으로 두면 bpmn-js 의 의도(「중심 쪽 원점 → 앵커를 향한 면에 붙는다」)가
12
+ * 살아난다. 주석 안 원점 · 주석이 아닌 끝 · 연관이 아닌 연결선은 건드리지 않는다. 저장되는 DI 는 바뀌지 않는다
13
+ * (`original` 은 직렬화되지 않는다 — 다음 이동부터 다르다).
14
+ *
15
+ * ⚠ **bpmn-js 내부 이벤트(`bpmnElement.added`)와 `ImportDockingFix` 의 원점 규칙에 기댄다** — pin 상향 게이트 =
16
+ * `annotationImportDocking.browser.test.ts`(`translationLocaleCopy` 와 같은 처지).
17
+ */
18
+ type Any = any;
19
+ export declare class AnnotationImportDocking {
20
+ static $inject: string[];
21
+ constructor(eventBus: Any);
22
+ }
23
+ /** bpmn-js 모듈 — 서비스 이름 = `annotationImportDocking`. 헤드리스 기본 셋과 `BpmnModelerView` 가 붙인다. */
24
+ export declare const AnnotationImportDockingModule: {
25
+ __init__: string[];
26
+ annotationImportDocking: (string | typeof AnnotationImportDocking)[];
27
+ };
28
+ export {};
@@ -1,9 +1,41 @@
1
+ export declare const I18N_NS = "http://www.omg.org/spec/BPMN/non-normative/extensions/i18n/1.0";
2
+ export declare const I18N_PREFIX = "i18n";
3
+ /** 번역 칸 moddle 타입. */
4
+ export declare const I18N_TRANSLATION_TYPE = "i18n:Translation";
5
+ type Any = any;
6
+ /**
7
+ * 라벨 문구가 실제로 사는 (객체, 키) — bpmn-js `LabelUtil.getLabelAttr` 와 같은 판정.
8
+ * 주석은 `text`, 그룹은 `categoryValueRef.value`, 나머지는 `name`.
9
+ */
10
+ export declare function labelSlot(bo: Any): {
11
+ target: Any;
12
+ key: string;
13
+ } | undefined;
14
+ /** 요소의 번역 칸 전부(`extensionElements` 안의 `i18n:Translation`). */
15
+ export declare function translationsOf(bo: Any): Any[];
16
+ /** 번역 칸의 로케일. */
17
+ export declare function translationLocale(t: Any): string | undefined;
18
+ /** 요소의 확인 요청 표식 전부(`bwl:ReviewRequest` — 상태 표식 · C-1). */
19
+ export declare function reviewRequestsOf(bo: Any): Any[];
1
20
  /**
2
- * 레거시 bpmn-i18n-moddle 호환 (백로그 B-4).
21
+ * 문서 언어 설정(B-4) — 설계 언어(고객에게 전달하는 설계 문서의 언어 · `name` 이 따른다) + 병기 언어(함께 최신으로
22
+ * 유지할 언어들). 호스트 그룹 설정(`designLocale` · `companionLocales`)과 같은 이름이라 그대로 넘긴다.
23
+ * 미설정(`undefined`) = 기능 끔.
24
+ */
25
+ export interface BpmnDocumentLocales {
26
+ designLocale: string;
27
+ companionLocales: string[];
28
+ }
29
+ /** 문서 언어 목록 — 설계 언어가 맨 앞 · 병기 언어에서 설계 언어와 중복은 뺀다. */
30
+ export declare function documentLocalesOf(config: BpmnDocumentLocales): string[];
31
+ /** 루트 `<bpmn:definitions xml:lang>` — 번역 칸으로 판정되지 않는 `name` 의 언어. */
32
+ export declare function rootLangOf(definitions: Any): string | undefined;
33
+ /**
34
+ * 요소 라벨의 문서 언어별 문구(B-4 ④) — 표시 판정(`view/i18nDisplay` `resolve`)과 **같은 규칙**이다:
35
+ * `name` 의 언어가 그 언어면 `name` → 아니면 그 언어의 번역 칸(`xml:lang` 있는 칸 · 문구 있음) → 없으면 빠진다
36
+ * (= 미번역). `name` 의 언어 = 같은 문구의 번역 칸 로케일 → 없으면 루트 `xml:lang` → 설계 언어.
3
37
  *
4
- * 스키마 자체는 유지한다 — 기존 운영 문서(실측 112곳 확장)와의 호환 필수.
5
- * 재설계 대상은 스키마가 아니라 적용 방식: 레거시 bpmnTranslationService 의
6
- * commandStack 우회 변조를 표시용/저장용 라벨 분리로 대체한다.
38
+ * 에이전트 대면 read(`describeProcess` 의 `names`/`texts`)와 에이전트 쓰기의 「바뀌었나」 판정이 같이 쓴다.
7
39
  */
8
- export declare const I18N_NS = "http://www.omg.org/spec/BPMN/non-normative/extensions/i18n/1.0";
9
- export declare const I18N_PREFIX = "i18n";
40
+ export declare function localeTextsOf(bo: Any, config: BpmnDocumentLocales, rootLang?: string): Record<string, string>;
41
+ export {};
@@ -0,0 +1,64 @@
1
+ type Any = any;
2
+ /** 문자 체계 — 판정에 쓰는 것은 한글 · 가나뿐이다. */
3
+ export type ScriptKind = 'hangul' | 'kana' | 'mixed' | 'han' | 'other';
4
+ export interface ScriptInference {
5
+ script: ScriptKind;
6
+ /** 문자 체계로 정해지는 언어 — 한글 = ko · 가나 = ja · 그 밖 = 없음. */
7
+ locale?: 'ko' | 'ja';
8
+ }
9
+ /** 문구의 문자 체계 판정. 한글과 가나가 함께 있으면 `mixed`(판정 불가). */
10
+ export declare function inferScriptLocale(text: string): ScriptInference;
11
+ /**
12
+ * 루트 판정의 근거.
13
+ * `kept` 이미 있다 · `matched` 번역 칸과 같은 이름들의 공통 언어 · `script` 문자 체계가 한 언어로 모인다 ·
14
+ * `ambiguous` 공통 언어가 여럿이고 문자 체계로도 못 고른다 · `mixed` 근거가 서로 다른 언어 · `no-evidence` 근거 없음
15
+ */
16
+ export type RootLocaleReason = 'kept' | 'matched' | 'script' | 'ambiguous' | 'mixed' | 'no-evidence';
17
+ /** 계획 항목이 가리키는 요소 — 미리보기 화면이 사람에게 보여 줄 최소 정보. */
18
+ export interface LocaleBackfillElement {
19
+ id: string;
20
+ /** moddle 타입(`bpmn:Task` 등). */
21
+ type: string;
22
+ /** 계획 시점의 라벨 문구. 적용은 이 문구가 그대로일 때만 쓴다. */
23
+ name: string;
24
+ }
25
+ export interface LocaleBackfillPlan {
26
+ root: {
27
+ /** 지금 루트 `xml:lang`. */
28
+ current?: string;
29
+ /** 새로 쓸 값 — `current` 가 있거나 판정 불가면 없다. */
30
+ proposed?: string;
31
+ reason: RootLocaleReason;
32
+ };
33
+ /** 더할 번역 칸(본문 = 그 요소의 `name`). */
34
+ additions: Array<LocaleBackfillElement & {
35
+ locale: string;
36
+ }>;
37
+ /** 언어 기록이 없고 문자 체계로도 못 가르는 이름 — 루트를 따른다 · 사람 확인 대상. */
38
+ undecided: Array<LocaleBackfillElement & {
39
+ script: ScriptKind;
40
+ }>;
41
+ /** 이름이 언어 있는 칸 어느 것과도 다르다(칸은 있다) — 백필 대상 아님(별도 정리). */
42
+ drift: LocaleBackfillElement[];
43
+ /**
44
+ * 이름이 언어 있는 칸과 같은 요소의 분포 — 키 = 일치한 로케일(정렬 · `+` 연결, 예 `ja` · `ja+ko`).
45
+ * 루트 판정의 근거이고, 판정 불가 문서에서 사람이 루트를 고를 근거다.
46
+ */
47
+ matchedBy: Record<string, number>;
48
+ /**
49
+ * 칸 언어 ↔ 문자 체계 불일치(레거시 복사본 번역 흔적 · F8) — **기록 대상 아님**(별도 정리).
50
+ * `script` = `kana` · `hangul` 은 그 칸 언어가 아닌 문자 · `han` 은 ko 칸이 한자만이고 다른 칸과 같은 문구(참고값 · 사람 판단).
51
+ */
52
+ scriptMismatch: Array<LocaleBackfillElement & {
53
+ locale: string;
54
+ script: ScriptKind;
55
+ }>;
56
+ }
57
+ /** 언어 백필 계획 — 문서를 바꾸지 않는다. */
58
+ export declare function planLocaleBackfill(definitions: Any): LocaleBackfillPlan;
59
+ /**
60
+ * 계획을 문서에 쓴다 — 바꾼 곳 수를 돌려준다. **멱등**이고 계획 뒤 문서가 바뀌었어도 덮지 않는다:
61
+ * 루트가 이미 있으면 루트를 건너뛰고, 요소는 지금도 「언어 기록 없음 + 이름이 계획 때 그대로」일 때만 쓴다.
62
+ */
63
+ export declare function applyLocaleBackfill(definitions: Any, plan: LocaleBackfillPlan): number;
64
+ export {};
@@ -0,0 +1,11 @@
1
+ type Any = any;
2
+ export declare class TranslationLocaleCopy {
3
+ static $inject: string[];
4
+ constructor(eventBus: Any);
5
+ }
6
+ /** bpmn-js 모듈 — 서비스 이름 = `translationLocaleCopy`. 헤드리스 기본 셋과 `BpmnModelerView` 가 붙인다. */
7
+ export declare const TranslationLocaleCopyModule: {
8
+ __init__: string[];
9
+ translationLocaleCopy: (string | typeof TranslationLocaleCopy)[];
10
+ };
11
+ export {};
@@ -0,0 +1,86 @@
1
+ import { ScriptKind } from './i18nBackfill';
2
+ type Any = any;
3
+ /** 번역 칸 하나의 상태 — `locale` 없음 = `xml:lang` 이 없는 칸. */
4
+ export interface TranslationCellState {
5
+ locale?: string;
6
+ body: string;
7
+ }
8
+ /** 요소 하나의 번역 칸 상태(문서 순서). */
9
+ export interface TranslationElementState {
10
+ /** moddle 타입(`bpmn:Task` 등). */
11
+ type: string;
12
+ cells: TranslationCellState[];
13
+ }
14
+ /** 문서 한 판본의 번역 칸 상태 — 요소 id → 상태(번역 칸이 있는 DI 평면 요소만). */
15
+ export type TranslationStates = Map<string, TranslationElementState>;
16
+ /** 문서 한 판본의 번역 칸 상태를 뽑는다(문서 무변경). */
17
+ export declare function collectTranslationStates(definitions: Any): TranslationStates;
18
+ interface IndexedState {
19
+ doc: string;
20
+ version: number;
21
+ id: string;
22
+ state: TranslationElementState;
23
+ }
24
+ /**
25
+ * 근거 색인 — 그룹 문서 전부의 판본(현재본 · 이력)을 담는다. 언어 칸이 하나도 없는 상태는 근거가 될 수 없어 담지 않는다.
26
+ * `doc` = 문서 식별자(호스트 문서 id) · `version` = 판본 번호(`history` 단계가 최근 판본부터 본다).
27
+ */
28
+ export declare class TranslationStateIndex {
29
+ private readonly byId;
30
+ private readonly byBodies;
31
+ add(doc: string, version: number, states: TranslationStates): void;
32
+ /** @internal */
33
+ sameId(id: string): IndexedState[];
34
+ /** @internal */
35
+ sameBodies(cells: TranslationCellState[]): IndexedState[];
36
+ }
37
+ /** 근거 단계 — `history` 같은 문서 이전 판본 · `lineage` 다른 문서 같은 요소 id · `bodies` id 무관 같은 본문 묶음. */
38
+ export type TranslationLocaleRestoreSource = 'history' | 'lineage' | 'bodies';
39
+ /** 계획 항목이 가리키는 요소. */
40
+ export interface TranslationLocaleRestoreTarget {
41
+ id: string;
42
+ /** moddle 타입. */
43
+ type: string;
44
+ }
45
+ export interface TranslationLocaleRestorePlan {
46
+ /** 되살릴 칸 — 적용은 그 본문의 무언어 칸이 남아 있고 요소에 그 언어가 아직 없을 때만 쓴다. */
47
+ restores: Array<TranslationLocaleRestoreTarget & {
48
+ source: TranslationLocaleRestoreSource;
49
+ cells: Array<{
50
+ body: string;
51
+ locale: string;
52
+ }>;
53
+ }>;
54
+ /** 맞는 근거 상태들이 서로 다른 배정을 낸다 — 쓰지 않는다(사람 확인). */
55
+ ambiguous: Array<TranslationLocaleRestoreTarget & {
56
+ source: TranslationLocaleRestoreSource;
57
+ }>;
58
+ /** 근거 언어가 이미 요소에 있다 — 손실 뒤 그 언어를 다시 썼다 · 무언어 칸은 낡은 문구(되살리지 않는다). */
59
+ stale: Array<TranslationLocaleRestoreTarget & {
60
+ body: string;
61
+ locale: string;
62
+ }>;
63
+ /**
64
+ * 후보인데 근거 상태가 없다 — 쓰지 않는다. `script` = 문자 체계(사람 확인 · 문자 판정 쓰기는 범위 밖).
65
+ * 문서에 나오는 언어를 그 요소가 이미 다 가졌으면 되살릴 언어가 없으므로 싣지 않는다(언어 칸 옆의 잔재 칸 — 로컬 실측 7).
66
+ */
67
+ unresolved: Array<TranslationLocaleRestoreTarget & {
68
+ body: string;
69
+ script: ScriptKind;
70
+ }>;
71
+ }
72
+ export interface TranslationLocaleRestoreContext {
73
+ /** 이 문서의 식별자 — 색인의 `doc` 과 같은 값. */
74
+ doc: string;
75
+ index: TranslationStateIndex;
76
+ /** 문서 이력 첫 판본의 상태 — 그 뒤에 생긴 무언어 칸만 후보다. 없으면 칸 전부가 무언어인 요소만 본다. */
77
+ baseline?: TranslationStates;
78
+ }
79
+ /** 언어 복구 계획 — 문서를 바꾸지 않는다. */
80
+ export declare function planTranslationLocaleRestore(definitions: Any, ctx: TranslationLocaleRestoreContext): TranslationLocaleRestorePlan;
81
+ /**
82
+ * 계획을 문서에 쓴다 — 바꾼 칸 수를 돌려준다. **멱등**이고 계획 뒤 문서가 바뀌었어도 덮지 않는다: 그 본문의 무언어 칸이
83
+ * 남아 있고 요소에 그 언어가 아직 없을 때만 그 칸에 `xml:lang` 을 단다.
84
+ */
85
+ export declare function applyTranslationLocaleRestore(definitions: Any, plan: TranslationLocaleRestorePlan): number;
86
+ export {};
@@ -2,6 +2,7 @@ import { BpmnDocumentModelerLike } from '../core/modelerLike';
2
2
  import { SymbolicOp } from './symbolicOp';
3
3
  import { ApplyBpmnOpsResult, ResolveIssue } from './resolver';
4
4
  import { GeometryFinding } from './geometryAudit';
5
+ import { BpmnDocumentLocales } from '../adapter/i18n';
5
6
  /** op 출처 — 감사·정책 분기용. `gui` = 호스트 채팅 패널, `rest` = 외부 브리지. */
6
7
  export type BpmnOpOrigin = 'agent' | 'gui' | 'rest';
7
8
  export interface BpmnOpBatch {
@@ -54,6 +55,11 @@ export type ApplyBatchOutcome =
54
55
  export interface ApplyBpmnOpBatchOptions {
55
56
  /** 적용 시점의 권위 버전 — 호스트(영속 소유자)가 공급한다. */
56
57
  currentVersion: number;
58
+ /**
59
+ * 그 문서가 속한 그룹의 문서 언어 설정(B-4 ④) — 호스트가 공급한다(문서에 없다). 있으면 문구는 `names`/`texts`
60
+ * 로 문서 언어 전부를 받고, 없으면 평문만 받는다(`applyBpmnOps` 의 같은 옵션).
61
+ */
62
+ i18n?: BpmnDocumentLocales;
57
63
  }
58
64
  /**
59
65
  * 배치를 캔버스에 적용하고 영속 페이로드를 낸다.
@@ -64,4 +70,4 @@ export interface ApplyBpmnOpBatchOptions {
64
70
  * 적용은 단일 undo 에피소드다(`applyBpmnOps` → `command/undoEpisode`) — 배치 수십 op 가
65
71
  * 사용자 undo 1회로 되감긴다.
66
72
  */
67
- export declare function applyBpmnOpBatch(modeler: BpmnDocumentModelerLike, batch: BpmnOpBatch, { currentVersion }: ApplyBpmnOpBatchOptions): Promise<ApplyBatchOutcome>;
73
+ export declare function applyBpmnOpBatch(modeler: BpmnDocumentModelerLike, batch: BpmnOpBatch, { currentVersion, i18n }: ApplyBpmnOpBatchOptions): Promise<ApplyBatchOutcome>;
@@ -1,4 +1,6 @@
1
1
  import { ModdleElement, ParseWarning } from '../adapter/xml';
2
+ import { BpmnDocumentLocales } from '../adapter/i18n';
3
+ import { ReviewRequestValue } from '../command/setTranslations';
2
4
  import { BwlAfterColumn, BwlBand, BwlPlacement, BwlPoolOrder } from '../core/hints';
3
5
  import { IrDefinition } from '../core/ir';
4
6
  /** 파생 뷰가 표현하지 못한 요소 — 침묵 폐기 금지(에이전트가 미표현 존재를 알아야 안전). */
@@ -41,15 +43,40 @@ export interface BwlHintView {
41
43
  /** 주석 id → 앵커 기준 방위 (앵커 부재분은 필터됨) */
42
44
  placements: Record<string, BwlPlacement>;
43
45
  }
46
+ /** 확인 요청 표식 한 건(B-4 ④) — `id` 요소의 `locale` 칸에 걸렸다. `sourceLocale` 이 `previous` → 지금 문구로 고쳐졌다. */
47
+ export interface ReviewRequestView extends ReviewRequestValue {
48
+ id: string;
49
+ }
50
+ /**
51
+ * 다국어 판독 결과(B-4 ④) — 문서 언어 설정이 있을 때만 낸다. IR 밖 채널(위 헤더 「다국어」).
52
+ * 에이전트는 이 값이 있으면 문구를 `names`/`texts` 로 문서 언어 전부를 써야 한다.
53
+ */
54
+ export interface I18nView {
55
+ designLocale: string;
56
+ /** 병기 언어(설계 언어 제외 · 중복 제거). */
57
+ companionLocales: string[];
58
+ /**
59
+ * 정리할 확인 요청 — 문서 언어 칸에 걸린 것만. `previous`(고치기 전 원문) → 지금 `names[sourceLocale]` 를 대조해
60
+ * 오타 수준이면 `translation.confirm`, 내용이 바뀌었으면 그 요소 update 에 `names` 로 번역을 고친다.
61
+ */
62
+ reviewRequests: ReviewRequestView[];
63
+ }
44
64
  export interface DescribeProcessResult {
45
65
  definition: IrDefinition;
46
66
  hints: BwlHintView;
47
67
  omitted: IrOmission[];
68
+ /** 문서 언어 설정이 있을 때만 있다(B-4 ④). */
69
+ i18n?: I18nView;
70
+ }
71
+ /** 판독 옵션 — 문서 밖에서만 알 수 있는 입력. */
72
+ export interface DescribeProcessOptions {
73
+ /** 그룹의 문서 언어 설정(B-4 ④) — 문서에 없어 호스트가 공급한다. 없으면 다국어 판독을 하지 않는다. */
74
+ i18n?: BpmnDocumentLocales;
48
75
  }
49
76
  export interface DescribeProcessXmlResult extends DescribeProcessResult {
50
77
  /** 입력 XML 파싱 경고 — 실운영 문서는 빈 배열이어야 한다(M1 수용 기준 1). */
51
78
  warnings: ParseWarning[];
52
79
  }
53
- export declare function describeProcess(definitions: ModdleElement): DescribeProcessResult;
80
+ export declare function describeProcess(definitions: ModdleElement, options?: DescribeProcessOptions): DescribeProcessResult;
54
81
  /** XML 문자열 입력 래퍼 — 헤드리스 read 경로(호스트 `describeProcess` API·테스트). */
55
- export declare function describeProcessXml(xml: string): Promise<DescribeProcessXmlResult>;
82
+ export declare function describeProcessXml(xml: string, options?: DescribeProcessOptions): Promise<DescribeProcessXmlResult>;
@@ -613,6 +613,8 @@ export declare function segmentShapeClearance(a: GeometryPoint, b: GeometryPoint
613
613
  /**
614
614
  * 한 간선(또는 그 후보 경로)이 다른 간선들과 교차하는 수. **끝점을 공유하는 간선은 제외**한다 —
615
615
  * 같은 노드에서 나가는 팬아웃·같은 노드로 드는 합류는 꺾이는 자리가 겹쳐 보여도 교차가 아니다.
616
+ * ⚠ `segmentsCross` 가 이미 접촉을 안 세므로 이 제외가 실제로 막는 것은 **내부 진성 교차**뿐이다(B-146) —
617
+ * 그쪽은 `sharedEndpointCrossingPairsOf` 가 따로 센다. 이 제외를 풀지 말 것: 위에 라우팅 채택 게이트가 선다.
616
618
  */
617
619
  export declare function edgeCrossCount(edge: GeometryEdge, others: readonly GeometryEdge[]): number;
618
620
  /**
@@ -625,6 +627,18 @@ export declare function crossingCost(edge: GeometryEdge, others: readonly Geomet
625
627
  export declare function sceneCrossingCost(scene: GeometryScene): number;
626
628
  /** 장면 전체의 교차 쌍(id 오름차순 정렬, 결정론적). 길이가 곧 교차 수다. */
627
629
  export declare function edgeCrossingPairsOf(scene: GeometryScene): Array<[string, string]>;
630
+ /**
631
+ * **끝점을 공유하는** 쌍의 진성 교차(B-146 ⓐ′ · 관측 전용) — `edgeCrossingPairsOf` 가 통째로 빼는 쌍 중
632
+ * 간선 **내부**에서 가로지르는 것. 둘을 합치면 장면의 진성 교차 전량이고 겹치는 쌍은 없다.
633
+ *
634
+ * 표본 98 에서 사람이 고친 교차가 이것이었다 — 게이트웨이 → 오류 노드 갈래와 오류 노드 → 상류 되돌아감이
635
+ * 오류 노드를 함께 끝점으로 가져 판정·계수가 모두 침묵했다(사람은 두 간선의 출입 변을 맞바꿨다).
636
+ * 🔴 **라우팅·채택 게이트의 입력이 아니다** — `edgeCrossCount` 의 제외를 바꾸면 그 위의 우회 채택·교차 보정과
637
+ * `--check` 기대값이 함께 움직인다. 이 함수는 보이게만 한다.
638
+ * ⚠ 「공유」는 각 어댑터의 `endpoints` 를 따른다 — 데이터 연관은 두 어댑터가 다르게 담는다(저장본 = 저장소만 ·
639
+ * 캔버스 = 활동 + 저장소).
640
+ */
641
+ export declare function sharedEndpointCrossingPairsOf(scene: GeometryScene): Array<[string, string]>;
628
642
  /**
629
643
  * 교차 쌍을 **에이전트가 판단할 수 있는 재료로 분해**한다(B-43). 개수만으로는 "이 정도가 정상인가" 를
630
644
  * 가릴 수 없고, 지금까지 세 회차에서 같은 마찰이 났다(표본 34·36 은 재료 없이도 결론이 맞았으나
@@ -9,6 +9,13 @@ export interface DocumentIndex {
9
9
  categoryOf(id: string): ElementCategory | undefined;
10
10
  /** 참여자에 속한 레인 id 목록 — **y순(위→아래)** 계약. lanes 재선언 diff 의 순서 비교 기준 */
11
11
  lanesOf(participantId: string): readonly string[];
12
+ /**
13
+ * 참여자에 속한 레인 id 목록 — **선언순**(laneSet 순서 = `describe` 가 내는 순서 · A-6). lanes 재선언은 이 순서도
14
+ * 받는다(B-153 — 선언순 ≠ y순 풀에서 `describe` 순서를 그대로 쓴 재선언이 거부됐다 · 레거시 레인 풀 19/50).
15
+ * 중첩 레인(`childLaneSet`)은 부모 뒤에 깊이 우선으로 잇는다(`lanesOf` 와 같은 집합).
16
+ * 선택 — 공개 타입이라 외부 구현을 깨지 않으려고 둔다(없으면 y순만 받는 종전 동작).
17
+ */
18
+ laneDeclarationOrderOf?(participantId: string): readonly string[];
12
19
  /** 플로우 노드가 속한 참여자 id (풀 없는 단일 프로세스 문서면 undefined) */
13
20
  participantOf(nodeId: string): string | undefined;
14
21
  /**
@@ -26,6 +33,11 @@ export interface DocumentIndex {
26
33
  * 어휘 밖 정의면 undefined.
27
34
  */
28
35
  eventDefinitionOf(nodeId: string): IrEventDefinition | undefined;
36
+ /**
37
+ * 요소에 확인 요청 표식(`bwl:reviewRequest`)이 걸린 언어들 (B-4 ④) — `translation.confirm` 이 없는 표식을
38
+ * 지목하면 거부한다(읽은 뒤 사람이 이미 정리했을 수 있다). 없으면 빈 배열.
39
+ */
40
+ reviewRequestLocalesOf(id: string): readonly string[];
29
41
  }
30
42
  /** elementRegistry 어댑터 — 하강 직전 실문서 상태를 대변한다. */
31
43
  export declare function buildRegistryIndex(registry: ElementRegistry): DocumentIndex;
@@ -2,11 +2,12 @@ import { BpmnModelerLike } from '../../core/modelerLike';
2
2
  import { SymbolicOp } from '../symbolicOp';
3
3
  import { ResolveIssue } from './issues';
4
4
  import { GeometryFinding } from '../geometryAudit';
5
+ import { BpmnDocumentLocales } from '../../adapter/i18n';
5
6
  import { lowerOps } from './lower';
6
7
  export type { ResolveIssue } from './issues';
7
8
  export type { DocumentIndex, ElementCategory } from './documentIndex';
8
9
  export { buildRegistryIndex } from './documentIndex';
9
- export { validateOps } from './validate';
10
+ export { validateOps, type ValidateOpsOptions } from './validate';
10
11
  export { lowerOps, resolverServicesOf, type ResolverServices } from './lower';
11
12
  export { forwardThreePointCandidates, planCrossPoolRoute, planEdgeRepair, planLabelLineClearance, planLabelPlacement, planMiddleSegmentShifts, planOppositeOverlapRepair, planSegmentDetours, planBackEdgeBoundaryClearance, repairIntroducedBoundaryHugging, repairIntroducedCrossings, repairIntroducedEdgeCrossings, repairIntroducedFakeMerges, repairIntroducedOppositeOverlaps, repairIntroducedSharedSegmentLabels, followMovedEdgeLabels, redockIntroducedDetachedEndpoints, repairIntroducedLabelLines, repairIntroducedShapeLabelLines, planShapeLabelClearance, rerouteIntroducedCrossPoolEdges, } from './routeRepair';
12
13
  export interface ApplyBpmnOpsResult {
@@ -57,6 +58,28 @@ export interface ApplyBpmnOpsResult {
57
58
  */
58
59
  crossPoolMessages: number;
59
60
  };
61
+ /**
62
+ * **끝점을 공유하는** 간선끼리의 내부 진성 교차(B-146 ⓐ′) — 위 `edgeCrossings` 가 세지 않는 쌍이다(둘을 합치면
63
+ * 진성 교차 전량 · 겹치는 쌍 없음). 표본 98 에서 사람이 고친 교차가 이것이었다(게이트웨이 → 오류 노드 갈래 ×
64
+ * 오류 노드 → 상류 되돌아감). **관측 전용** — 보정 단계의 채택 게이트는 이 값을 보지 않는다.
65
+ */
66
+ sharedEndpointCrossings: {
67
+ before: number;
68
+ after: number;
69
+ /** 하강 뒤 남은 쌍(간선 id, 오름차순). */
70
+ pairs: Array<[string, string]>;
71
+ };
60
72
  };
61
73
  }
62
- export declare function applyBpmnOps(modeler: BpmnModelerLike, ops: readonly SymbolicOp[], lower?: typeof lowerOps): ApplyBpmnOpsResult;
74
+ /** 배치 적용 옵션 — 문서 밖에서만 알 수 있는 입력. */
75
+ export interface ApplyBpmnOpsOptions {
76
+ /**
77
+ * 그룹의 문서 언어 설정(B-4 ④). 있으면 다국어 그룹이다 — 문구는 `names`/`texts` 로 문서 언어 전부를 받고
78
+ * (평문 거부) 하강 뒤 번역 칸을 같은 undo 에피소드에서 기록한다. 없으면 기능이 꺼진 그룹이다(평문만).
79
+ * 🔴 **문서에는 이 설정이 없다**(루트 `xml:lang` 은 만들 당시의 설계 언어일 뿐이다) — 호스트가 그룹 설정을 공급한다.
80
+ */
81
+ i18n?: BpmnDocumentLocales;
82
+ /** 테스트 시임 — 롤백 경로를 결정론적으로 검증하기 위한 하강 함수 주입점. 실사용은 기본값. */
83
+ lower?: typeof lowerOps;
84
+ }
85
+ export declare function applyBpmnOps(modeler: BpmnModelerLike, ops: readonly SymbolicOp[], options?: ApplyBpmnOpsOptions): ApplyBpmnOpsResult;
@@ -167,6 +167,59 @@ export type ResolveIssue =
167
167
  type: string;
168
168
  dropped: string[];
169
169
  }
170
+ /** 평문(`name`/`text`)과 로케일 맵(`names`/`texts`)을 함께 줬다 — 어느 쪽이 진실인지 모호하다(🔁 `condition-name-conflict`). */
171
+ | {
172
+ kind: 'locale-texts-conflict';
173
+ opIndex: number;
174
+ id: string;
175
+ field: string;
176
+ }
177
+ /**
178
+ * 다국어 그룹(문서 언어 설정 있음)에 평문을 줬다 — 언어를 모르는 문구는 설계 언어 칸에 다른 언어가 들어가는 경로다
179
+ * (켠 뒤의 에이전트 배치가 언어 기록 없는 이름 · drift 를 만드는 근인). `names`/`texts` 로 문서 언어 전부를 준다.
180
+ * 🔴 **조건 라벨(`condition`)도 여기다** — name 채널의 별칭(A-5)이라 다국어 그룹에선 그 플로우의 `names` 로 쓴다.
181
+ */
182
+ | {
183
+ kind: 'locale-texts-required';
184
+ opIndex: number;
185
+ id: string;
186
+ field: string;
187
+ locales: string[];
188
+ }
189
+ /** 기능이 꺼진 그룹(문서 언어 미설정)에 로케일 맵이나 `translation.confirm` 을 줬다 — 평문을 쓴다. */
190
+ | {
191
+ kind: 'locale-texts-not-enabled';
192
+ opIndex: number;
193
+ id: string;
194
+ field: string;
195
+ }
196
+ /** 로케일 맵에 문서 언어가 빠졌다 — 에이전트 쓰기는 문서 언어 **전부**를 함께 쓴다(그래야 표식이 안 생긴다). */
197
+ | {
198
+ kind: 'locale-texts-incomplete';
199
+ opIndex: number;
200
+ id: string;
201
+ field: string;
202
+ missing: string[];
203
+ }
204
+ /** 문서 언어(설계 + 병기) 밖의 언어 — 표시도 판정도 안 하는 칸이라 아무도 못 보고 못 고친다. */
205
+ | {
206
+ kind: 'locale-not-in-document';
207
+ opIndex: number;
208
+ id: string;
209
+ field: string;
210
+ locale: string;
211
+ locales: string[];
212
+ }
213
+ /**
214
+ * `translation.confirm` 의 대상 칸에 확인 요청 표식이 없다 — 읽은 뒤 사람이 이미 정리했거나 언어를 잘못 짚었다.
215
+ * 다시 읽어 `i18n.reviewRequests` 를 본다.
216
+ */
217
+ | {
218
+ kind: 'review-request-missing';
219
+ opIndex: number;
220
+ id: string;
221
+ locale: string;
222
+ }
170
223
  /** 하강 실행 중 실패 — 실행분은 롤백됨(원자성 2차 방어) */
171
224
  | {
172
225
  kind: 'lower-failed';
@@ -0,0 +1,24 @@
1
+ import { BpmnDocumentLocales } from '../../adapter/i18n';
2
+ import { SymbolicOp } from '../symbolicOp';
3
+ import { DocumentIndex } from './documentIndex';
4
+ import { ResolveIssue } from './issues';
5
+ /** 하강 뒤 한 요소에 할 번역 쓰기 — 같은 요소를 여러 op 가 건드리면 합친다. */
6
+ export interface LocaleWrite {
7
+ /** 문서 언어 전부의 문구. `null` = 라벨 제거(칸 · 표식 전부). 없으면 문구를 쓰지 않는다. */
8
+ texts?: Record<string, string> | null;
9
+ /** 문구를 바꾸지 않고 해소할 확인 요청의 언어들(`translation.confirm`). */
10
+ confirm?: string[];
11
+ }
12
+ /**
13
+ * 다국어 검증(순수). `config` = 그룹의 문서 언어 설정 — 없으면 기능이 꺼진 그룹이다.
14
+ * 페이로드 shape(맵이 객체인가 · 값이 비지 않은 문자열인가)도 여기서 본다 — 패스 0 은 kind 별 고정 자리만 안다.
15
+ */
16
+ export declare function validateLocaleTexts(ops: readonly SymbolicOp[], index: DocumentIndex, config: BpmnDocumentLocales | undefined): ResolveIssue[];
17
+ /**
18
+ * 하강 준비 — 검증 통과가 전제다. 반환 `ops` 는 평문만 남은 사본(설계 언어 문구 · `translation.confirm` 제외)이고,
19
+ * `writes` 는 하강 뒤 요소별로 할 번역 쓰기다. `config` 가 없으면(기능 끔) 입력을 그대로 돌려준다.
20
+ */
21
+ export declare function localizeOps(ops: readonly SymbolicOp[], index: DocumentIndex, config: BpmnDocumentLocales | undefined): {
22
+ ops: SymbolicOp[];
23
+ writes: Map<string, LocaleWrite>;
24
+ };
@@ -39,6 +39,14 @@ export declare function resolverServicesOf(modeler: BpmnModelerLike): ResolverSe
39
39
  * B-33 → B-34 ⓐ 가 그룹 경계 보정에서 닫은 것과 같은 클래스다.
40
40
  *
41
41
  * `selfId` = 이미 존재하는 주석(update)의 자기 도형·자기 연관을 장애물에서 뺀다 — 안 빼면 늘 "막힘"이다.
42
+ *
43
+ * **B-144** — 앵커가 레인 안이면 클램프 상자와 대안 방위의 `inside` 를 **앵커 레인 대역**으로 좁힌다(풀 클램프와
44
+ * 같은 규칙 — 레인 경계에서 클램프하고 앵커와 겹치면 오른쪽으로 비낀다). 🔴 **레인 안에 막히지 않은 자리가 없으면
45
+ * 종전대로 풀 안 빈 자리(이웃 레인일 수 있다)로 간다** — 레인 소속을 막힌 자리(겹침·관통)와 바꾸지 않는다
46
+ * (반사실: 레인 안 막힌 자리로 두는 안은 findings 가 는 케이스가 두 배였다 · 66 vs 33 / 방위 합성 6,208).
47
+ * 그것도 없으면 레인 안 선언 자리(막힘 — 판정기가 보고한다). ⚠ 잔존 대가 = 그 폴백의 이웃 레인 착지(방위 합성
48
+ * 0.6% — 사람 기저 0.4~1.0% 수준) · 레인 클램프가 오른쪽 비끼기를 더 자주 발동시켜 **가로로 풀 밖** 착지가
49
+ * 12 → 16(그 분기가 풀 우변을 넘는 것은 이 축 이전부터다 — 원장 B-144 곁).
42
50
  */
43
51
  export declare function annotationSpot(elementRegistry: ElementRegistry, anchor: {
44
52
  x: number;
@@ -62,6 +70,14 @@ export declare function annotationSpot(elementRegistry: ElementRegistry, anchor:
62
70
  x: number;
63
71
  y: number;
64
72
  };
73
+ /**
74
+ * **B-168** — source 꼴 직접 끼우기 감지(하강 **전** 문서 기준). 키 = F id · 값 = 7단계까지 미룰 신규 유입(`A → X`) op.
75
+ * 조건 = X 로의 target 재배선이 없다 · X 가 F 의 옛 출발 A 에서 신규 유입을 받는다 · X 마다 첫 F 하나 · 그 신규 유입을
76
+ * 다른 op 가 참조하지 않는다(7단계 앞 단계 — 주석 연관 · 그룹 멤버 — 에서 아직 없다). 뒤 보정(`index.ts`)도 같은 판정을 쓴다.
77
+ */
78
+ export declare function sourceFormInsertsOf(ops: readonly SymbolicOp[], oldSourceOf: (flowId: string) => string | undefined): Map<string, Extract<SymbolicOp, {
79
+ kind: 'sequenceFlow.add';
80
+ }>>;
65
81
  /**
66
82
  * 하강 중에야 드러나는 거부를 **구조화된 issue 로** 올린다 — `applyBpmnOps` 가 자유 문장 `lower-failed` 대신
67
83
  * 이 issue 를 그대로 낸다(LLM 교정 루프가 읽을 수 있게). 롤백은 다른 throw 와 같다(undo 에피소드가 되감는다).
@@ -97,13 +113,22 @@ export declare function repairIntroducedAnnotationOverlaps(services: Pick<Resolv
97
113
  */
98
114
  export declare function repairIntroducedPoolOverlaps(services: Pick<ResolverServices, 'elementRegistry' | 'modeling'>, beforeKeys: ReadonlySet<string>, sceneBefore: GeometryScene): void;
99
115
  /**
100
- * 🔴 **B-120 — 문서 전체가 한 우변에 맞춰져 있던 풀들을 배치 뒤에도 한 우변으로 되돌린다.**
116
+ * 🔴 **B-120 — 배치 전 한 우변에 맞춰져 있던 풀 무리를 배치 뒤에도 한 우변으로 되돌린다.**
101
117
  *
102
118
  * 증언(표본 86) = *"레인 끝부분이 걸린건 위쪽의 세개의 레인이 정렬되있어서야"*. 배치는 두 풀만 늘렸고 **늘리는 경로가 둘인데
103
119
  * 기준이 다르다**(`shiftGroups` = 내용 우단 +150 · `createSpace` = 밀기 폭) — 한 우변이 셋으로 갈렸다.
104
- * 🔴 **판별자는 「양」이 아니라 「대상」이다** — 우변이 같은 풀이 몇 개인가가 아니라 **문서 전체가 한 우변이었나**. N20 전이 =
105
- * 전체 정렬 무리는 사람이 **3/3 반응** · 부분 무리는 **0/5**. 부분 일치는 도구 문서에서도 우연히 생긴다(저장본 부분 무리 19/69 ↔
106
- * 전체 정렬 0/69). ⇒ 발동은 **배치 전 모든 풀(≥2)의 우변이 같을 때만**이다.
120
+ *
121
+ * 무리 = 배치 전 우변이 허용 오차 안에서 같은 풀들(크기 ≥2). 범위는 두 단계로 넓어졌다:
122
+ * - **ⓐ 문서 전체가 한 우변**(2026-09-28) — N20 전이 = 전체 정렬 무리는 사람이 **3/3 반응** · 부분 무리는 **0/5**.
123
+ * - **ⓓ 부분 무리 — 블랙박스 멤버가 없을 때만**(2026-10-06 · 표본 99) — 증언 = *"끝부분이 어긋난건 보였는데 … 맞추는게
124
+ * 맞아보이긴해"*. N20 = 사람 문서(풀 ≥2) 98 중 **부분 무리 문서 25** · ⓐ 뒤 현행이 깨는 무리는 **부분 무리뿐**(계보 7/23) ·
125
+ * 합성 재고(블랙박스 없는 부분 무리 1,899) = 깨짐 376 → 복원 **312** · 판정 키 · 교차 · 끝점 공유 교차 · 흐름 간선 변화 **0**.
126
+ * 🔴 **블랙박스 멤버가 있는 부분 무리는 뺀다** — 계보 반사실에서 블랙박스 풀이 **570 → 2155** 로 늘고 그 우변에 붙던 메시지가
127
+ * 다시 그려져 끝점 공유 교차가 **1 → 3** 이 됐다(그 회차의 사람은 맞추지 않았다). ⚠ 아래 가드 ②는 그 메시지를 못 막았다 —
128
+ * 이 패스 시점엔 우변에 안 붙어 있었고 뒤 라우팅이 붙인다(추정). ⚠ 판별은 **이 패스 시점**의 모델이다(배치가 빈 풀에 노드를
129
+ * 넣었으면 더는 블랙박스가 아니다).
130
+ * ⚠ 부분 일치는 도구 문서에서도 우연히 생긴다(저장본 19/69) — 그런 무리는 대개 처음부터 같은 폭이라 되돌려도 원래 모양이다
131
+ * (계보 102 재하강에서 기하가 바뀐 문서 = 표본 99 하나).
107
132
  *
108
133
  * **목표 우변 = max(base 우변, 각 풀의 산출 내용 우단 + 150)** — 사람 값이 있는 회차(표본 85 = 2338)를 **정확히** 낸 규칙은
109
134
  * 이것 하나였다(무리 최댓값 · 풀별 base 여백 보존은 둘 다 2473). base 우변 아래로는 **안 줄인다**.