@cardenelabs/dragon 0.7.0 → 0.8.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/README.md +111 -0
- package/dist/index.cjs +2365 -277
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +240 -3
- package/dist/index.d.ts +240 -3
- package/dist/index.js +2366 -279
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/compile.ts +2895 -258
- package/src/index.ts +4 -1
- package/src/input-size.ts +8 -1
- package/src/json-parser.ts +480 -30
- package/src/notation-lint.ts +27 -4
- package/src/schemas/diagram.json +56 -5
- package/src/types.ts +125 -0
- package/src/v05/parser.ts +341 -41
- package/src/value-syntax.ts +313 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NODE_KINDS, TONES, layout, diagram, rendersRows, requiredRowsHeight, requiredRowsWidth, sequence, flow, swimlane, er, stateMachine, topology } from '@cardenelabs/cdl';
|
|
1
|
+
import { NODE_KINDS, TONES, layout, applyDerivedValues, diagram, rendersRows, requiredRowsHeight, requiredRowsWidth, sequence, flow, swimlane, er, stateMachine, topology, parseFormula } from '@cardenelabs/cdl';
|
|
2
2
|
|
|
3
3
|
// src/keywords.ts
|
|
4
4
|
var HEADERS = {
|
|
@@ -608,7 +608,7 @@ function countDocElements(doc) {
|
|
|
608
608
|
(acc, p) => acc + (p.highlight?.length ?? 0) + (p.tweens?.length ?? 0) + (p.sets?.length ?? 0),
|
|
609
609
|
0
|
|
610
610
|
);
|
|
611
|
-
return doc.actors.length + doc.flow.length + phases.length + phaseChildren + (doc.animate?.states.length ?? 0) + (doc.groups ? Object.keys(doc.groups).length : 0) + (doc.lanes ? Object.keys(doc.lanes).length : 0);
|
|
611
|
+
return doc.actors.length + doc.flow.length + phases.length + phaseChildren + (doc.animate?.states.length ?? 0) + (doc.values?.length ?? 0) + (doc.groups ? Object.keys(doc.groups).length : 0) + (doc.lanes ? Object.keys(doc.lanes).length : 0);
|
|
612
612
|
}
|
|
613
613
|
function countDiagramElements(diagram2) {
|
|
614
614
|
const phases = Array.isArray(diagram2.phases) ? diagram2.phases : [];
|
|
@@ -617,7 +617,8 @@ function countDiagramElements(diagram2) {
|
|
|
617
617
|
return acc + (Array.isArray(ph?.activate) ? ph.activate.length : 0) + (Array.isArray(ph?.highlight) ? ph.highlight.length : 0) + (Array.isArray(ph?.tweens) ? ph.tweens.length : 0) + (Array.isArray(ph?.sets) ? ph.sets.length : 0);
|
|
618
618
|
}, 0);
|
|
619
619
|
return (diagram2.nodes?.length ?? 0) + (diagram2.edges?.length ?? 0) + (diagram2.lanes?.length ?? 0) + (diagram2.states?.length ?? 0) + phases.length + phaseChildren + // 図が持てる並びは全部数える。 1 つでも外すと、そこに寄せた図が素通りする
|
|
620
|
-
(diagram2.readouts?.length ?? 0) + (diagram2.inputs?.length ?? 0) + (diagram2.formulas?.length ?? 0) + (diagram2.scrollTriggers?.length ?? 0) + (diagram2.eventBindings?.length ?? 0)
|
|
620
|
+
(diagram2.readouts?.length ?? 0) + (diagram2.inputs?.length ?? 0) + (diagram2.formulas?.length ?? 0) + (diagram2.scrollTriggers?.length ?? 0) + (diagram2.eventBindings?.length ?? 0) + // 他の値から決まる値 (#1162)。 記法側 (`countDocElements`) が数えるので、こちらも揃える
|
|
621
|
+
(diagram2.derived?.length ?? 0);
|
|
621
622
|
}
|
|
622
623
|
function countBytes(src) {
|
|
623
624
|
return new TextEncoder().encode(src).length;
|
|
@@ -723,6 +724,12 @@ function orderByDependency(items) {
|
|
|
723
724
|
function compileToCdl(doc, opts) {
|
|
724
725
|
const oversize = describeOversize({ elements: countDocElements(doc), bytes: 0 });
|
|
725
726
|
if (oversize) throw new Error(oversize);
|
|
727
|
+
doc = canonicalizeFlowActors(doc);
|
|
728
|
+
const \u66F8\u3044\u305F\u307E\u307E = doc;
|
|
729
|
+
doc = dropUnresolvedFlow(doc);
|
|
730
|
+
doc = dropSelfLoopFlow(doc);
|
|
731
|
+
const \u5206\u3051\u305F = disambiguateActorIds(doc, opts?.onNotice);
|
|
732
|
+
doc = \u5206\u3051\u305F.doc;
|
|
726
733
|
let diagram2;
|
|
727
734
|
switch (doc.type) {
|
|
728
735
|
case "sequence":
|
|
@@ -753,27 +760,64 @@ function compileToCdl(doc, opts) {
|
|
|
753
760
|
diagram2 = compileClass(doc);
|
|
754
761
|
break;
|
|
755
762
|
case "pie":
|
|
756
|
-
diagram2 =
|
|
763
|
+
diagram2 = compileValueChart(doc, "pie", "chart-pie", opts?.onNotice);
|
|
764
|
+
break;
|
|
765
|
+
case "bar":
|
|
766
|
+
diagram2 = compileValueChart(doc, "bar", "chart-bar", opts?.onNotice);
|
|
767
|
+
break;
|
|
768
|
+
case "line":
|
|
769
|
+
diagram2 = compileValueChart(doc, "line", "chart-line", opts?.onNotice);
|
|
770
|
+
break;
|
|
771
|
+
case "funnel":
|
|
772
|
+
diagram2 = compileFunnel(doc, opts?.onNotice);
|
|
773
|
+
break;
|
|
774
|
+
case "tree":
|
|
775
|
+
diagram2 = compileTree(doc, opts?.onNotice);
|
|
776
|
+
break;
|
|
777
|
+
case "journey":
|
|
778
|
+
diagram2 = compileJourney(doc, opts?.onNotice);
|
|
779
|
+
break;
|
|
780
|
+
case "quadrant":
|
|
781
|
+
diagram2 = compileQuadrant(doc, opts?.onNotice);
|
|
757
782
|
break;
|
|
758
783
|
case "c4":
|
|
759
784
|
diagram2 = compileC4(doc);
|
|
760
785
|
break;
|
|
761
786
|
case "mind":
|
|
762
|
-
diagram2 = compileMind(doc);
|
|
787
|
+
diagram2 = compileMind(doc, opts?.onNotice);
|
|
763
788
|
break;
|
|
764
789
|
default:
|
|
765
790
|
throw new Error(`unknown type: ${String(doc.type)}`);
|
|
766
791
|
}
|
|
792
|
+
const \u4F5C\u308A\u66FF\u3048\u305F\u5BFE\u8C61 = collectRenamedTargets(diagram2, \u5206\u3051\u305F.\u5143\u306E\u540D\u524D);
|
|
767
793
|
const edgeSourceLines = opts?.onEdgeSource ? /* @__PURE__ */ new Map() : void 0;
|
|
768
794
|
applyEdgeInlineOptions(diagram2, doc, edgeSourceLines);
|
|
769
|
-
if (edgeSourceLines) fillFlowEdgeSources(diagram2, doc, edgeSourceLines);
|
|
770
795
|
applyGroupContainers(diagram2, doc);
|
|
771
796
|
applyNodeTones(diagram2, doc);
|
|
772
|
-
reportMissingFocusTargets(
|
|
797
|
+
reportMissingFocusTargets(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
798
|
+
reportMissingFlowActors(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
799
|
+
reportSelfLoopFlow(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
800
|
+
reportFlowEndpointNotHonored(doc, \u5206\u3051\u305F.\u5143\u306E\u540D\u524D, opts?.onNotice);
|
|
801
|
+
reportLaneNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
802
|
+
reportDocEyebrowNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
803
|
+
reportChartFieldsNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
804
|
+
reportAxesNotHonored(\u66F8\u3044\u305F\u307E\u307E, opts?.onNotice);
|
|
773
805
|
const placed = resolveRelativeDoc(diagram2, doc, opts?.onNotice, opts?.partsCatalog);
|
|
774
806
|
applyCanvasPivotPositions(diagram2, placed);
|
|
775
|
-
const
|
|
776
|
-
const
|
|
807
|
+
const \u8FFD\u52A0\u3057\u305F\u7E26\u5217 = [];
|
|
808
|
+
const extended = applyV05Extensions(diagram2, placed, \u8FFD\u52A0\u3057\u305F\u7E26\u5217);
|
|
809
|
+
const inheritedDerivedSourceLines = opts?.onNotice ? /* @__PURE__ */ new Map() : void 0;
|
|
810
|
+
for (const value of extended.derived ?? []) {
|
|
811
|
+
recordDerivedSourceLine(inheritedDerivedSourceLines, value.id, 0);
|
|
812
|
+
}
|
|
813
|
+
const merged = mergePartsFromActors(
|
|
814
|
+
extended,
|
|
815
|
+
placed,
|
|
816
|
+
opts?.partsCatalog,
|
|
817
|
+
opts?.onNotice,
|
|
818
|
+
inheritedDerivedSourceLines
|
|
819
|
+
);
|
|
820
|
+
reportEmptyDeclaredLanes(merged, \u8FFD\u52A0\u3057\u305F\u7E26\u5217, opts?.onNotice);
|
|
777
821
|
if (edgeSourceLines && opts?.onEdgeSource) {
|
|
778
822
|
const alive = new Set(merged.edges.map((e) => e.id));
|
|
779
823
|
for (const [id, line] of edgeSourceLines) {
|
|
@@ -781,6 +825,10 @@ function compileToCdl(doc, opts) {
|
|
|
781
825
|
}
|
|
782
826
|
}
|
|
783
827
|
injectStaticPhase(merged);
|
|
828
|
+
materializeStates(merged, doc);
|
|
829
|
+
\u8A9E\u306E\u72B6\u614B\u3092\u56F3\u306E\u8A9E\u3078\u76F4\u3059(merged);
|
|
830
|
+
const \u7573\u3093\u3060\u304D\u3063\u304B\u3051 = foldValueTriggers(merged, doc, opts?.onNotice);
|
|
831
|
+
attachDerivedValues(merged, doc, opts?.onNotice, inheritedDerivedSourceLines, \u7573\u3093\u3060\u304D\u3063\u304B\u3051);
|
|
784
832
|
for (const dropped of stripExternalPaint(merged)) {
|
|
785
833
|
opts?.onNotice?.({
|
|
786
834
|
kind: "external-paint-dropped",
|
|
@@ -790,8 +838,17 @@ function compileToCdl(doc, opts) {
|
|
|
790
838
|
hint: "\u8272\u306F `#ff0000` \u306E\u3088\u3046\u306A\u8272\u756A\u53F7\u304B\u3001 `red` \u306E\u3088\u3046\u306A\u8272\u540D\u3067\u66F8\u304F"
|
|
791
839
|
});
|
|
792
840
|
}
|
|
841
|
+
restoreActorNames(merged, \u5206\u3051\u305F.\u5143\u306E\u540D\u524D, \u4F5C\u308A\u66FF\u3048\u305F\u5BFE\u8C61);
|
|
793
842
|
return merged;
|
|
794
843
|
}
|
|
844
|
+
function materializeStates(diagram2, doc) {
|
|
845
|
+
const \u8F09\u3063\u3066\u3044\u308B = new Set(diagram2.states.map((s) => s.id));
|
|
846
|
+
for (const st of doc.animate?.states ?? []) {
|
|
847
|
+
if (\u8F09\u3063\u3066\u3044\u308B.has(st.name)) continue;
|
|
848
|
+
diagram2.states.push({ id: st.name, initial: st.initial });
|
|
849
|
+
\u8F09\u3063\u3066\u3044\u308B.add(st.name);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
795
852
|
function injectStaticPhase(diagram2) {
|
|
796
853
|
if (diagram2.phases.length > 0) return;
|
|
797
854
|
const activate = [...diagram2.nodes.map((n) => n.id), ...diagram2.edges.map((e) => e.id)];
|
|
@@ -809,6 +866,314 @@ function truncateForMessage(v) {
|
|
|
809
866
|
const s = v.trim();
|
|
810
867
|
return s.length <= 40 ? s : `${s.slice(0, 37)}...`;
|
|
811
868
|
}
|
|
869
|
+
function actorRefTable(doc) {
|
|
870
|
+
const \u8868 = /* @__PURE__ */ new Map();
|
|
871
|
+
const slug\u6570 = /* @__PURE__ */ new Map();
|
|
872
|
+
for (const a of doc.actors) {
|
|
873
|
+
const sl = slugify(a.name);
|
|
874
|
+
slug\u6570.set(sl, (slug\u6570.get(sl) ?? 0) + 1);
|
|
875
|
+
}
|
|
876
|
+
for (const a of doc.actors) {
|
|
877
|
+
\u8868.set(a.name, a.name);
|
|
878
|
+
const sl = slugify(a.name);
|
|
879
|
+
if ((slug\u6570.get(sl) ?? 0) === 1) \u8868.set(sl, a.name);
|
|
880
|
+
}
|
|
881
|
+
return \u8868;
|
|
882
|
+
}
|
|
883
|
+
function canonicalizeFlowActors(doc) {
|
|
884
|
+
const \u8868 = actorRefTable(doc);
|
|
885
|
+
let \u5909\u3048\u305F = false;
|
|
886
|
+
const flow2 = doc.flow.map((s) => {
|
|
887
|
+
const from = \u8868.get(s.from) ?? s.from;
|
|
888
|
+
const to = \u8868.get(s.to) ?? s.to;
|
|
889
|
+
if (from === s.from && to === s.to) return s;
|
|
890
|
+
\u5909\u3048\u305F = true;
|
|
891
|
+
return { ...s, from, to };
|
|
892
|
+
});
|
|
893
|
+
return \u5909\u3048\u305F ? { ...doc, flow: flow2 } : doc;
|
|
894
|
+
}
|
|
895
|
+
var \u56F3\u7A2E\u306E\u4F5C\u308A = {
|
|
896
|
+
// 矢印の端と登場人物の名前が、 そのまま箱や枠の id になる
|
|
897
|
+
sequence: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
898
|
+
flow: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
899
|
+
swimlane: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
900
|
+
er: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
901
|
+
state: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
902
|
+
topology: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
903
|
+
solidity: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
904
|
+
class: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
905
|
+
c4: "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1",
|
|
906
|
+
// 中身は payload が持ち、 図そのものは 1 箱。 矢印は描かず本数を数えて知らせる
|
|
907
|
+
gantt: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
908
|
+
pie: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
909
|
+
bar: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
910
|
+
line: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
911
|
+
funnel: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
912
|
+
tree: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
913
|
+
journey: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
914
|
+
quadrant: "\u56F3\u5168\u4F53\u3092 1 \u7BB1",
|
|
915
|
+
mind: "\u56F3\u5168\u4F53\u3092 1 \u7BB1"
|
|
916
|
+
};
|
|
917
|
+
function dropUnresolvedFlow(doc) {
|
|
918
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return doc;
|
|
919
|
+
const \u8868 = actorRefTable(doc);
|
|
920
|
+
const flow2 = doc.flow.filter((s) => \u8868.has(s.from) && \u8868.has(s.to));
|
|
921
|
+
return flow2.length === doc.flow.length ? doc : { ...doc, flow: flow2 };
|
|
922
|
+
}
|
|
923
|
+
function dropSelfLoopFlow(doc) {
|
|
924
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return doc;
|
|
925
|
+
const flow2 = doc.flow.filter((s) => s.from !== s.to);
|
|
926
|
+
return flow2.length === doc.flow.length ? doc : { ...doc, flow: flow2 };
|
|
927
|
+
}
|
|
928
|
+
function reportSelfLoopFlow(doc, onNotice) {
|
|
929
|
+
if (!onNotice) return;
|
|
930
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return;
|
|
931
|
+
const \u77E5\u3089\u305B\u305F = /* @__PURE__ */ new Set();
|
|
932
|
+
for (const s of doc.flow) {
|
|
933
|
+
if (s.from !== s.to || \u77E5\u3089\u305B\u305F.has(s.from)) continue;
|
|
934
|
+
\u77E5\u3089\u305B\u305F.add(s.from);
|
|
935
|
+
onNotice({
|
|
936
|
+
kind: "flow-self-loop",
|
|
937
|
+
actor: s.from,
|
|
938
|
+
line: s.pos.line,
|
|
939
|
+
message: `"${truncateForMessage(s.from)}" \u304B\u3089\u81EA\u5206\u3078\u623B\u308B\u77E2\u5370\u306F\u63CF\u3051\u307E\u305B\u3093 (\u7D44\u307F\u7ACB\u3066\u304B\u3089\u5916\u3057\u307E\u3057\u305F)`,
|
|
940
|
+
hint: "\u9014\u4E2D\u306E\u7BB1\u3092 1 \u3064\u8DB3\u3057\u3066 2 \u672C\u306B\u5206\u3051\u308B\u304B\u3001 \u6BB5 (animation) \u3067\u72B6\u614B\u304C\u5909\u308F\u308B\u69D8\u5B50\u3068\u3057\u3066\u898B\u305B\u308B"
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
function \u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc) {
|
|
945
|
+
return doc.eyebrow === void 0 ? {} : { eyebrow: doc.eyebrow };
|
|
946
|
+
}
|
|
947
|
+
function reportDocEyebrowNotHonored(doc, onNotice) {
|
|
948
|
+
if (!onNotice) return;
|
|
949
|
+
if (doc.eyebrow === void 0) return;
|
|
950
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] === "\u56F3\u5168\u4F53\u3092 1 \u7BB1") return;
|
|
951
|
+
onNotice({
|
|
952
|
+
kind: "eyebrow-not-honored",
|
|
953
|
+
actor: doc.title,
|
|
954
|
+
// 図の `pos` は常に 1 行目を指す。 書いた行に辿り着けるよう `eyebrowPos` を優先する
|
|
955
|
+
line: doc.eyebrowPos?.line ?? doc.pos?.line ?? 0,
|
|
956
|
+
message: `\u6700\u4E0A\u4F4D\u306B\u66F8\u3044\u305F eyebrow \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306F\u7BB1\u3054\u3068\u306B\u5206\u304B\u308C\u308B\u305F\u3081\u76F8\u624B\u304C\u6C7A\u307E\u308A\u307E\u305B\u3093)`,
|
|
957
|
+
hint: '\u7BB1\u3054\u3068\u306B\u66F8\u3044\u3066\u304F\u3060\u3055\u3044 (`- A: { eyebrow: "..." }`)'
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
function reportLaneMixed(doc, onNotice) {
|
|
961
|
+
const \u5BFE\u8C61 = doc.actors.filter((a) => a.partId === void 0);
|
|
962
|
+
const \u66F8\u3044\u305F = \u5BFE\u8C61.filter((a) => a.lane !== void 0);
|
|
963
|
+
if (\u66F8\u3044\u305F.length === 0 || \u66F8\u3044\u305F.length === \u5BFE\u8C61.length) return;
|
|
964
|
+
const \u66F8\u3044\u3066\u3044\u306A\u3044 = \u5BFE\u8C61.filter((a) => a.lane === void 0);
|
|
965
|
+
onNotice({
|
|
966
|
+
kind: "lane-not-honored",
|
|
967
|
+
actor: \u66F8\u3044\u3066\u3044\u306A\u3044[0]?.name ?? "",
|
|
968
|
+
line: \u66F8\u3044\u3066\u3044\u306A\u3044[0]?.pos?.line ?? 0,
|
|
969
|
+
message: `type: ${doc.type} \u3067\u306F\u7E26\u5217\u3092\u66F8\u304F\u306A\u3089\u5168\u3066\u306E\u7BB1\u306B\u66F8\u304D\u307E\u3059 (\u66F8\u3044\u3066\u3044\u306A\u3044\u7BB1: ${\u66F8\u3044\u3066\u3044\u306A\u3044.map((a) => truncateForMessage(a.name)).join(" / ")})`,
|
|
970
|
+
hint: "\u66F8\u304B\u306A\u304B\u3063\u305F\u7BB1\u3092\u3069\u306E\u7E26\u5217\u306B\u7F6E\u304F\u304B\u3092\u6C7A\u3081\u3089\u308C\u306A\u3044\u305F\u3081\u3001\u5168\u90E8\u66F8\u304F\u304B 1 \u3064\u3082\u66F8\u304B\u306A\u3044\u304B\u306B\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
function reportFlowEndpointNotHonored(doc, \u5143\u306E\u540D\u524D, onNotice) {
|
|
974
|
+
if (!onNotice) return;
|
|
975
|
+
if (!\u9396\u3067\u3064\u306A\u3050\u5F62\u304B(doc)) return;
|
|
976
|
+
const \u66F8\u3044\u305F\u540D\u524D = (name) => \u5143\u306E\u540D\u524D.get(name) ?? name;
|
|
977
|
+
const \u9396\u306E\u7D44 = /* @__PURE__ */ new Set();
|
|
978
|
+
doc.actors.forEach((a, i) => {
|
|
979
|
+
const \u6B21 = doc.actors[i + 1];
|
|
980
|
+
if (\u6B21 === void 0) return;
|
|
981
|
+
\u9396\u306E\u7D44.add(`${a.name}\0${\u6B21.name}`);
|
|
982
|
+
});
|
|
983
|
+
for (const s of doc.flow) {
|
|
984
|
+
if (\u9396\u306E\u7D44.has(`${s.from}\0${s.to}`)) continue;
|
|
985
|
+
onNotice({
|
|
986
|
+
kind: "flow-endpoint-not-honored",
|
|
987
|
+
actor: \u66F8\u3044\u305F\u540D\u524D(s.from),
|
|
988
|
+
line: s.pos.line,
|
|
989
|
+
message: `"${truncateForMessage(\u66F8\u3044\u305F\u540D\u524D(s.from))} -> ${truncateForMessage(\u66F8\u3044\u305F\u540D\u524D(s.to))}" \u306E\u7AEF\u306F\u4F7F\u308F\u308C\u307E\u305B\u3093 (type: flow \u306F\u767B\u5834\u4EBA\u7269\u3092\u66F8\u3044\u305F\u9806\u306B\u7E4B\u304E\u307E\u3059)`,
|
|
990
|
+
hint: "\u66F8\u3044\u305F\u7AEF\u3069\u304A\u308A\u306B\u7E4B\u3050\u306B\u306F\u3001\u7BB1\u306B lane: \u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044 (\u7E26\u5217\u3092\u66F8\u3044\u305F\u5F62\u306F\u66F8\u3044\u305F\u7AEF\u304C\u305D\u306E\u307E\u307E\u77E2\u5370\u306B\u306A\u308A\u307E\u3059)"
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
function reportLaneNotHonored(doc, onNotice) {
|
|
995
|
+
if (!onNotice) return;
|
|
996
|
+
if (doc.type === "mind") return;
|
|
997
|
+
const \u52B9\u304F\u56F3\u7A2E = \u7E26\u5217\u3092\u9078\u3079\u308B\u56F3\u7A2E.has(doc.type);
|
|
998
|
+
if (\u52B9\u304F\u56F3\u7A2E && \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F(doc.type, doc)) return;
|
|
999
|
+
if (\u52B9\u304F\u56F3\u7A2E) {
|
|
1000
|
+
reportLaneMixed(doc, onNotice);
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
for (const a of doc.actors) {
|
|
1004
|
+
if (a.partId !== void 0) continue;
|
|
1005
|
+
if (a.lane === void 0) continue;
|
|
1006
|
+
onNotice({
|
|
1007
|
+
kind: "lane-not-honored",
|
|
1008
|
+
actor: a.name,
|
|
1009
|
+
line: a.pos?.line ?? 0,
|
|
1010
|
+
message: `"${truncateForMessage(a.name)}" \u306B\u66F8\u3044\u305F lane \u306F\u52B9\u304D\u307E\u305B\u3093 (\u7E26\u5217\u306F type: ${doc.type} \u304C\u6C7A\u3081\u307E\u3059)`,
|
|
1011
|
+
hint: "\u7E26\u5217\u306F\u56F3\u7A2E\u304C\u6C7A\u3081\u308B\u305F\u3081\u7BB1\u304B\u3089\u306F\u9078\u3079\u307E\u305B\u3093\u3002 lane \u3092\u6D88\u3057\u3066\u304F\u3060\u3055\u3044 (\u898B\u672C\u3067\u306F\u5F35\u66FF\u3048\u5148\u3068\u3057\u3066\u4F7F\u3048\u307E\u3059)"
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
function \u540D\u524D\u306E\u5C3E(name) {
|
|
1016
|
+
let h = 2166136261;
|
|
1017
|
+
for (const c of name) {
|
|
1018
|
+
h ^= c.codePointAt(0) ?? 0;
|
|
1019
|
+
h = Math.imul(h, 16777619) >>> 0;
|
|
1020
|
+
}
|
|
1021
|
+
return h.toString(16).padStart(8, "0").slice(0, 6);
|
|
1022
|
+
}
|
|
1023
|
+
function cdl\u5074\u306Eslug(s) {
|
|
1024
|
+
return s.toLowerCase().replace(/[^a-z0-9-ゟ゠-ヿ一-龯]+/g, "-").replace(/^-|-$/g, "");
|
|
1025
|
+
}
|
|
1026
|
+
var \u7A7A\u306E\u5F62\u306E\u9003\u3052\u5148 = {
|
|
1027
|
+
sequence: ["actor-"],
|
|
1028
|
+
solidity: ["actor-"],
|
|
1029
|
+
swimlane: ["lane-"],
|
|
1030
|
+
flow: [],
|
|
1031
|
+
er: [],
|
|
1032
|
+
state: [],
|
|
1033
|
+
topology: [],
|
|
1034
|
+
class: [],
|
|
1035
|
+
c4: [],
|
|
1036
|
+
// 図全体を 1 箱で描く群 (作り替えないのでここは使わない)
|
|
1037
|
+
gantt: [],
|
|
1038
|
+
pie: [],
|
|
1039
|
+
bar: [],
|
|
1040
|
+
line: [],
|
|
1041
|
+
funnel: [],
|
|
1042
|
+
tree: [],
|
|
1043
|
+
journey: [],
|
|
1044
|
+
quadrant: [],
|
|
1045
|
+
mind: []
|
|
1046
|
+
};
|
|
1047
|
+
function id\u306B\u306A\u308B\u5F62(name, \u4F4D\u7F6E, \u9003\u3052\u5148\u306E\u982D = []) {
|
|
1048
|
+
const cdl = cdl\u5074\u306Eslug(name);
|
|
1049
|
+
const out = [slugify(name), cdl];
|
|
1050
|
+
if (cdl === "" && \u4F4D\u7F6E !== void 0) {
|
|
1051
|
+
for (const \u982D of \u9003\u3052\u5148\u306E\u982D) out.push(`${\u982D}${\u4F4D\u7F6E}`);
|
|
1052
|
+
}
|
|
1053
|
+
return out;
|
|
1054
|
+
}
|
|
1055
|
+
function disambiguateActorIds(doc, onNotice) {
|
|
1056
|
+
const \u5143\u306E\u540D\u524D = /* @__PURE__ */ new Map();
|
|
1057
|
+
if (\u56F3\u7A2E\u306E\u4F5C\u308A[doc.type] !== "\u767B\u5834\u4EBA\u7269\u3054\u3068\u306B\u7BB1") return { doc, \u5143\u306E\u540D\u524D };
|
|
1058
|
+
const \u898B\u305F = /* @__PURE__ */ new Set();
|
|
1059
|
+
const \u6B8B\u3059 = [];
|
|
1060
|
+
for (const a of doc.actors) {
|
|
1061
|
+
if (\u898B\u305F.has(a.name)) {
|
|
1062
|
+
onNotice?.({
|
|
1063
|
+
kind: "chart-value-unreadable",
|
|
1064
|
+
actor: a.name,
|
|
1065
|
+
line: a.pos?.line ?? 0,
|
|
1066
|
+
message: `"${truncateForMessage(a.name)}" \u3092 2 \u5EA6\u66F8\u3044\u3066\u3044\u307E\u3059 (\u5148\u306B\u66F8\u3044\u305F\u65B9\u3060\u3051\u63CF\u304D\u307E\u3059)`,
|
|
1067
|
+
hint: "\u9055\u3046\u540D\u524D\u306B\u3059\u308B\u304B\u3001 1 \u3064\u306B\u307E\u3068\u3081\u308B"
|
|
1068
|
+
});
|
|
1069
|
+
continue;
|
|
1070
|
+
}
|
|
1071
|
+
\u898B\u305F.add(a.name);
|
|
1072
|
+
\u6B8B\u3059.push(a);
|
|
1073
|
+
}
|
|
1074
|
+
const \u5F62\u3054\u3068\u306E\u540D\u524D = /* @__PURE__ */ new Map();
|
|
1075
|
+
const \u4F4D\u7F6E = /* @__PURE__ */ new Map();
|
|
1076
|
+
\u6B8B\u3059.forEach((a, i) => \u4F4D\u7F6E.set(a.name, i));
|
|
1077
|
+
const \u52D5\u304D\u3092\u66F8\u3044\u305F = (doc.animate?.phases.length ?? 0) > 0;
|
|
1078
|
+
const \u9003\u3052\u5148\u306E\u982D = \u52D5\u304D\u3092\u66F8\u3044\u305F ? [] : \u7A7A\u306E\u5F62\u306E\u9003\u3052\u5148[doc.type];
|
|
1079
|
+
for (const a of \u6B8B\u3059) {
|
|
1080
|
+
for (const \u5F62 of id\u306B\u306A\u308B\u5F62(a.name, \u4F4D\u7F6E.get(a.name), \u9003\u3052\u5148\u306E\u982D)) {
|
|
1081
|
+
const \u7FA4 = \u5F62\u3054\u3068\u306E\u540D\u524D.get(\u5F62) ?? /* @__PURE__ */ new Set();
|
|
1082
|
+
\u7FA4.add(a.name);
|
|
1083
|
+
\u5F62\u3054\u3068\u306E\u540D\u524D.set(\u5F62, \u7FA4);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
const \u91CD\u306A\u308B = (name) => id\u306B\u306A\u308B\u5F62(name, \u4F4D\u7F6E.get(name), \u9003\u3052\u5148\u306E\u982D).some(
|
|
1087
|
+
(\u5F62) => (\u5F62\u3054\u3068\u306E\u540D\u524D.get(\u5F62)?.size ?? 0) > 1
|
|
1088
|
+
);
|
|
1089
|
+
const \u4F5C\u308A\u66FF\u3048\u308B = \u6B8B\u3059.filter((a) => a.partId === void 0 && \u91CD\u306A\u308B(a.name));
|
|
1090
|
+
const \u4F7F\u3046\u5F62 = /* @__PURE__ */ new Set();
|
|
1091
|
+
for (const a of \u6B8B\u3059) {
|
|
1092
|
+
if (\u4F5C\u308A\u66FF\u3048\u308B.some((b) => b.name === a.name)) continue;
|
|
1093
|
+
for (const \u5F62 of id\u306B\u306A\u308B\u5F62(a.name)) \u4F7F\u3046\u5F62.add(\u5F62);
|
|
1094
|
+
}
|
|
1095
|
+
const \u65B0\u3057\u3044\u540D\u524D = /* @__PURE__ */ new Map();
|
|
1096
|
+
for (const a of [...\u4F5C\u308A\u66FF\u3048\u308B].sort((x, y) => x.name < y.name ? -1 : x.name > y.name ? 1 : 0)) {
|
|
1097
|
+
const \u5C3E = \u540D\u524D\u306E\u5C3E(a.name);
|
|
1098
|
+
const \u4F59\u5730 = ID_MAX - (\u5C3E.length + 1);
|
|
1099
|
+
const \u57FA\u5E95 = a.name.slice(0, \u4F59\u5730);
|
|
1100
|
+
let \u5019\u88DC = `${\u57FA\u5E95} ${\u5C3E}`;
|
|
1101
|
+
let n = 0;
|
|
1102
|
+
while (id\u306B\u306A\u308B\u5F62(\u5019\u88DC).some((\u5F62) => \u4F7F\u3046\u5F62.has(\u5F62))) {
|
|
1103
|
+
n += 1;
|
|
1104
|
+
\u5019\u88DC = `${\u57FA\u5E95.slice(0, \u4F59\u5730 - String(n).length)} ${\u5C3E}${n}`;
|
|
1105
|
+
}
|
|
1106
|
+
for (const \u5F62 of id\u306B\u306A\u308B\u5F62(\u5019\u88DC)) \u4F7F\u3046\u5F62.add(\u5F62);
|
|
1107
|
+
\u65B0\u3057\u3044\u540D\u524D.set(a.name, \u5019\u88DC);
|
|
1108
|
+
\u5143\u306E\u540D\u524D.set(\u5019\u88DC, a.name);
|
|
1109
|
+
}
|
|
1110
|
+
if (\u65B0\u3057\u3044\u540D\u524D.size === 0 && \u6B8B\u3059.length === doc.actors.length) return { doc, \u5143\u306E\u540D\u524D };
|
|
1111
|
+
const \u76F4\u3059 = (\u540D) => \u65B0\u3057\u3044\u540D\u524D.get(\u540D) ?? \u540D;
|
|
1112
|
+
const \u6B21 = {
|
|
1113
|
+
...doc,
|
|
1114
|
+
actors: \u6B8B\u3059.map((a) => \u65B0\u3057\u3044\u540D\u524D.has(a.name) ? { ...a, name: \u76F4\u3059(a.name) } : a),
|
|
1115
|
+
flow: doc.flow.map((s) => {
|
|
1116
|
+
const from = \u76F4\u3059(s.from);
|
|
1117
|
+
const to = \u76F4\u3059(s.to);
|
|
1118
|
+
return from === s.from && to === s.to ? s : { ...s, from, to };
|
|
1119
|
+
})
|
|
1120
|
+
};
|
|
1121
|
+
if (\u6B21.animate) {
|
|
1122
|
+
\u6B21.animate = {
|
|
1123
|
+
...\u6B21.animate,
|
|
1124
|
+
phases: \u6B21.animate.phases.map(
|
|
1125
|
+
(ph) => ph.highlight ? { ...ph, highlight: ph.highlight.map((h) => \u76F4\u3059(h)) } : ph
|
|
1126
|
+
)
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
\u6B21.actors = \u6B21.actors.map(
|
|
1130
|
+
(a) => a.posRel ? { ...a, posRel: { ...a.posRel, anchor: \u76F4\u3059(a.posRel.anchor) } } : a
|
|
1131
|
+
);
|
|
1132
|
+
return { doc: \u6B21, \u5143\u306E\u540D\u524D };
|
|
1133
|
+
}
|
|
1134
|
+
function collectRenamedTargets(diagram2, \u5143\u306E\u540D\u524D) {
|
|
1135
|
+
const \u7BB1 = /* @__PURE__ */ new Set();
|
|
1136
|
+
const \u67A0 = /* @__PURE__ */ new Set();
|
|
1137
|
+
if (\u5143\u306E\u540D\u524D.size === 0) return { \u7BB1, \u67A0 };
|
|
1138
|
+
for (const n of diagram2.nodes) if (\u5143\u306E\u540D\u524D.has(n.title)) \u7BB1.add(n.id);
|
|
1139
|
+
for (const l of diagram2.lanes) if (l.label !== void 0 && \u5143\u306E\u540D\u524D.has(l.label)) \u67A0.add(l.id);
|
|
1140
|
+
return { \u7BB1, \u67A0 };
|
|
1141
|
+
}
|
|
1142
|
+
function restoreActorNames(diagram2, \u5143\u306E\u540D\u524D, \u5BFE\u8C61) {
|
|
1143
|
+
if (\u5143\u306E\u540D\u524D.size === 0) return;
|
|
1144
|
+
for (const n of diagram2.nodes) {
|
|
1145
|
+
if (!\u5BFE\u8C61.\u7BB1.has(n.id)) continue;
|
|
1146
|
+
const \u5143 = \u5143\u306E\u540D\u524D.get(n.title);
|
|
1147
|
+
if (\u5143 !== void 0) n.title = \u5143;
|
|
1148
|
+
}
|
|
1149
|
+
for (const l of diagram2.lanes) {
|
|
1150
|
+
if (!\u5BFE\u8C61.\u67A0.has(l.id) || l.label === void 0) continue;
|
|
1151
|
+
const \u5143 = \u5143\u306E\u540D\u524D.get(l.label);
|
|
1152
|
+
if (\u5143 !== void 0) l.label = \u5143;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
function reportMissingFlowActors(doc, onNotice) {
|
|
1156
|
+
if (!onNotice) return;
|
|
1157
|
+
const \u8868 = actorRefTable(doc);
|
|
1158
|
+
const \u898B\u305B\u308B\u6570 = 8;
|
|
1159
|
+
const \u540D\u524D\u4E00\u89A7 = doc.actors.slice(0, \u898B\u305B\u308B\u6570).map((a) => truncateForMessage(a.name)).join(" / ");
|
|
1160
|
+
const \u6B8B\u308A = doc.actors.length - \u898B\u305B\u308B\u6570;
|
|
1161
|
+
const hint = doc.actors.length > 0 ? `actors \u306B\u66F8\u3044\u305F\u540D\u524D\u3067\u6307\u3059 (${\u540D\u524D\u4E00\u89A7}${\u6B8B\u308A > 0 ? ` \u307B\u304B ${\u6B8B\u308A} \u4EF6` : ""})` : "actors \u306B\u767B\u5834\u4EBA\u7269\u3092\u66F8\u304F";
|
|
1162
|
+
const \u77E5\u3089\u305B\u305F = /* @__PURE__ */ new Set();
|
|
1163
|
+
for (const s of doc.flow) {
|
|
1164
|
+
for (const ref of [s.from, s.to]) {
|
|
1165
|
+
if (\u8868.has(ref) || \u77E5\u3089\u305B\u305F.has(ref)) continue;
|
|
1166
|
+
\u77E5\u3089\u305B\u305F.add(ref);
|
|
1167
|
+
onNotice({
|
|
1168
|
+
kind: "flow-actor-missing",
|
|
1169
|
+
actor: ref,
|
|
1170
|
+
line: s.pos.line,
|
|
1171
|
+
message: `\u77E2\u5370\u304C "${truncateForMessage(ref)}" \u3092\u6307\u3057\u3066\u3044\u307E\u3059\u304C\u3001 actors \u306B\u66F8\u304B\u308C\u3066\u3044\u307E\u305B\u3093`,
|
|
1172
|
+
hint
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
812
1177
|
function reportMissingFocusTargets(doc, onNotice) {
|
|
813
1178
|
if (!onNotice || !doc.animate) return;
|
|
814
1179
|
const names = new Set(doc.actors.map((a) => a.name));
|
|
@@ -825,10 +1190,12 @@ function reportMissingFocusTargets(doc, onNotice) {
|
|
|
825
1190
|
tos.add(st.to);
|
|
826
1191
|
steps.set(st.from, tos);
|
|
827
1192
|
}
|
|
1193
|
+
const \u540D\u524D\u3078 = actorRefTable(doc);
|
|
1194
|
+
const \u63C3\u3048\u308B = (ref) => \u540D\u524D\u3078.get(ref) ?? ref;
|
|
828
1195
|
for (const phase of doc.animate.phases) {
|
|
829
1196
|
for (const raw of phase.highlight ?? []) {
|
|
830
1197
|
const entry = parseFocusEntry(raw, names);
|
|
831
|
-
const found = entry.kind === "edge" ? steps.get(entry.from)?.has(entry.to) ?? false : accepted.has(entry.name);
|
|
1198
|
+
const found = entry.kind === "edge" ? steps.get(\u63C3\u3048\u308B(entry.from))?.has(\u63C3\u3048\u308B(entry.to)) ?? false : accepted.has(entry.name);
|
|
832
1199
|
if (found) continue;
|
|
833
1200
|
onNotice({
|
|
834
1201
|
kind: "focus-target-missing",
|
|
@@ -1416,9 +1783,10 @@ function cleanupPlaceholderActor(target, doc, a) {
|
|
|
1416
1783
|
phase.activate = phase.activate.filter((id) => !relatedToActor(id) && !removedEdgeIds.has(id));
|
|
1417
1784
|
}
|
|
1418
1785
|
}
|
|
1419
|
-
function mergePartsFromActors(target, doc, partsCatalog, onNotice) {
|
|
1786
|
+
function mergePartsFromActors(target, doc, partsCatalog, onNotice, derivedSourceLines) {
|
|
1420
1787
|
const partsActors = doc.actors.filter((a) => a.partId !== void 0);
|
|
1421
1788
|
if (partsActors.length === 0) return target;
|
|
1789
|
+
const \u5024\u306E\u524D\u7F6E\u304D = \u5024\u306E\u524D\u7F6E\u304D\u3092\u4F5C\u308B(partsActors.map((a) => a.name));
|
|
1422
1790
|
if (!partsCatalog) {
|
|
1423
1791
|
if (typeof console !== "undefined" && console.warn) {
|
|
1424
1792
|
const names = partsActors.map((a) => `${a.name} (kind: ${a.partId ?? "?"})`).join(", ");
|
|
@@ -1474,7 +1842,21 @@ function mergePartsFromActors(target, doc, partsCatalog, onNotice) {
|
|
|
1474
1842
|
}
|
|
1475
1843
|
}
|
|
1476
1844
|
const t = partTargetSize(part, actor.posW, actor.posH, actor.scale);
|
|
1477
|
-
mergePartIntoDiagram(
|
|
1845
|
+
mergePartIntoDiagram(
|
|
1846
|
+
target,
|
|
1847
|
+
part,
|
|
1848
|
+
actor.name,
|
|
1849
|
+
merged,
|
|
1850
|
+
actor.lane,
|
|
1851
|
+
placeX,
|
|
1852
|
+
placeY,
|
|
1853
|
+
t.w,
|
|
1854
|
+
t.h,
|
|
1855
|
+
onNotice,
|
|
1856
|
+
actor.pos?.line ?? 0,
|
|
1857
|
+
derivedSourceLines,
|
|
1858
|
+
\u5024\u306E\u524D\u7F6E\u304D.get(actor.name)
|
|
1859
|
+
);
|
|
1478
1860
|
}
|
|
1479
1861
|
return target;
|
|
1480
1862
|
}
|
|
@@ -1493,15 +1875,47 @@ function applyColorHex(part, colorHex, stateOverride) {
|
|
|
1493
1875
|
}
|
|
1494
1876
|
return out;
|
|
1495
1877
|
}
|
|
1496
|
-
function
|
|
1878
|
+
function \u5024\u306E\u524D\u7F6E\u304D\u3092\u4F5C\u308B(\u540D\u524D\u305F\u3061) {
|
|
1879
|
+
const \u51FA\u529B = /* @__PURE__ */ new Map();
|
|
1880
|
+
const \u4F7F\u7528\u4E2D = /* @__PURE__ */ new Set();
|
|
1881
|
+
const \u6B21\u306E\u756A\u53F7 = /* @__PURE__ */ new Map();
|
|
1882
|
+
for (const \u540D\u524D of \u540D\u524D\u305F\u3061) {
|
|
1883
|
+
if (\u51FA\u529B.has(\u540D\u524D)) continue;
|
|
1884
|
+
let \u7D20 = \u540D\u524D.normalize("NFKC").replace(/[^A-Za-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1885
|
+
if (\u7D20 === "" || /^[0-9]/.test(\u7D20)) \u7D20 = `p${\u7D20}`;
|
|
1886
|
+
let \u5019\u88DC = \u7D20;
|
|
1887
|
+
let \u756A\u53F7 = \u6B21\u306E\u756A\u53F7.get(\u7D20) ?? 2;
|
|
1888
|
+
while (\u4F7F\u7528\u4E2D.has(\u5019\u88DC)) {
|
|
1889
|
+
\u5019\u88DC = `${\u7D20}_${\u756A\u53F7}`;
|
|
1890
|
+
\u756A\u53F7 += 1;
|
|
1891
|
+
}
|
|
1892
|
+
\u6B21\u306E\u756A\u53F7.set(\u7D20, \u756A\u53F7);
|
|
1893
|
+
\u4F7F\u7528\u4E2D.add(\u5019\u88DC);
|
|
1894
|
+
\u51FA\u529B.set(\u540D\u524D, \u5019\u88DC);
|
|
1895
|
+
}
|
|
1896
|
+
return \u51FA\u529B;
|
|
1897
|
+
}
|
|
1898
|
+
function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, offsetX, offsetY, targetW, targetH, onNotice, noticeLine = 0, derivedSourceLines, valueAlias) {
|
|
1497
1899
|
const prefix = (id) => `${alias}__${id}`;
|
|
1498
|
-
const
|
|
1900
|
+
const \u5024\u524D\u7F6E\u304D = valueAlias ?? alias;
|
|
1901
|
+
const valuePrefix = (id) => `${\u5024\u524D\u7F6E\u304D}__${id}`;
|
|
1902
|
+
const ownIdSet = /* @__PURE__ */ new Set([
|
|
1903
|
+
...part.states.map((s) => s.id),
|
|
1904
|
+
...(part.derived ?? []).map((d) => d.id)
|
|
1905
|
+
]);
|
|
1499
1906
|
const rewriteTemplate = (s) => {
|
|
1500
1907
|
if (!s) return s;
|
|
1501
|
-
return s.replace(/\{(
|
|
1502
|
-
return
|
|
1908
|
+
return s.replace(/\{(\w+)\}/g, (m, name) => {
|
|
1909
|
+
return ownIdSet.has(name) ? `{${valuePrefix(name)}}` : m;
|
|
1503
1910
|
});
|
|
1504
1911
|
};
|
|
1912
|
+
const rewriteDerivedExpression = (expression) => {
|
|
1913
|
+
try {
|
|
1914
|
+
return writeFormula(renameFormulaIdentifiers(parseFormula(expression), valuePrefix));
|
|
1915
|
+
} catch {
|
|
1916
|
+
return expression;
|
|
1917
|
+
}
|
|
1918
|
+
};
|
|
1505
1919
|
const targetLaneId = laneMapping;
|
|
1506
1920
|
const laneIdMap = /* @__PURE__ */ new Map();
|
|
1507
1921
|
const PARTS_LANE_GAP = 300;
|
|
@@ -1619,7 +2033,16 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1619
2033
|
hint: "\u8272\u306F `#ff0000` \u306E\u3088\u3046\u306A\u8272\u756A\u53F7\u304B\u3001 `red` \u306E\u3088\u3046\u306A\u8272\u540D\u3067\u66F8\u304F"
|
|
1620
2034
|
});
|
|
1621
2035
|
}
|
|
1622
|
-
target.states.push({ id:
|
|
2036
|
+
target.states.push({ id: valuePrefix(stateOrig.id), initial });
|
|
2037
|
+
}
|
|
2038
|
+
for (const derivedOrig of part.derived ?? []) {
|
|
2039
|
+
if (!target.derived) target.derived = [];
|
|
2040
|
+
const id = valuePrefix(derivedOrig.id);
|
|
2041
|
+
target.derived.push({
|
|
2042
|
+
id,
|
|
2043
|
+
expression: rewriteDerivedExpression(derivedOrig.expression)
|
|
2044
|
+
});
|
|
2045
|
+
recordDerivedSourceLine(derivedSourceLines, id, noticeLine);
|
|
1623
2046
|
}
|
|
1624
2047
|
for (const edgeOrig of part.edges) {
|
|
1625
2048
|
target.edges.push({
|
|
@@ -1649,8 +2072,8 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1649
2072
|
...phaseOrig,
|
|
1650
2073
|
id: prefix(phaseOrig.id),
|
|
1651
2074
|
activate: phaseOrig.activate.map(prefix),
|
|
1652
|
-
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId:
|
|
1653
|
-
sets: phaseOrig.sets.map((s) => ({ ...s, stateId:
|
|
2075
|
+
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId: valuePrefix(t.stateId) })),
|
|
2076
|
+
sets: phaseOrig.sets.map((s) => ({ ...s, stateId: valuePrefix(s.stateId) }))
|
|
1654
2077
|
});
|
|
1655
2078
|
}
|
|
1656
2079
|
} else {
|
|
@@ -1662,8 +2085,8 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1662
2085
|
const partPhase = part.phases[i];
|
|
1663
2086
|
targetPhase.duration = Math.max(targetPhase.duration, partPhase.duration);
|
|
1664
2087
|
targetPhase.activate = [...targetPhase.activate, ...partPhase.activate.map(prefix)];
|
|
1665
|
-
targetPhase.tweens = [...targetPhase.tweens, ...partPhase.tweens.map((t) => ({ ...t, stateId:
|
|
1666
|
-
targetPhase.sets = [...targetPhase.sets, ...partPhase.sets.map((s) => ({ ...s, stateId:
|
|
2088
|
+
targetPhase.tweens = [...targetPhase.tweens, ...partPhase.tweens.map((t) => ({ ...t, stateId: valuePrefix(t.stateId) }))];
|
|
2089
|
+
targetPhase.sets = [...targetPhase.sets, ...partPhase.sets.map((s) => ({ ...s, stateId: valuePrefix(s.stateId) }))];
|
|
1667
2090
|
}
|
|
1668
2091
|
for (let i = commonLen; i < partsLen; i++) {
|
|
1669
2092
|
const phaseOrig = part.phases[i];
|
|
@@ -1671,8 +2094,8 @@ function mergePartIntoDiagram(target, part, alias, stateOverride, laneMapping, o
|
|
|
1671
2094
|
...phaseOrig,
|
|
1672
2095
|
id: prefix(phaseOrig.id),
|
|
1673
2096
|
activate: phaseOrig.activate.map(prefix),
|
|
1674
|
-
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId:
|
|
1675
|
-
sets: phaseOrig.sets.map((s) => ({ ...s, stateId:
|
|
2097
|
+
tweens: phaseOrig.tweens.map((t) => ({ ...t, stateId: valuePrefix(t.stateId) })),
|
|
2098
|
+
sets: phaseOrig.sets.map((s) => ({ ...s, stateId: valuePrefix(s.stateId) }))
|
|
1676
2099
|
});
|
|
1677
2100
|
}
|
|
1678
2101
|
}
|
|
@@ -1692,6 +2115,15 @@ function deepRewriteStrings(value, rewrite, seen = /* @__PURE__ */ new WeakSet()
|
|
|
1692
2115
|
return out;
|
|
1693
2116
|
}
|
|
1694
2117
|
function applyEdgeInlineOptions(diagram2, doc, sourceLines) {
|
|
2118
|
+
if (\u9396\u3067\u3064\u306A\u3050\u5F62\u304B(doc)) {
|
|
2119
|
+
diagram2.edges.forEach((e, idx) => {
|
|
2120
|
+
const s = \u9396\u306E\u3069\u306E\u884C\u304B\u3089\u6765\u305F\u304B(doc, idx);
|
|
2121
|
+
if (s === void 0) return;
|
|
2122
|
+
sourceLines?.set(e.id, s.pos.line);
|
|
2123
|
+
\u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(e, s, doc);
|
|
2124
|
+
});
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
1695
2127
|
const used = /* @__PURE__ */ new Set();
|
|
1696
2128
|
const isSeqLike = doc.type === "sequence" || doc.type === "solidity";
|
|
1697
2129
|
doc.flow.forEach((s, stepIdx) => {
|
|
@@ -1707,20 +2139,35 @@ function applyEdgeInlineOptions(diagram2, doc, sourceLines) {
|
|
|
1707
2139
|
if (!target) return;
|
|
1708
2140
|
used.add(target.id);
|
|
1709
2141
|
sourceLines?.set(target.id, s.pos.line);
|
|
1710
|
-
|
|
1711
|
-
target.guard = s.guard;
|
|
1712
|
-
if (doc.type === "state" && target.sub === void 0) target.sub = s.guard;
|
|
1713
|
-
}
|
|
1714
|
-
if (s.cardinality !== void 0) {
|
|
1715
|
-
target.cardinality = s.cardinality;
|
|
1716
|
-
if (doc.type === "er" && !target.label.includes(s.cardinality)) {
|
|
1717
|
-
target.label = target.label ? `${target.label} (${s.cardinality})` : `(${s.cardinality})`;
|
|
1718
|
-
}
|
|
1719
|
-
}
|
|
1720
|
-
if (s.labelOffsetX !== void 0) target.labelOffsetX = s.labelOffsetX;
|
|
1721
|
-
if (s.labelOffsetY !== void 0) target.labelOffsetY = s.labelOffsetY;
|
|
2142
|
+
\u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(target, s, doc);
|
|
1722
2143
|
});
|
|
1723
2144
|
}
|
|
2145
|
+
function \u77E2\u5370\u3078\u66F8\u304D\u5199\u3059(target, s, doc) {
|
|
2146
|
+
if (s.sub !== void 0) target.sub = s.sub;
|
|
2147
|
+
if (s.guard !== void 0) {
|
|
2148
|
+
target.guard = s.guard;
|
|
2149
|
+
if (doc.type === "state" && target.sub === void 0) target.sub = s.guard;
|
|
2150
|
+
}
|
|
2151
|
+
if (s.cardinality !== void 0) {
|
|
2152
|
+
target.cardinality = s.cardinality;
|
|
2153
|
+
if (doc.type === "er" && !target.label.includes(s.cardinality)) {
|
|
2154
|
+
target.label = target.label ? `${target.label} (${s.cardinality})` : `(${s.cardinality})`;
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
if (s.labelOffsetX !== void 0) target.labelOffsetX = s.labelOffsetX;
|
|
2158
|
+
if (s.labelOffsetY !== void 0) target.labelOffsetY = s.labelOffsetY;
|
|
2159
|
+
if (s.overlay !== void 0) target.overlay = s.overlay;
|
|
2160
|
+
}
|
|
2161
|
+
function \u9396\u3067\u3064\u306A\u3050\u5F62\u304B(doc) {
|
|
2162
|
+
if (doc.type !== "flow") return false;
|
|
2163
|
+
if (doc.animate && doc.animate.phases.length > 0) return false;
|
|
2164
|
+
return !\u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("flow", doc);
|
|
2165
|
+
}
|
|
2166
|
+
function \u9396\u306E\u3069\u306E\u884C\u304B\u3089\u6765\u305F\u304B(doc, edgeIndex) {
|
|
2167
|
+
const to = doc.actors[edgeIndex + 1];
|
|
2168
|
+
if (to === void 0) return void 0;
|
|
2169
|
+
return doc.flow.find((s) => s.to === to.name);
|
|
2170
|
+
}
|
|
1724
2171
|
var DRAWABLE_KINDS = new Set(NODE_KINDS);
|
|
1725
2172
|
var KIND_ALIAS = {
|
|
1726
2173
|
eoa: "shape-wallet",
|
|
@@ -1731,13 +2178,312 @@ var KIND_ALIAS = {
|
|
|
1731
2178
|
library: "shape-code-block",
|
|
1732
2179
|
interface: "shape-code-block"
|
|
1733
2180
|
};
|
|
2181
|
+
function \u5F0F\u306B\u66F8\u304F\u6570(n) {
|
|
2182
|
+
if (!Number.isFinite(n)) return "0";
|
|
2183
|
+
const text = String(n);
|
|
2184
|
+
if (!/[eE]/.test(text)) return text;
|
|
2185
|
+
const [coefficient = "0", exponentText = "0"] = text.toLowerCase().split("e");
|
|
2186
|
+
const negative = coefficient.startsWith("-");
|
|
2187
|
+
const unsigned = negative ? coefficient.slice(1) : coefficient;
|
|
2188
|
+
const [whole = "0", fraction = ""] = unsigned.split(".");
|
|
2189
|
+
const digits = `${whole}${fraction}`;
|
|
2190
|
+
const decimalAt = whole.length + Number(exponentText);
|
|
2191
|
+
let expanded;
|
|
2192
|
+
if (decimalAt <= 0) expanded = `0.${"0".repeat(-decimalAt)}${digits}`;
|
|
2193
|
+
else if (decimalAt >= digits.length) expanded = `${digits}${"0".repeat(decimalAt - digits.length)}`;
|
|
2194
|
+
else expanded = `${digits.slice(0, decimalAt)}.${digits.slice(decimalAt)}`;
|
|
2195
|
+
return negative ? `-${expanded}` : expanded;
|
|
2196
|
+
}
|
|
2197
|
+
function \u5883\u76EE\u3092\u901A\u308B\u6642\u523B(\u533A\u9593, op, \u5883\u76EE) {
|
|
2198
|
+
const \u6E80\u305F\u3059 = (x) => {
|
|
2199
|
+
switch (op) {
|
|
2200
|
+
case ">=":
|
|
2201
|
+
return x >= \u5883\u76EE;
|
|
2202
|
+
case ">":
|
|
2203
|
+
return x > \u5883\u76EE;
|
|
2204
|
+
case "<=":
|
|
2205
|
+
return x <= \u5883\u76EE;
|
|
2206
|
+
case "<":
|
|
2207
|
+
return x < \u5883\u76EE;
|
|
2208
|
+
case "==":
|
|
2209
|
+
return x === \u5883\u76EE;
|
|
2210
|
+
case "!=":
|
|
2211
|
+
return x !== \u5883\u76EE;
|
|
2212
|
+
default:
|
|
2213
|
+
return false;
|
|
2214
|
+
}
|
|
2215
|
+
};
|
|
2216
|
+
if (\u6E80\u305F\u3059(\u533A\u9593.from)) return \u533A\u9593.start;
|
|
2217
|
+
if (op === "==") {
|
|
2218
|
+
const min = Math.min(\u533A\u9593.from, \u533A\u9593.to);
|
|
2219
|
+
const max = Math.max(\u533A\u9593.from, \u533A\u9593.to);
|
|
2220
|
+
if (\u5883\u76EE < min || \u5883\u76EE > max) return null;
|
|
2221
|
+
} else if (!\u6E80\u305F\u3059(\u533A\u9593.to)) {
|
|
2222
|
+
return null;
|
|
2223
|
+
}
|
|
2224
|
+
if (\u533A\u9593.to === \u533A\u9593.from) return null;
|
|
2225
|
+
const t = \u533A\u9593.start + \u533A\u9593.dur * (\u5883\u76EE - \u533A\u9593.from) / (\u533A\u9593.to - \u533A\u9593.from);
|
|
2226
|
+
if (!Number.isFinite(t)) return null;
|
|
2227
|
+
return Math.min(Math.max(t, \u533A\u9593.start), \u533A\u9593.end);
|
|
2228
|
+
}
|
|
2229
|
+
function foldValueTriggers(diagram2, doc, onNotice) {
|
|
2230
|
+
const \u51FA\u529B = /* @__PURE__ */ new Map();
|
|
2231
|
+
const \u304D\u3063\u304B\u3051\u4ED8\u304D = (doc.values ?? []).filter((v) => v.trigger !== void 0);
|
|
2232
|
+
if (\u304D\u3063\u304B\u3051\u4ED8\u304D.length === 0) return \u51FA\u529B;
|
|
2233
|
+
const \u5BA3\u8A00 = /* @__PURE__ */ new Map();
|
|
2234
|
+
for (const v of \u304D\u3063\u304B\u3051\u4ED8\u304D) if (!\u5BA3\u8A00.has(v.name)) \u5BA3\u8A00.set(v.name, v);
|
|
2235
|
+
const \u521D\u671F\u5024 = /* @__PURE__ */ new Map();
|
|
2236
|
+
for (const s of diagram2.states) {
|
|
2237
|
+
const n = Number(s.initial);
|
|
2238
|
+
if (Number.isFinite(n)) \u521D\u671F\u5024.set(s.id, n);
|
|
2239
|
+
}
|
|
2240
|
+
const \u6BB5\u306E\u756A\u53F7 = /* @__PURE__ */ new Map();
|
|
2241
|
+
diagram2.phases.forEach((p, i) => {
|
|
2242
|
+
if (!\u6BB5\u306E\u756A\u53F7.has(p.title)) \u6BB5\u306E\u756A\u53F7.set(p.title, i);
|
|
2243
|
+
if (!\u6BB5\u306E\u756A\u53F7.has(p.id)) \u6BB5\u306E\u756A\u53F7.set(p.id, i);
|
|
2244
|
+
});
|
|
2245
|
+
const \u89E3\u3051\u305F = /* @__PURE__ */ new Map();
|
|
2246
|
+
const \u89E3\u3051\u306A\u3044 = /* @__PURE__ */ new Set();
|
|
2247
|
+
const \u89E3\u6C7A\u4E2D = /* @__PURE__ */ new Set();
|
|
2248
|
+
const \u77E5\u3089\u305B\u308B = (v, message, hint) => {
|
|
2249
|
+
onNotice?.({ kind: "value-trigger-unresolved", actor: v.name, line: v.pos?.line ?? 0, message, hint });
|
|
2250
|
+
};
|
|
2251
|
+
const \u89E3\u304F = (name) => {
|
|
2252
|
+
const \u65E2\u51FA = \u89E3\u3051\u305F.get(name);
|
|
2253
|
+
if (\u65E2\u51FA) return \u65E2\u51FA;
|
|
2254
|
+
if (\u89E3\u3051\u306A\u3044.has(name)) return null;
|
|
2255
|
+
const v = \u5BA3\u8A00.get(name);
|
|
2256
|
+
if (!v || !v.trigger) return null;
|
|
2257
|
+
if (\u89E3\u6C7A\u4E2D.has(name)) {
|
|
2258
|
+
\u89E3\u3051\u306A\u3044.add(name);
|
|
2259
|
+
\u77E5\u3089\u305B\u308B(v, `"${name}" \u306E\u304D\u3063\u304B\u3051\u304C\u4E00\u5468\u3057\u3066\u3044\u307E\u3059`, "\u3069\u308C\u304B 1 \u3064\u3092 `trigger: step ...` \u306B\u5909\u3048\u308B");
|
|
2260
|
+
return null;
|
|
2261
|
+
}
|
|
2262
|
+
\u89E3\u6C7A\u4E2D.add(name);
|
|
2263
|
+
const \u533A\u9593 = \u7D44\u307F\u7ACB\u3066\u308B(v);
|
|
2264
|
+
\u89E3\u6C7A\u4E2D.delete(name);
|
|
2265
|
+
if (!\u533A\u9593) {
|
|
2266
|
+
\u89E3\u3051\u306A\u3044.add(name);
|
|
2267
|
+
return null;
|
|
2268
|
+
}
|
|
2269
|
+
\u89E3\u3051\u305F.set(name, \u533A\u9593);
|
|
2270
|
+
return \u533A\u9593;
|
|
2271
|
+
};
|
|
2272
|
+
const \u7D44\u307F\u7ACB\u3066\u308B = (v) => {
|
|
2273
|
+
const trigger = v.trigger;
|
|
2274
|
+
const from = \u521D\u671F\u5024.get(v.name) ?? 0;
|
|
2275
|
+
const to = v.to ?? 0;
|
|
2276
|
+
const dur = v.durationMs ?? 0;
|
|
2277
|
+
let \u6BB5 = 0;
|
|
2278
|
+
let start = 0;
|
|
2279
|
+
if (trigger.kind === "step") {
|
|
2280
|
+
const idx = \u6BB5\u306E\u756A\u53F7.get(trigger.step);
|
|
2281
|
+
if (idx === void 0) {
|
|
2282
|
+
\u77E5\u3089\u305B\u308B(v, `"${trigger.step}" \u3068\u3044\u3046\u6BB5\u304C\u3042\u308A\u307E\u305B\u3093`, "`animation:` \u306B\u305D\u306E\u540D\u524D\u306E\u6BB5\u3092\u66F8\u304F\u304B\u3001 \u6BB5\u306E\u540D\u524D\u306B\u5408\u308F\u305B\u308B");
|
|
2283
|
+
return null;
|
|
2284
|
+
}
|
|
2285
|
+
\u6BB5 = idx;
|
|
2286
|
+
start = 0;
|
|
2287
|
+
} else {
|
|
2288
|
+
const \u76F8\u624B = \u89E3\u304F(trigger.source);
|
|
2289
|
+
if (!\u76F8\u624B) {
|
|
2290
|
+
\u77E5\u3089\u305B\u308B(
|
|
2291
|
+
v,
|
|
2292
|
+
`"${trigger.source}" \u304C\u52D5\u304F\u5024\u3067\u306A\u3044\u305F\u3081\u3001 \u304D\u3063\u304B\u3051\u306E\u6642\u523B\u3092\u6C7A\u3081\u3089\u308C\u307E\u305B\u3093`,
|
|
2293
|
+
"\u898B\u5F35\u308B\u76F8\u624B\u3082 `trigger:` \u3092\u6301\u3064\u5024\u306B\u3059\u308B"
|
|
2294
|
+
);
|
|
2295
|
+
return null;
|
|
2296
|
+
}
|
|
2297
|
+
const at = \u5883\u76EE\u3092\u901A\u308B\u6642\u523B(\u76F8\u624B, trigger.op, trigger.threshold);
|
|
2298
|
+
if (at === null) {
|
|
2299
|
+
\u77E5\u3089\u305B\u308B(
|
|
2300
|
+
v,
|
|
2301
|
+
`"${trigger.source}" \u306F ${trigger.op} ${trigger.threshold} \u3092\u6E80\u305F\u3057\u307E\u305B\u3093`,
|
|
2302
|
+
"\u76F8\u624B\u304C\u901A\u308B\u5024\u3092\u5883\u76EE\u306B\u3059\u308B\u304B\u3001 \u76F8\u624B\u306E `to` \u3092\u898B\u76F4\u3059"
|
|
2303
|
+
);
|
|
2304
|
+
return null;
|
|
2305
|
+
}
|
|
2306
|
+
\u6BB5 = \u76F8\u624B.\u6BB5;
|
|
2307
|
+
start = at;
|
|
2308
|
+
}
|
|
2309
|
+
const \u6BB5\u306E\u9577\u3055 = diagram2.phases[\u6BB5]?.duration ?? 0;
|
|
2310
|
+
if (start + dur > \u6BB5\u306E\u9577\u3055) {
|
|
2311
|
+
\u77E5\u3089\u305B\u308B(
|
|
2312
|
+
v,
|
|
2313
|
+
`\u6BB5 "${diagram2.phases[\u6BB5]?.title ?? ""}" (${\u6BB5\u306E\u9577\u3055}ms) \u306B\u53CE\u307E\u308A\u307E\u305B\u3093 (${Math.round(start + dur)}ms \u5FC5\u8981)`,
|
|
2314
|
+
"\u6BB5\u3092\u9577\u304F\u3059\u308B\u304B `dur` \u3092\u77ED\u304F\u3059\u308B"
|
|
2315
|
+
);
|
|
2316
|
+
return null;
|
|
2317
|
+
}
|
|
2318
|
+
return { \u6BB5, start, end: start + dur, dur, from, to };
|
|
2319
|
+
};
|
|
2320
|
+
for (const v of \u5BA3\u8A00.values()) \u89E3\u304F(v.name);
|
|
2321
|
+
if (\u89E3\u3051\u305F.size === 0) return \u51FA\u529B;
|
|
2322
|
+
const \u4F7F\u7528\u4E2D = new Set(diagram2.states.map((s) => s.id));
|
|
2323
|
+
for (const v of doc.values ?? []) \u4F7F\u7528\u4E2D.add(v.name);
|
|
2324
|
+
const \u6BB5\u3054\u3068\u306E\u6642\u8A08 = /* @__PURE__ */ new Map();
|
|
2325
|
+
const \u6642\u8A08\u3092\u7528\u610F\u3059\u308B = (\u6BB5) => {
|
|
2326
|
+
const \u65E2\u51FA = \u6BB5\u3054\u3068\u306E\u6642\u8A08.get(\u6BB5);
|
|
2327
|
+
if (\u65E2\u51FA) return \u65E2\u51FA;
|
|
2328
|
+
let \u540D\u524D = `__step_clock_${\u6BB5}`;
|
|
2329
|
+
let \u9023\u756A = 2;
|
|
2330
|
+
while (\u4F7F\u7528\u4E2D.has(\u540D\u524D)) \u540D\u524D = `__step_clock_${\u6BB5}_${\u9023\u756A++}`;
|
|
2331
|
+
\u4F7F\u7528\u4E2D.add(\u540D\u524D);
|
|
2332
|
+
\u6BB5\u3054\u3068\u306E\u6642\u8A08.set(\u6BB5, \u540D\u524D);
|
|
2333
|
+
diagram2.states.push({ id: \u540D\u524D, initial: 0 });
|
|
2334
|
+
const \u6BB5\u306E\u4E2D\u8EAB = diagram2.phases[\u6BB5];
|
|
2335
|
+
if (\u6BB5\u306E\u4E2D\u8EAB) \u6BB5\u306E\u4E2D\u8EAB.tweens = [...\u6BB5\u306E\u4E2D\u8EAB.tweens, { stateId: \u540D\u524D, from: 0, to: \u6BB5\u306E\u4E2D\u8EAB.duration }];
|
|
2336
|
+
return \u540D\u524D;
|
|
2337
|
+
};
|
|
2338
|
+
for (const [name, \u533A\u9593] of \u89E3\u3051\u305F) {
|
|
2339
|
+
const \u6642\u8A08 = \u6642\u8A08\u3092\u7528\u610F\u3059\u308B(\u533A\u9593.\u6BB5);
|
|
2340
|
+
const \u9032\u307F = `min(max(({${\u6642\u8A08}} - ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.start)}) / ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.dur)}, 0), 1)`;
|
|
2341
|
+
\u51FA\u529B.set(name, `((${\u9032\u307F} * ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.to - \u533A\u9593.from)}) + ${\u5F0F\u306B\u66F8\u304F\u6570(\u533A\u9593.from)})`);
|
|
2342
|
+
}
|
|
2343
|
+
return \u51FA\u529B;
|
|
2344
|
+
}
|
|
2345
|
+
function attachDerivedValues(diagram2, doc, onNotice, inheritedSourceLines, foldedTriggers) {
|
|
2346
|
+
const values = doc.values ?? [];
|
|
2347
|
+
if (values.length === 0) {
|
|
2348
|
+
if ((diagram2.derived?.length ?? 0) > 0) {
|
|
2349
|
+
reportUnresolvedValues(diagram2, doc, onNotice, inheritedSourceLines);
|
|
2350
|
+
}
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
2353
|
+
const \u72B6\u614B\u306E\u540D\u524D = new Set(diagram2.states.map((s) => s.id));
|
|
2354
|
+
for (const v of values) {
|
|
2355
|
+
if (!\u72B6\u614B\u306E\u540D\u524D.has(v.name)) continue;
|
|
2356
|
+
if (v.trigger !== void 0) continue;
|
|
2357
|
+
onNotice?.({
|
|
2358
|
+
kind: "value-shadows-state",
|
|
2359
|
+
actor: v.name,
|
|
2360
|
+
line: v.pos?.line ?? 0,
|
|
2361
|
+
message: `"${v.name}" \u3092 states \u3068 values \u306E\u4E21\u65B9\u306B\u66F8\u3044\u3066\u3044\u307E\u3059\u3002 values \u3092\u4F7F\u3044\u307E\u3059`,
|
|
2362
|
+
hint: "states \u304B\u3089\u5916\u3059\u304B\u3001 values \u306E\u540D\u524D\u3092\u5909\u3048\u308B"
|
|
2363
|
+
});
|
|
2364
|
+
}
|
|
2365
|
+
const \u8F09\u305B\u308B = [];
|
|
2366
|
+
for (const v of values) {
|
|
2367
|
+
const expression = v.expression ?? foldedTriggers?.get(v.name);
|
|
2368
|
+
if (expression === void 0) continue;
|
|
2369
|
+
\u8F09\u305B\u308B.push({ id: v.name, expression });
|
|
2370
|
+
}
|
|
2371
|
+
diagram2.derived = [...\u8F09\u305B\u308B, ...diagram2.derived ?? []];
|
|
2372
|
+
reportUnresolvedValues(diagram2, doc, onNotice, inheritedSourceLines);
|
|
2373
|
+
}
|
|
2374
|
+
function renameFormulaIdentifiers(ast, rename) {
|
|
2375
|
+
switch (ast.type) {
|
|
2376
|
+
case "number":
|
|
2377
|
+
return ast;
|
|
2378
|
+
case "identifier":
|
|
2379
|
+
return { type: "identifier", name: rename(ast.name) };
|
|
2380
|
+
case "unaryOp":
|
|
2381
|
+
return { ...ast, operand: renameFormulaIdentifiers(ast.operand, rename) };
|
|
2382
|
+
case "binaryOp":
|
|
2383
|
+
return {
|
|
2384
|
+
...ast,
|
|
2385
|
+
left: renameFormulaIdentifiers(ast.left, rename),
|
|
2386
|
+
right: renameFormulaIdentifiers(ast.right, rename)
|
|
2387
|
+
};
|
|
2388
|
+
case "ternary":
|
|
2389
|
+
return {
|
|
2390
|
+
type: "ternary",
|
|
2391
|
+
condition: renameFormulaIdentifiers(ast.condition, rename),
|
|
2392
|
+
whenTrue: renameFormulaIdentifiers(ast.whenTrue, rename),
|
|
2393
|
+
whenFalse: renameFormulaIdentifiers(ast.whenFalse, rename)
|
|
2394
|
+
};
|
|
2395
|
+
case "call":
|
|
2396
|
+
return { ...ast, args: ast.args.map((a) => renameFormulaIdentifiers(a, rename)) };
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
function writeNumber(value) {
|
|
2400
|
+
if (!Number.isFinite(value)) throw new Error(`cannot write non-finite number: ${String(value)}`);
|
|
2401
|
+
const s = String(value);
|
|
2402
|
+
if (!/[eE]/.test(s)) return s;
|
|
2403
|
+
const m = /^(-?)(\d+)(?:\.(\d+))?[eE]([+-]?\d+)$/.exec(s);
|
|
2404
|
+
if (!m) throw new Error(`cannot write number: ${s}`);
|
|
2405
|
+
const sign = m[1] ?? "";
|
|
2406
|
+
const int = m[2] ?? "";
|
|
2407
|
+
const frac = m[3] ?? "";
|
|
2408
|
+
const digits = int + frac;
|
|
2409
|
+
const point = int.length + Number(m[4] ?? "0");
|
|
2410
|
+
if (point <= 0) return `${sign}0.${"0".repeat(-point)}${digits}`;
|
|
2411
|
+
if (point >= digits.length) return `${sign}${digits}${"0".repeat(point - digits.length)}`;
|
|
2412
|
+
return `${sign}${digits.slice(0, point)}.${digits.slice(point)}`;
|
|
2413
|
+
}
|
|
2414
|
+
function writeFormula(ast) {
|
|
2415
|
+
switch (ast.type) {
|
|
2416
|
+
case "number":
|
|
2417
|
+
return writeNumber(ast.value);
|
|
2418
|
+
case "identifier":
|
|
2419
|
+
return /^[A-Za-z_$][\w$]*$/.test(ast.name) ? ast.name : `{${ast.name}}`;
|
|
2420
|
+
case "unaryOp":
|
|
2421
|
+
return `(${ast.op}${writeFormula(ast.operand)})`;
|
|
2422
|
+
case "binaryOp":
|
|
2423
|
+
return `(${writeFormula(ast.left)} ${ast.op} ${writeFormula(ast.right)})`;
|
|
2424
|
+
case "ternary":
|
|
2425
|
+
return `(${writeFormula(ast.condition)} ? ${writeFormula(ast.whenTrue)} : ${writeFormula(ast.whenFalse)})`;
|
|
2426
|
+
case "call":
|
|
2427
|
+
return `${ast.fn}(${ast.args.map(writeFormula).join(", ")})`;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
function recordDerivedSourceLine(sourceLines, id, line) {
|
|
2431
|
+
if (!sourceLines) return;
|
|
2432
|
+
const lines = sourceLines.get(id) ?? [];
|
|
2433
|
+
lines.push(line);
|
|
2434
|
+
sourceLines.set(id, lines);
|
|
2435
|
+
}
|
|
2436
|
+
function reportUnresolvedValues(diagram2, doc, onNotice, inheritedSourceLines) {
|
|
2437
|
+
if (!onNotice) return;
|
|
2438
|
+
const \u521D\u671F\u5024 = /* @__PURE__ */ Object.create(null);
|
|
2439
|
+
for (const s of diagram2.states) \u521D\u671F\u5024[s.id] = String(s.initial);
|
|
2440
|
+
const \u6700\u521D\u306E\u884C = /* @__PURE__ */ new Map();
|
|
2441
|
+
const \u91CD\u8907\u3057\u305F\u884C = /* @__PURE__ */ new Map();
|
|
2442
|
+
for (const v of doc.values ?? []) {
|
|
2443
|
+
if (!\u6700\u521D\u306E\u884C.has(v.name)) {
|
|
2444
|
+
\u6700\u521D\u306E\u884C.set(v.name, v.pos?.line ?? 0);
|
|
2445
|
+
continue;
|
|
2446
|
+
}
|
|
2447
|
+
const \u540C\u3058\u540D\u524D\u306E\u884C = \u91CD\u8907\u3057\u305F\u884C.get(v.name) ?? [];
|
|
2448
|
+
\u540C\u3058\u540D\u524D\u306E\u884C.push(v.pos?.line ?? 0);
|
|
2449
|
+
\u91CD\u8907\u3057\u305F\u884C.set(v.name, \u540C\u3058\u540D\u524D\u306E\u884C);
|
|
2450
|
+
}
|
|
2451
|
+
for (const [id, lines] of inheritedSourceLines ?? []) {
|
|
2452
|
+
for (const line of lines) {
|
|
2453
|
+
if (!\u6700\u521D\u306E\u884C.has(id)) {
|
|
2454
|
+
\u6700\u521D\u306E\u884C.set(id, line);
|
|
2455
|
+
continue;
|
|
2456
|
+
}
|
|
2457
|
+
const \u540C\u3058\u540D\u524D\u306E\u884C = \u91CD\u8907\u3057\u305F\u884C.get(id) ?? [];
|
|
2458
|
+
\u540C\u3058\u540D\u524D\u306E\u884C.push(line);
|
|
2459
|
+
\u91CD\u8907\u3057\u305F\u884C.set(id, \u540C\u3058\u540D\u524D\u306E\u884C);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
for (const n of applyDerivedValues(\u521D\u671F\u5024, diagram2.derived).notices) {
|
|
2463
|
+
onNotice({
|
|
2464
|
+
kind: n.kind === "duplicate-id" ? "value-duplicate" : "value-unresolved",
|
|
2465
|
+
actor: n.id,
|
|
2466
|
+
// 重複は後から書いた宣言そのものを、式の問題は engine が使う最初の宣言を指す
|
|
2467
|
+
line: n.kind === "duplicate-id" ? \u91CD\u8907\u3057\u305F\u884C.get(n.id)?.shift() ?? \u6700\u521D\u306E\u884C.get(n.id) ?? 0 : \u6700\u521D\u306E\u884C.get(n.id) ?? 0,
|
|
2468
|
+
message: n.message,
|
|
2469
|
+
hint: VALUE_NOTICE_HINT[n.kind]
|
|
2470
|
+
});
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
var VALUE_NOTICE_HINT = {
|
|
2474
|
+
cycle: "\u53C2\u7167\u304C\u4E00\u5468\u3057\u3066\u3044\u307E\u3059\u3002 \u3069\u308C\u304B 1 \u3064\u3092 states \u306E\u521D\u671F\u5024\u306B\u5909\u3048\u308B",
|
|
2475
|
+
"unknown-reference": "\u305D\u306E\u540D\u524D\u306E states / values \u3092\u8DB3\u3059\u304B\u3001\u7DB4\u308A\u3092\u76F4\u3059",
|
|
2476
|
+
"parse-error": "\u5F0F\u306B\u66F8\u3051\u308B\u306E\u306F\u56DB\u5247 (+ - * /) \u3068\u62EC\u5F27\u3001\u6BD4\u8F03\u3001min / max \u3060\u3051",
|
|
2477
|
+
"eval-error": "\u521D\u671F\u5024\u3067\u8A08\u7B97\u3067\u304D\u306A\u3044\u5F62\u3067\u3059\u3002 \u5272\u308B\u6570\u3084\u3001\u6570\u3068\u3057\u3066\u8AAD\u3081\u306A\u3044\u521D\u671F\u5024\u3092\u898B\u76F4\u3059",
|
|
2478
|
+
"duplicate-id": "\u540C\u3058\u540D\u524D\u304C 2 \u5EA6\u3042\u308A\u307E\u3059\u3002 \u7247\u65B9\u3092\u6D88\u3059\u304B\u540D\u524D\u3092\u5909\u3048\u308B",
|
|
2479
|
+
"invalid-id": "\u540D\u524D\u306B\u4F7F\u3048\u308B\u306E\u306F\u82F1\u6570\u5B57\u3068 _ \u3060\u3051"
|
|
2480
|
+
};
|
|
1734
2481
|
var SINGLE_BOX_KINDS = /* @__PURE__ */ new Set([
|
|
1735
2482
|
"chart-pie",
|
|
1736
2483
|
"chart-line",
|
|
1737
2484
|
"chart-bar",
|
|
1738
2485
|
"gantt-timeline",
|
|
1739
2486
|
"mind-map",
|
|
1740
|
-
"mind-radial",
|
|
1741
2487
|
"funnel-stages",
|
|
1742
2488
|
"quadrant-matrix",
|
|
1743
2489
|
"tree-hierarchy",
|
|
@@ -1836,17 +2582,6 @@ function dropUnfittableEndKinds(diagram2, doc) {
|
|
|
1836
2582
|
}
|
|
1837
2583
|
}
|
|
1838
2584
|
}
|
|
1839
|
-
function fillFlowEdgeSources(diagram2, doc, sourceLines) {
|
|
1840
|
-
if (doc.type !== "flow") return;
|
|
1841
|
-
if (doc.animate && doc.animate.phases.length > 0) return;
|
|
1842
|
-
diagram2.edges.forEach((e, idx) => {
|
|
1843
|
-
const to = doc.actors[idx + 1];
|
|
1844
|
-
if (to === void 0) return;
|
|
1845
|
-
const step = doc.flow.find((s) => s.to === to.name);
|
|
1846
|
-
if (step === void 0) return;
|
|
1847
|
-
sourceLines.set(e.id, step.pos.line);
|
|
1848
|
-
});
|
|
1849
|
-
}
|
|
1850
2585
|
function applyGroupContainers(diagram2, doc) {
|
|
1851
2586
|
if (!doc.groups || Object.keys(doc.groups).length === 0) return;
|
|
1852
2587
|
for (const [id, g] of Object.entries(doc.groups)) {
|
|
@@ -1883,10 +2618,57 @@ function compileSolidity(doc) {
|
|
|
1883
2618
|
const sortedDoc = { ...doc, actors: sorted };
|
|
1884
2619
|
return compileSequence(sortedDoc);
|
|
1885
2620
|
}
|
|
2621
|
+
function \u72B6\u614B\u304C\u53D6\u308B\u5024(\u53C2\u7167, doc) {
|
|
2622
|
+
const \u540D = \u53C2\u7167.slice(1, -1);
|
|
2623
|
+
const out = [];
|
|
2624
|
+
const \u6570\u306B\u3059\u308B = (v) => {
|
|
2625
|
+
if (typeof v === "number") {
|
|
2626
|
+
if (Number.isFinite(v)) out.push(v);
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
const \u6587\u5B57 = String(v).trim();
|
|
2630
|
+
if (\u6587\u5B57 === "") return;
|
|
2631
|
+
const n = Number(\u6587\u5B57);
|
|
2632
|
+
if (Number.isFinite(n)) out.push(n);
|
|
2633
|
+
};
|
|
2634
|
+
for (const st of doc.animate?.states ?? []) if (st.name === \u540D) \u6570\u306B\u3059\u308B(st.initial);
|
|
2635
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2636
|
+
for (const t of p.tweens ?? []) {
|
|
2637
|
+
if (t.state !== \u540D) continue;
|
|
2638
|
+
\u6570\u306B\u3059\u308B(t.from);
|
|
2639
|
+
\u6570\u306B\u3059\u308B(t.to);
|
|
2640
|
+
}
|
|
2641
|
+
for (const v of p.sets ?? []) if (v.state === \u540D) \u6570\u306B\u3059\u308B(v.value);
|
|
2642
|
+
}
|
|
2643
|
+
return out;
|
|
2644
|
+
}
|
|
2645
|
+
function \u7D42\u308F\u308B\u4F4D\u7F6E(end, \u59CB\u307E\u308A, \u76EE\u76DB\u308A, \u540D\u524D, \u4F1D\u3048\u308B, doc) {
|
|
2646
|
+
if (end === void 0) return { idx: \u59CB\u307E\u308A };
|
|
2647
|
+
if (/^\{\w+\}$/.test(end)) {
|
|
2648
|
+
const \u4F4E\u3044 = \u72B6\u614B\u304C\u53D6\u308B\u5024(end, doc).filter((v) => v < \u59CB\u307E\u308A);
|
|
2649
|
+
if (\u4F4E\u3044.length > 0) {
|
|
2650
|
+
\u4F1D\u3048\u308B(
|
|
2651
|
+
\u540D\u524D,
|
|
2652
|
+
`type: gantt \u3067 ${truncateForMessage(\u540D\u524D)} \u306E\u7D42\u308F\u308A (${truncateForMessage(end)}) \u304C\u59CB\u307E\u308A\u3088\u308A\u524D\u306B\u306A\u308B\u5024\u3092\u53D6\u308A\u307E\u3059 (${[...new Set(\u4F4E\u3044)].join(", ")})\u3002 \u59CB\u307E\u308A\u306F ${\u59CB\u307E\u308A} \u756A\u76EE\u3067\u3059`
|
|
2653
|
+
);
|
|
2654
|
+
}
|
|
2655
|
+
return { idx: end };
|
|
2656
|
+
}
|
|
2657
|
+
const i = \u76EE\u76DB\u308A.indexOf(end);
|
|
2658
|
+
if (i < 0) return { idx: \u59CB\u307E\u308A };
|
|
2659
|
+
if (i < \u59CB\u307E\u308A) {
|
|
2660
|
+
\u4F1D\u3048\u308B(
|
|
2661
|
+
\u540D\u524D,
|
|
2662
|
+
`type: gantt \u3067 ${truncateForMessage(\u540D\u524D)} \u306E\u7D42\u308F\u308A (${truncateForMessage(end)}) \u304C\u59CB\u307E\u308A\u3088\u308A\u524D\u3067\u3059 (\u59CB\u307E\u308A\u3068\u540C\u3058\u306B\u5012\u3057\u307E\u3057\u305F)`
|
|
2663
|
+
);
|
|
2664
|
+
return { idx: \u59CB\u307E\u308A };
|
|
2665
|
+
}
|
|
2666
|
+
return { idx: i, label: end };
|
|
2667
|
+
}
|
|
1886
2668
|
function compileGantt(doc) {
|
|
1887
2669
|
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
1888
2670
|
const CHART_W = 720;
|
|
1889
|
-
b.lane("gantt", { width: CHART_W
|
|
2671
|
+
b.lane("gantt", { width: CHART_W });
|
|
1890
2672
|
const \u76EE\u76DB\u308A = [];
|
|
1891
2673
|
const \u76EE\u76DB\u308A\u306A\u3057 = [];
|
|
1892
2674
|
const \u30BF\u30B9\u30AF = [];
|
|
@@ -1897,7 +2679,13 @@ function compileGantt(doc) {
|
|
|
1897
2679
|
continue;
|
|
1898
2680
|
}
|
|
1899
2681
|
if (!\u76EE\u76DB\u308A.includes(label)) \u76EE\u76DB\u308A.push(label);
|
|
1900
|
-
\u30BF\u30B9\u30AF.push({
|
|
2682
|
+
\u30BF\u30B9\u30AF.push({
|
|
2683
|
+
name: a.name,
|
|
2684
|
+
label,
|
|
2685
|
+
...a.tone !== void 0 ? { tone: a.tone } : {},
|
|
2686
|
+
...a.owner !== void 0 ? { owner: a.owner } : {},
|
|
2687
|
+
...a.end !== void 0 ? { end: a.end } : {}
|
|
2688
|
+
});
|
|
1901
2689
|
}
|
|
1902
2690
|
if (\u76EE\u76DB\u308A\u306A\u3057.length > 0 && typeof console !== "undefined" && console.warn) {
|
|
1903
2691
|
console.warn(
|
|
@@ -1928,24 +2716,30 @@ function compileGantt(doc) {
|
|
|
1928
2716
|
`[dragon] type: gantt \u306E\u77E2\u5370\u306F\u524D\u5F8C\u306E\u95A2\u4FC2\u3060\u3051\u3092\u4F7F\u3044\u307E\u3059 (\u6587\u5B57 / \u8272 / \u7DDA\u7A2E\u306F\u63CF\u3051\u307E\u305B\u3093): ${\u88C5\u98FE\u3064\u304D.join(", ")}`
|
|
1929
2717
|
);
|
|
1930
2718
|
}
|
|
2719
|
+
const \u9006\u5411\u304D\u3092\u4F1D\u3048\u308B = (_\u540D, message) => {
|
|
2720
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
2721
|
+
};
|
|
1931
2722
|
const CHART_H = Math.max(360, 48 * \u30BF\u30B9\u30AF.length + 96);
|
|
1932
2723
|
b.node(`${slugify(doc.title)}-chart`, {
|
|
1933
2724
|
lane: "gantt",
|
|
1934
2725
|
stack: 0,
|
|
1935
2726
|
kind: "gantt-timeline",
|
|
1936
2727
|
title: doc.title,
|
|
2728
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
1937
2729
|
w: CHART_W,
|
|
1938
2730
|
h: CHART_H,
|
|
1939
2731
|
ganttData: \u30BF\u30B9\u30AF.map((t) => {
|
|
1940
2732
|
const idx = \u76EE\u76DB\u308A.indexOf(t.label);
|
|
1941
2733
|
const from = \u4F9D\u5B58\u5143.get(t.name);
|
|
2734
|
+
const \u7D42\u308F\u308A = \u7D42\u308F\u308B\u4F4D\u7F6E(t.end, idx, \u76EE\u76DB\u308A, t.name, \u9006\u5411\u304D\u3092\u4F1D\u3048\u308B, doc);
|
|
1942
2735
|
return {
|
|
1943
2736
|
id: slugify(t.name),
|
|
1944
2737
|
title: t.name,
|
|
1945
2738
|
startIdx: idx,
|
|
1946
|
-
endIdx: idx,
|
|
2739
|
+
endIdx: \u7D42\u308F\u308A.idx,
|
|
1947
2740
|
startLabel: t.label,
|
|
1948
|
-
endLabel: t.label,
|
|
2741
|
+
endLabel: \u7D42\u308F\u308A.label ?? t.label,
|
|
2742
|
+
...t.owner !== void 0 ? { owner: t.owner } : {},
|
|
1949
2743
|
...from !== void 0 ? { dependsOn: slugify(from) } : {},
|
|
1950
2744
|
...t.tone !== void 0 ? { tone: t.tone } : {}
|
|
1951
2745
|
};
|
|
@@ -1956,13 +2750,15 @@ function compileGantt(doc) {
|
|
|
1956
2750
|
function compileClass(doc) {
|
|
1957
2751
|
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
1958
2752
|
const CLASS_W = 400;
|
|
2753
|
+
const CLASS_LANE_W = 450;
|
|
1959
2754
|
if (doc.actors.length === 0) return b.build();
|
|
1960
|
-
b.lane("class-stack", { width: CLASS_W, label: doc.title });
|
|
1961
2755
|
doc.actors.forEach((a, idx) => {
|
|
1962
2756
|
const nodeId = slugify(a.name);
|
|
2757
|
+
const laneId = `lane-${nodeId}`;
|
|
2758
|
+
b.lane(laneId, { width: CLASS_LANE_W });
|
|
1963
2759
|
b.node(nodeId, {
|
|
1964
|
-
lane:
|
|
1965
|
-
stack:
|
|
2760
|
+
lane: laneId,
|
|
2761
|
+
stack: 0,
|
|
1966
2762
|
kind: "storage",
|
|
1967
2763
|
title: a.name,
|
|
1968
2764
|
w: CLASS_W
|
|
@@ -1982,47 +2778,474 @@ function compileClass(doc) {
|
|
|
1982
2778
|
}
|
|
1983
2779
|
function parseShareValue(raw) {
|
|
1984
2780
|
if (raw === void 0) return null;
|
|
1985
|
-
const m = raw.trim().match(/^(
|
|
2781
|
+
const m = raw.trim().match(/^(-?\d+(?:\.\d+)?)\s*%?$/);
|
|
1986
2782
|
if (m === null) return null;
|
|
1987
2783
|
const v = Number(m[1]);
|
|
1988
2784
|
return Number.isFinite(v) ? v : null;
|
|
1989
2785
|
}
|
|
1990
|
-
function
|
|
2786
|
+
function parseBoundValue(raw) {
|
|
2787
|
+
if (raw === void 0) return null;
|
|
2788
|
+
const t = raw.trim();
|
|
2789
|
+
return /^\{\w+(?:\.(?:length|sum|max|min|avg)|\[\d+\])?\}$/.test(t) ? t : null;
|
|
2790
|
+
}
|
|
2791
|
+
function parseChartValue(raw) {
|
|
2792
|
+
const n = parseShareValue(raw);
|
|
2793
|
+
if (n !== null) return n;
|
|
2794
|
+
return parseBoundValue(raw);
|
|
2795
|
+
}
|
|
2796
|
+
function \u53C2\u7167\u3059\u308B\u540D\u524D(value) {
|
|
2797
|
+
if (typeof value !== "string") return null;
|
|
2798
|
+
const m = value.match(/^\{(\w+)/);
|
|
2799
|
+
return m ? m[1] : null;
|
|
2800
|
+
}
|
|
2801
|
+
function compileValueChart(doc, \u578B, kind, onNotice) {
|
|
1991
2802
|
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
1992
2803
|
const CHART_W = 640;
|
|
1993
|
-
const CHART_H = 320;
|
|
1994
|
-
b.lane("chart", { width: CHART_W + 64
|
|
2804
|
+
const CHART_H = \u578B === "pie" ? 320 : 368;
|
|
2805
|
+
b.lane("chart", { width: CHART_W + 64 });
|
|
1995
2806
|
const data = [];
|
|
1996
2807
|
const \u8AAD\u3081\u306A\u3044 = [];
|
|
2808
|
+
const \u672A\u5BA3\u8A00 = [];
|
|
2809
|
+
let \u672A\u5BA3\u8A00\u884C = 0;
|
|
2810
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u6570\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc);
|
|
2811
|
+
let \u8AAD\u3081\u306A\u3044\u884C = 0;
|
|
1997
2812
|
for (const a of doc.actors) {
|
|
1998
|
-
const value =
|
|
1999
|
-
if (value === null) {
|
|
2813
|
+
const value = parseChartValue(a.value ?? a.subtitle);
|
|
2814
|
+
if (value === null || typeof value === "number" && value < 0 && \u578B !== "line") {
|
|
2815
|
+
if (\u8AAD\u3081\u306A\u3044.length === 0) \u8AAD\u3081\u306A\u3044\u884C = a.pos?.line ?? 0;
|
|
2000
2816
|
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
2001
2817
|
continue;
|
|
2002
2818
|
}
|
|
2819
|
+
const \u540D\u524D = \u53C2\u7167\u3059\u308B\u540D\u524D(value);
|
|
2820
|
+
if (\u540D\u524D !== null && !\u53C2\u7167\u3067\u304D\u308B.has(\u540D\u524D)) {
|
|
2821
|
+
if (\u672A\u5BA3\u8A00.length === 0) \u672A\u5BA3\u8A00\u884C = a.pos?.line ?? 0;
|
|
2822
|
+
\u672A\u5BA3\u8A00.push(a.name);
|
|
2823
|
+
continue;
|
|
2824
|
+
}
|
|
2003
2825
|
data.push({ label: a.name, value, ...a.tone !== void 0 ? { tone: a.tone } : {} });
|
|
2004
2826
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2827
|
+
const \u8A9E = \u578B === "pie" ? { \u91CF: "\u5272\u5408", \u56F3: "\u5186", \u4F8B: '"45%"' } : \u578B === "bar" ? { \u91CF: "\u5024", \u56F3: "\u68D2", \u4F8B: '"420"' } : { \u91CF: "\u5024", \u56F3: "\u6298\u308C\u7DDA", \u4F8B: '"180"' };
|
|
2828
|
+
const \u4F1D\u3048\u308B = (\u7A2E\u985E, \u540D\u524D, message, line = 0) => {
|
|
2829
|
+
onNotice?.({ kind: \u7A2E\u985E, actor: \u540D\u524D, line, message });
|
|
2830
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
2831
|
+
};
|
|
2832
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
2833
|
+
\u4F1D\u3048\u308B(
|
|
2834
|
+
"chart-value-unreadable",
|
|
2835
|
+
\u8AAD\u3081\u306A\u3044[0],
|
|
2836
|
+
`type: ${\u578B} \u3067${\u8A9E.\u91CF}\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (${\u8A9E.\u56F3}\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u540D\u524D: ${\u8A9E.\u4F8B}\` \u306E\u5F62\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
|
|
2837
|
+
\u8AAD\u3081\u306A\u3044\u884C
|
|
2008
2838
|
);
|
|
2009
2839
|
}
|
|
2010
|
-
if (
|
|
2011
|
-
|
|
2012
|
-
|
|
2840
|
+
if (\u672A\u5BA3\u8A00.length > 0) {
|
|
2841
|
+
\u4F1D\u3048\u308B(
|
|
2842
|
+
"chart-value-unreadable",
|
|
2843
|
+
\u672A\u5BA3\u8A00[0],
|
|
2844
|
+
`type: ${\u578B} \u3067\u6570\u306B\u306A\u3089\u306A\u3044\u5024\u3092\u53C2\u7167\u3057\u305F\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (${\u8A9E.\u56F3}\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u672A\u5BA3\u8A00.join(", ")}\u3002 \`states:\` \u306B\u305D\u306E\u540D\u524D\u3092\u6570\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
|
|
2845
|
+
\u672A\u5BA3\u8A00\u884C
|
|
2846
|
+
);
|
|
2847
|
+
}
|
|
2848
|
+
if (doc.flow.length > 0) {
|
|
2849
|
+
\u4F1D\u3048\u308B(
|
|
2850
|
+
"chart-edge-dropped",
|
|
2851
|
+
doc.flow[0]?.from ?? "",
|
|
2852
|
+
`type: ${\u578B} \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`,
|
|
2853
|
+
doc.flow[0]?.pos?.line ?? 0
|
|
2013
2854
|
);
|
|
2014
2855
|
}
|
|
2015
2856
|
b.node(`${slugify(doc.title)}-chart`, {
|
|
2016
2857
|
lane: "chart",
|
|
2017
2858
|
stack: 0,
|
|
2018
|
-
kind
|
|
2859
|
+
kind,
|
|
2019
2860
|
title: doc.title,
|
|
2861
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
2020
2862
|
w: CHART_W,
|
|
2021
2863
|
h: CHART_H,
|
|
2022
2864
|
chartData: data
|
|
2023
2865
|
});
|
|
2024
2866
|
return b.build();
|
|
2025
2867
|
}
|
|
2868
|
+
var \u56F3\u8868\u306E\u5927\u304D\u3055 = {
|
|
2869
|
+
funnel: { w: 560, h: 480 },
|
|
2870
|
+
tree: { w: 720, h: 480 },
|
|
2871
|
+
mind: { w: 720, h: 480 },
|
|
2872
|
+
journey: { w: 720, h: 480 },
|
|
2873
|
+
quadrant: { w: 640, h: 480 }
|
|
2874
|
+
};
|
|
2875
|
+
var \u6C17\u6301\u3061 = /* @__PURE__ */ new Map([
|
|
2876
|
+
["\u6700\u9AD8", "delighted"],
|
|
2877
|
+
["\u6E80\u8DB3", "happy"],
|
|
2878
|
+
["\u666E\u901A", "neutral"],
|
|
2879
|
+
["\u4E0D\u6E80", "frustrated"],
|
|
2880
|
+
["\u6012\u308A", "angry"]
|
|
2881
|
+
]);
|
|
2882
|
+
var \u533A\u753B = /* @__PURE__ */ new Map([
|
|
2883
|
+
["\u5DE6\u4E0A", "topLeft"],
|
|
2884
|
+
["\u53F3\u4E0A", "topRight"],
|
|
2885
|
+
["\u5DE6\u4E0B", "bottomLeft"],
|
|
2886
|
+
["\u53F3\u4E0B", "bottomRight"]
|
|
2887
|
+
]);
|
|
2888
|
+
function \u56F3\u8868\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u6B04) {
|
|
2889
|
+
const \u5B9F\u52B9 = /* @__PURE__ */ new Map();
|
|
2890
|
+
for (const s of doc.animate?.states ?? []) \u5B9F\u52B9.set(s.name, s.initial);
|
|
2891
|
+
const \u58CA\u308C\u308B = /* @__PURE__ */ new Set();
|
|
2892
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2893
|
+
for (const st of p.sets ?? []) if (!\u6B04.\u8AAD\u3081\u308B\u304B(st.value)) \u58CA\u308C\u308B.add(st.state);
|
|
2894
|
+
if (\u6B04.\u88DC\u9593\u3067\u58CA\u308C\u308B\u304B) for (const tw of p.tweens ?? []) \u58CA\u308C\u308B.add(tw.state);
|
|
2895
|
+
}
|
|
2896
|
+
const out = /* @__PURE__ */ new Set();
|
|
2897
|
+
for (const [\u540D\u524D, \u5024] of \u5B9F\u52B9) {
|
|
2898
|
+
if (!\u6B04.\u8AAD\u3081\u308B\u304B(\u5024)) continue;
|
|
2899
|
+
if (\u58CA\u308C\u308B.has(\u540D\u524D)) continue;
|
|
2900
|
+
out.add(\u540D\u524D);
|
|
2901
|
+
}
|
|
2902
|
+
if (\u6B04.\u81EA\u52D5\u306E\u5024\u3092\u8A31\u3059\u304B) for (const v of doc.values ?? []) out.add(v.name);
|
|
2903
|
+
return out;
|
|
2904
|
+
}
|
|
2905
|
+
function \u6570\u3068\u3057\u3066\u8AAD\u3081\u308B\u304B(v) {
|
|
2906
|
+
if (typeof v === "number") return Number.isFinite(v);
|
|
2907
|
+
const t = v.trim();
|
|
2908
|
+
if (t === "") return false;
|
|
2909
|
+
return Number.isFinite(Number(t));
|
|
2910
|
+
}
|
|
2911
|
+
function \u6570\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc) {
|
|
2912
|
+
return \u56F3\u8868\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, {
|
|
2913
|
+
\u8AAD\u3081\u308B\u304B: \u6570\u3068\u3057\u3066\u8AAD\u3081\u308B\u304B,
|
|
2914
|
+
// 補間の行き先は数なので、数の欄では壊れない
|
|
2915
|
+
\u88DC\u9593\u3067\u58CA\u308C\u308B\u304B: false,
|
|
2916
|
+
\u81EA\u52D5\u306E\u5024\u3092\u8A31\u3059\u304B: true
|
|
2917
|
+
});
|
|
2918
|
+
}
|
|
2919
|
+
function \u8A9E\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u8A9E\u8868) {
|
|
2920
|
+
return \u56F3\u8868\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, {
|
|
2921
|
+
\u8AAD\u3081\u308B\u304B: (v) => \u8A9E\u8868.has(String(v).trim()),
|
|
2922
|
+
// 補間の行き先は数。 語の欄が読む状態を補間すると、その段で語が数に変わる
|
|
2923
|
+
\u88DC\u9593\u3067\u58CA\u308C\u308B\u304B: true,
|
|
2924
|
+
// 式の評価結果は数になるため、語の欄からは読めない
|
|
2925
|
+
\u81EA\u52D5\u306E\u5024\u3092\u8A31\u3059\u304B: false
|
|
2926
|
+
});
|
|
2927
|
+
}
|
|
2928
|
+
function \u8A9E\u306E\u72B6\u614B\u3092\u56F3\u306E\u8A9E\u3078\u76F4\u3059(diagram2) {
|
|
2929
|
+
const \u5BFE\u8C61 = /* @__PURE__ */ new Map();
|
|
2930
|
+
const \u6570\u306E\u6B04\u304B\u3089 = /* @__PURE__ */ new Set();
|
|
2931
|
+
const \u62FE\u3046 = (v, \u8A9E\u8868) => {
|
|
2932
|
+
const m = typeof v === "string" ? v.match(/^\{(\w+)/) : null;
|
|
2933
|
+
if (m) \u5BFE\u8C61.set(m[1], \u8A9E\u8868);
|
|
2934
|
+
};
|
|
2935
|
+
for (const n of diagram2.nodes) {
|
|
2936
|
+
for (const st of n.journeyData ?? []) \u62FE\u3046(st.emotion, \u6C17\u6301\u3061);
|
|
2937
|
+
for (const it of n.quadrantData?.items ?? []) \u62FE\u3046(it.quadrant, \u533A\u753B);
|
|
2938
|
+
for (const d of n.chartData ?? []) {
|
|
2939
|
+
const m = typeof d.value === "string" ? d.value.match(/^\{(\w+)/) : null;
|
|
2940
|
+
if (m) \u6570\u306E\u6B04\u304B\u3089.add(m[1]);
|
|
2941
|
+
}
|
|
2942
|
+
for (const f of n.funnelData ?? []) {
|
|
2943
|
+
const m = typeof f.count === "string" ? f.count.match(/^\{(\w+)/) : null;
|
|
2944
|
+
if (m) \u6570\u306E\u6B04\u304B\u3089.add(m[1]);
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
if (\u5BFE\u8C61.size === 0) return;
|
|
2948
|
+
const \u76F4\u3059 = (\u540D\u524D, \u5024) => {
|
|
2949
|
+
const \u8A9E\u8868 = \u5BFE\u8C61.get(\u540D\u524D);
|
|
2950
|
+
if (!\u8A9E\u8868 || \u6570\u306E\u6B04\u304B\u3089.has(\u540D\u524D)) return \u5024;
|
|
2951
|
+
return \u8A9E\u8868.get(String(\u5024).trim()) ?? \u5024;
|
|
2952
|
+
};
|
|
2953
|
+
for (const s of diagram2.states) s.initial = \u76F4\u3059(s.id, s.initial);
|
|
2954
|
+
for (const p of diagram2.phases) {
|
|
2955
|
+
for (const st of p.sets) st.value = \u76F4\u3059(st.stateId, st.value);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
function compileFunnel(doc, onNotice) {
|
|
2959
|
+
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
2960
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.funnel;
|
|
2961
|
+
b.lane("chart", { width: W + 64 });
|
|
2962
|
+
const data = [];
|
|
2963
|
+
const \u8AAD\u3081\u306A\u3044 = [];
|
|
2964
|
+
const \u672A\u5BA3\u8A00 = [];
|
|
2965
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u6570\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc);
|
|
2966
|
+
for (const a of doc.actors) {
|
|
2967
|
+
const v = parseChartValue(a.value ?? a.subtitle);
|
|
2968
|
+
if (v === null || typeof v === "number" && v < 0) {
|
|
2969
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
2970
|
+
continue;
|
|
2971
|
+
}
|
|
2972
|
+
const \u540D\u524D = \u53C2\u7167\u3059\u308B\u540D\u524D(v);
|
|
2973
|
+
if (\u540D\u524D !== null && !\u53C2\u7167\u3067\u304D\u308B.has(\u540D\u524D)) {
|
|
2974
|
+
\u672A\u5BA3\u8A00.push(a.name);
|
|
2975
|
+
continue;
|
|
2976
|
+
}
|
|
2977
|
+
data.push({ id: slugify(a.name), title: a.name, count: v });
|
|
2978
|
+
}
|
|
2979
|
+
if (\u672A\u5BA3\u8A00.length > 0) {
|
|
2980
|
+
const m3 = `type: funnel \u3067\u6570\u306B\u306A\u3089\u306A\u3044\u5024\u3092\u53C2\u7167\u3057\u305F\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u6BB5\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u672A\u5BA3\u8A00.join(", ")}\u3002 \`states:\` \u306B\u305D\u306E\u540D\u524D\u3092\u6570\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
2981
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u672A\u5BA3\u8A00[0], line: 0, message: m3 });
|
|
2982
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m3}`);
|
|
2983
|
+
}
|
|
2984
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
2985
|
+
const m = `type: funnel \u3067\u6570\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u6BB5\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u8A2A\u554F: "12000"\` \u306E\u5F62\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
2986
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u8AAD\u3081\u306A\u3044[0], line: 0, message: m });
|
|
2987
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m}`);
|
|
2988
|
+
}
|
|
2989
|
+
if (doc.flow.length > 0) {
|
|
2990
|
+
const m2 = `type: funnel \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`;
|
|
2991
|
+
onNotice?.({ kind: "chart-edge-dropped", actor: doc.flow[0]?.from ?? "", line: doc.flow[0]?.pos?.line ?? 0, message: m2 });
|
|
2992
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m2}`);
|
|
2993
|
+
}
|
|
2994
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
2995
|
+
lane: "chart",
|
|
2996
|
+
stack: 0,
|
|
2997
|
+
kind: "funnel-stages",
|
|
2998
|
+
title: doc.title,
|
|
2999
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3000
|
+
w: W,
|
|
3001
|
+
h: H,
|
|
3002
|
+
funnelData: data
|
|
3003
|
+
});
|
|
3004
|
+
return b.build();
|
|
3005
|
+
}
|
|
3006
|
+
function \u77E2\u5370\u304B\u3089\u89AA\u3092\u6C7A\u3081\u308B(doc, \u56F3\u7A2E, \u540D\u524D, \u4F1D\u3048\u308B) {
|
|
3007
|
+
const \u89AA = /* @__PURE__ */ new Map();
|
|
3008
|
+
for (const f of doc.flow) {
|
|
3009
|
+
const \u5B50 = slugify(f.to);
|
|
3010
|
+
const \u89AA\u540D = slugify(f.from);
|
|
3011
|
+
if (!\u540D\u524D.has(\u89AA\u540D)) {
|
|
3012
|
+
\u4F1D\u3048\u308B(f.from, `type: ${\u56F3\u7A2E} \u3067\u66F8\u3044\u3066\u3044\u306A\u3044\u540D\u524D\u3092\u89AA\u306B\u3057\u3066\u3044\u307E\u3059: ${f.from} -> ${f.to}`, f.pos?.line ?? 0);
|
|
3013
|
+
continue;
|
|
3014
|
+
}
|
|
3015
|
+
if (!\u540D\u524D.has(\u5B50)) {
|
|
3016
|
+
\u4F1D\u3048\u308B(f.to, `type: ${\u56F3\u7A2E} \u3067\u66F8\u3044\u3066\u3044\u306A\u3044\u540D\u524D\u3092\u5B50\u306B\u3057\u3066\u3044\u307E\u3059: ${f.from} -> ${f.to}`, f.pos?.line ?? 0);
|
|
3017
|
+
continue;
|
|
3018
|
+
}
|
|
3019
|
+
if (\u5B50 === \u89AA\u540D) {
|
|
3020
|
+
\u4F1D\u3048\u308B(f.to, `type: ${\u56F3\u7A2E} \u3067\u81EA\u5206\u3092\u89AA\u306B\u3057\u3066\u3044\u307E\u3059: ${f.to}`, f.pos?.line ?? 0);
|
|
3021
|
+
continue;
|
|
3022
|
+
}
|
|
3023
|
+
const \u65E2\u5B58 = \u89AA.get(\u5B50);
|
|
3024
|
+
if (\u65E2\u5B58 !== void 0 && \u65E2\u5B58 !== \u89AA\u540D) {
|
|
3025
|
+
\u4F1D\u3048\u308B(f.to, `type: ${\u56F3\u7A2E} \u3067 ${f.to} \u306B\u89AA\u304C 2 \u3064\u3042\u308A\u307E\u3059 (\u5F8C\u306E ${f.from} \u306F\u4F7F\u3044\u307E\u305B\u3093)`, f.pos?.line ?? 0);
|
|
3026
|
+
continue;
|
|
3027
|
+
}
|
|
3028
|
+
\u89AA.set(\u5B50, \u89AA\u540D);
|
|
3029
|
+
}
|
|
3030
|
+
for (const \u5B50 of [...\u89AA.keys()]) {
|
|
3031
|
+
const \u898B\u305F = /* @__PURE__ */ new Set([\u5B50]);
|
|
3032
|
+
let p2 = \u89AA.get(\u5B50);
|
|
3033
|
+
while (p2 !== void 0) {
|
|
3034
|
+
if (\u898B\u305F.has(p2)) {
|
|
3035
|
+
\u4F1D\u3048\u308B(\u5B50, `type: ${\u56F3\u7A2E} \u3067\u89AA\u3092\u8FBF\u308B\u3068\u8F2A\u306B\u306A\u308A\u307E\u3059 (${\u5B50} \u306E\u89AA\u3092\u5916\u3057\u307E\u3057\u305F)`);
|
|
3036
|
+
\u89AA.delete(\u5B50);
|
|
3037
|
+
break;
|
|
3038
|
+
}
|
|
3039
|
+
\u898B\u305F.add(p2);
|
|
3040
|
+
p2 = \u89AA.get(p2);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
return \u89AA;
|
|
3044
|
+
}
|
|
3045
|
+
function compileTree(doc, onNotice) {
|
|
3046
|
+
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
3047
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.tree;
|
|
3048
|
+
b.lane("chart", { width: W + 64 });
|
|
3049
|
+
const slug\u5225 = /* @__PURE__ */ new Map();
|
|
3050
|
+
for (const a of doc.actors) {
|
|
3051
|
+
const k = slugify(a.name);
|
|
3052
|
+
slug\u5225.set(k, [...slug\u5225.get(k) ?? [], a.name]);
|
|
3053
|
+
}
|
|
3054
|
+
const \u540D\u524D = new Set(slug\u5225.keys());
|
|
3055
|
+
const \u4F1D\u3048\u308B = (\u540D, message, line = 0) => {
|
|
3056
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u540D, line, message });
|
|
3057
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
3058
|
+
};
|
|
3059
|
+
for (const [k, \u7FA4] of slug\u5225) {
|
|
3060
|
+
if (\u7FA4.length > 1) {
|
|
3061
|
+
\u4F1D\u3048\u308B(\u7FA4[0], `type: tree \u3067 ${\u7FA4.join(" / ")} \u304C\u540C\u3058 id (${k}) \u306B\u306A\u308A\u307E\u3059\u3002 \u540D\u524D\u3092\u5909\u3048\u3066\u304F\u3060\u3055\u3044`);
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
const \u89AA = \u77E2\u5370\u304B\u3089\u89AA\u3092\u6C7A\u3081\u308B(doc, "tree", \u540D\u524D, \u4F1D\u3048\u308B);
|
|
3065
|
+
const data = doc.actors.map((a) => {
|
|
3066
|
+
const id = slugify(a.name);
|
|
3067
|
+
const p3 = \u89AA.get(id);
|
|
3068
|
+
return { id, title: a.name, ...p3 !== void 0 ? { parent: p3 } : {} };
|
|
3069
|
+
});
|
|
3070
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3071
|
+
lane: "chart",
|
|
3072
|
+
stack: 0,
|
|
3073
|
+
kind: "tree-hierarchy",
|
|
3074
|
+
title: doc.title,
|
|
3075
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3076
|
+
w: W,
|
|
3077
|
+
h: H,
|
|
3078
|
+
treeData: data
|
|
3079
|
+
});
|
|
3080
|
+
return b.build();
|
|
3081
|
+
}
|
|
3082
|
+
function \u9053\u7B4B\u306E\u6B04(a) {
|
|
3083
|
+
return {
|
|
3084
|
+
...a.touchpoint !== void 0 ? { touchpoint: a.touchpoint } : {},
|
|
3085
|
+
...a.opportunity !== void 0 ? { opportunity: a.opportunity } : {}
|
|
3086
|
+
};
|
|
3087
|
+
}
|
|
3088
|
+
function reportChartFieldsNotHonored(doc, onNotice) {
|
|
3089
|
+
if (!onNotice) return;
|
|
3090
|
+
if (doc.type === "mind") return;
|
|
3091
|
+
for (const a of doc.actors) {
|
|
3092
|
+
if (a.partId !== void 0) continue;
|
|
3093
|
+
const \u9053\u7B4B = doc.type === "journey" ? [] : [
|
|
3094
|
+
...a.touchpoint !== void 0 ? ["touchpoint"] : [],
|
|
3095
|
+
...a.opportunity !== void 0 ? ["opportunity"] : []
|
|
3096
|
+
];
|
|
3097
|
+
const \u5DE5\u7A0B = doc.type === "gantt" ? [] : [
|
|
3098
|
+
...a.owner !== void 0 ? ["owner"] : [],
|
|
3099
|
+
...a.end !== void 0 ? ["end"] : []
|
|
3100
|
+
];
|
|
3101
|
+
if (\u9053\u7B4B.length > 0) {
|
|
3102
|
+
onNotice({
|
|
3103
|
+
kind: "chart-value-unreadable",
|
|
3104
|
+
actor: a.name,
|
|
3105
|
+
line: a.pos?.line ?? 0,
|
|
3106
|
+
message: `"${truncateForMessage(a.name)}" \u306B\u66F8\u3044\u305F ${\u9053\u7B4B.join(" / ")} \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306B\u306F\u4F53\u9A13\u306E\u9053\u7B4B\u306E\u6B04\u304C\u3042\u308A\u307E\u305B\u3093)`,
|
|
3107
|
+
hint: "\u4F53\u9A13\u306E\u9053\u7B4B\u3092\u63CF\u304F\u306A\u3089 type: journey \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044"
|
|
3108
|
+
});
|
|
3109
|
+
}
|
|
3110
|
+
if (\u5DE5\u7A0B.length > 0) {
|
|
3111
|
+
onNotice({
|
|
3112
|
+
kind: "chart-value-unreadable",
|
|
3113
|
+
actor: a.name,
|
|
3114
|
+
line: a.pos?.line ?? 0,
|
|
3115
|
+
message: `"${truncateForMessage(a.name)}" \u306B\u66F8\u3044\u305F ${\u5DE5\u7A0B.join(" / ")} \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306B\u306F\u5DE5\u7A0B\u306E\u4E26\u3073\u306E\u6B04\u304C\u3042\u308A\u307E\u305B\u3093)`,
|
|
3116
|
+
hint: "\u5DE5\u7A0B\u306E\u4E26\u3073\u3092\u63CF\u304F\u306A\u3089 type: gantt \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044"
|
|
3117
|
+
});
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
function compileJourney(doc, onNotice) {
|
|
3122
|
+
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
3123
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.journey;
|
|
3124
|
+
b.lane("chart", { width: W + 64 });
|
|
3125
|
+
const data = [];
|
|
3126
|
+
const \u8AAD\u3081\u306A\u3044 = [];
|
|
3127
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u8A9E\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u6C17\u6301\u3061);
|
|
3128
|
+
for (const a of doc.actors) {
|
|
3129
|
+
const \u8A9E = (a.value ?? a.subtitle ?? "").trim();
|
|
3130
|
+
const \u53C2\u7167 = \u8A9E.match(/^\{(\w+)\}$/);
|
|
3131
|
+
if (\u53C2\u7167) {
|
|
3132
|
+
if (!\u53C2\u7167\u3067\u304D\u308B.has(\u53C2\u7167[1])) {
|
|
3133
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3134
|
+
continue;
|
|
3135
|
+
}
|
|
3136
|
+
data.push({ id: slugify(a.name), title: a.name, emotion: \u8A9E, ...\u9053\u7B4B\u306E\u6B04(a) });
|
|
3137
|
+
continue;
|
|
3138
|
+
}
|
|
3139
|
+
const e = \u6C17\u6301\u3061.get(\u8A9E);
|
|
3140
|
+
if (e === void 0) {
|
|
3141
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3142
|
+
continue;
|
|
3143
|
+
}
|
|
3144
|
+
data.push({ id: slugify(a.name), title: a.name, emotion: e, ...\u9053\u7B4B\u306E\u6B04(a) });
|
|
3145
|
+
}
|
|
3146
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
3147
|
+
const m = `type: journey \u3067\u6C17\u6301\u3061\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u9053\u7B4B\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u767B\u9332: "\u4E0D\u6E80"\` \u306E\u5F62\u3067\u3001 ${[...\u6C17\u6301\u3061.keys()].join(" / ")} \u306E\u3069\u308C\u304B\u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
3148
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u8AAD\u3081\u306A\u3044[0], line: 0, message: m });
|
|
3149
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m}`);
|
|
3150
|
+
}
|
|
3151
|
+
if (doc.flow.length > 0) {
|
|
3152
|
+
const m2 = `type: journey \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`;
|
|
3153
|
+
onNotice?.({ kind: "chart-edge-dropped", actor: doc.flow[0]?.from ?? "", line: doc.flow[0]?.pos?.line ?? 0, message: m2 });
|
|
3154
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m2}`);
|
|
3155
|
+
}
|
|
3156
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3157
|
+
lane: "chart",
|
|
3158
|
+
stack: 0,
|
|
3159
|
+
kind: "journey-map",
|
|
3160
|
+
title: doc.title,
|
|
3161
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3162
|
+
w: W,
|
|
3163
|
+
h: H,
|
|
3164
|
+
journeyData: data
|
|
3165
|
+
});
|
|
3166
|
+
return b.build();
|
|
3167
|
+
}
|
|
3168
|
+
var \u8EF8\u306E\u65E2\u5B9A = {
|
|
3169
|
+
xAxis: { left: "\u5C0F\u3055\u3044", right: "\u5927\u304D\u3044" },
|
|
3170
|
+
yAxis: { bottom: "\u5C0F\u3055\u3044", top: "\u5927\u304D\u3044" },
|
|
3171
|
+
quadrantLabels: { topLeft: "\u5DE6\u4E0A", topRight: "\u53F3\u4E0A", bottomLeft: "\u5DE6\u4E0B", bottomRight: "\u53F3\u4E0B" }
|
|
3172
|
+
};
|
|
3173
|
+
function \u8EF8\u3068\u533A\u753B\u306E\u540D\u524D(doc) {
|
|
3174
|
+
if (doc.axes === void 0) return \u8EF8\u306E\u65E2\u5B9A;
|
|
3175
|
+
const left = doc.axes.x?.left ?? \u8EF8\u306E\u65E2\u5B9A.xAxis.left;
|
|
3176
|
+
const right = doc.axes.x?.right ?? \u8EF8\u306E\u65E2\u5B9A.xAxis.right;
|
|
3177
|
+
const bottom = doc.axes.y?.bottom ?? \u8EF8\u306E\u65E2\u5B9A.yAxis.bottom;
|
|
3178
|
+
const top = doc.axes.y?.top ?? \u8EF8\u306E\u65E2\u5B9A.yAxis.top;
|
|
3179
|
+
return {
|
|
3180
|
+
xAxis: { left, right },
|
|
3181
|
+
yAxis: { bottom, top },
|
|
3182
|
+
quadrantLabels: {
|
|
3183
|
+
topLeft: `${top} \xD7 ${left}`,
|
|
3184
|
+
topRight: `${top} \xD7 ${right}`,
|
|
3185
|
+
bottomLeft: `${bottom} \xD7 ${left}`,
|
|
3186
|
+
bottomRight: `${bottom} \xD7 ${right}`
|
|
3187
|
+
}
|
|
3188
|
+
};
|
|
3189
|
+
}
|
|
3190
|
+
function reportAxesNotHonored(doc, onNotice) {
|
|
3191
|
+
if (!onNotice) return;
|
|
3192
|
+
if (doc.axes === void 0) return;
|
|
3193
|
+
if (doc.type === "quadrant") return;
|
|
3194
|
+
onNotice({
|
|
3195
|
+
kind: "chart-value-unreadable",
|
|
3196
|
+
actor: doc.title,
|
|
3197
|
+
line: doc.axesPos?.line ?? doc.pos?.line ?? 0,
|
|
3198
|
+
message: `\u6700\u4E0A\u4F4D\u306B\u66F8\u3044\u305F axes \u306F\u52B9\u304D\u307E\u305B\u3093 (type: ${doc.type} \u306B\u306F\u8EF8\u304C\u3042\u308A\u307E\u305B\u3093)`,
|
|
3199
|
+
hint: "2 \u3064\u306E\u8EF8\u3067\u4ED5\u5206\u3051\u308B\u56F3\u3092\u63CF\u304F\u306A\u3089 type: quadrant \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044"
|
|
3200
|
+
});
|
|
3201
|
+
}
|
|
3202
|
+
function compileQuadrant(doc, onNotice) {
|
|
3203
|
+
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
3204
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.quadrant;
|
|
3205
|
+
b.lane("chart", { width: W + 64 });
|
|
3206
|
+
const items = [];
|
|
3207
|
+
const \u8AAD\u3081\u306A\u3044 = [];
|
|
3208
|
+
const \u53C2\u7167\u3067\u304D\u308B = \u8A9E\u306E\u6B04\u304B\u3089\u53C2\u7167\u3067\u304D\u308B\u540D\u524D(doc, \u533A\u753B);
|
|
3209
|
+
for (const a of doc.actors) {
|
|
3210
|
+
const \u8A9E = (a.value ?? a.subtitle ?? "").trim();
|
|
3211
|
+
const \u53C2\u7167 = \u8A9E.match(/^\{(\w+)\}$/);
|
|
3212
|
+
if (\u53C2\u7167) {
|
|
3213
|
+
if (!\u53C2\u7167\u3067\u304D\u308B.has(\u53C2\u7167[1])) {
|
|
3214
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3215
|
+
continue;
|
|
3216
|
+
}
|
|
3217
|
+
items.push({ id: slugify(a.name), title: a.name, quadrant: \u8A9E });
|
|
3218
|
+
continue;
|
|
3219
|
+
}
|
|
3220
|
+
const q = \u533A\u753B.get(\u8A9E);
|
|
3221
|
+
if (q === void 0) {
|
|
3222
|
+
\u8AAD\u3081\u306A\u3044.push(a.name);
|
|
3223
|
+
continue;
|
|
3224
|
+
}
|
|
3225
|
+
items.push({ id: slugify(a.name), title: a.name, quadrant: q });
|
|
3226
|
+
}
|
|
3227
|
+
if (\u8AAD\u3081\u306A\u3044.length > 0) {
|
|
3228
|
+
const m = `type: quadrant \u3067\u533A\u753B\u3092\u8AAD\u3081\u306A\u3044\u9805\u76EE\u304C\u3042\u308A\u307E\u3059 (\u56F3\u306B\u8F09\u305B\u307E\u305B\u3093): ${\u8AAD\u3081\u306A\u3044.join(", ")}\u3002 \`- \u91CD\u8907\u524A\u9664: "\u5DE6\u4E0A"\` \u306E\u5F62\u3067\u3001 ${[...\u533A\u753B.keys()].join(" / ")} \u306E\u3069\u308C\u304B\u3092\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`;
|
|
3229
|
+
onNotice?.({ kind: "chart-value-unreadable", actor: \u8AAD\u3081\u306A\u3044[0], line: 0, message: m });
|
|
3230
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m}`);
|
|
3231
|
+
}
|
|
3232
|
+
if (doc.flow.length > 0) {
|
|
3233
|
+
const m2 = `type: quadrant \u3067\u306F\u77E2\u5370\u3092\u63CF\u3051\u307E\u305B\u3093 (${doc.flow.length} \u672C\u3092\u7121\u8996\u3057\u307E\u3057\u305F)\u3002 \u95A2\u4FC2\u3092\u63CF\u304F\u306A\u3089 type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`;
|
|
3234
|
+
onNotice?.({ kind: "chart-edge-dropped", actor: doc.flow[0]?.from ?? "", line: doc.flow[0]?.pos?.line ?? 0, message: m2 });
|
|
3235
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${m2}`);
|
|
3236
|
+
}
|
|
3237
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3238
|
+
lane: "chart",
|
|
3239
|
+
stack: 0,
|
|
3240
|
+
kind: "quadrant-matrix",
|
|
3241
|
+
title: doc.title,
|
|
3242
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3243
|
+
w: W,
|
|
3244
|
+
h: H,
|
|
3245
|
+
quadrantData: { ...\u8EF8\u3068\u533A\u753B\u306E\u540D\u524D(doc), items }
|
|
3246
|
+
});
|
|
3247
|
+
return b.build();
|
|
3248
|
+
}
|
|
2026
3249
|
function \u6BB5\u3092\u8AAD\u307F\u53D6\u308B(subtitle) {
|
|
2027
3250
|
const \u5143 = (subtitle ?? "").trim();
|
|
2028
3251
|
const m = \u5143.match(/^L([123])(?![0-9A-Za-z])/i);
|
|
@@ -2074,74 +3297,196 @@ function compileC4(doc) {
|
|
|
2074
3297
|
}
|
|
2075
3298
|
return b.build();
|
|
2076
3299
|
}
|
|
2077
|
-
|
|
3300
|
+
var \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u306E\u540D\u524D = {
|
|
3301
|
+
kind: "\u7A2E\u985E",
|
|
3302
|
+
eyebrow: "\u4E0A\u306E\u5C0F\u898B\u51FA\u3057",
|
|
3303
|
+
touchpoint: "\u5834\u6240 (\u4F53\u9A13\u306E\u9053\u7B4B\u306E\u6B04)",
|
|
3304
|
+
opportunity: "\u6539\u5584\u306E\u4F59\u5730 (\u4F53\u9A13\u306E\u9053\u7B4B\u306E\u6B04)",
|
|
3305
|
+
owner: "\u62C5\u5F53 (\u5DE5\u7A0B\u306E\u4E26\u3073\u306E\u6B04)",
|
|
3306
|
+
end: "\u7D42\u308F\u308B\u6642\u671F (\u5DE5\u7A0B\u306E\u4E26\u3073\u306E\u6B04)",
|
|
3307
|
+
rows: "\u884C",
|
|
3308
|
+
lane: "\u67A0\u306E\u6307\u5B9A",
|
|
3309
|
+
stack: "\u7A4D\u3080\u9806",
|
|
3310
|
+
initial: "\u59CB\u307E\u308A / \u7D42\u308F\u308A \u306E\u5370",
|
|
3311
|
+
final: "\u59CB\u307E\u308A / \u7D42\u308F\u308A \u306E\u5370",
|
|
3312
|
+
colorHex: "\u8272\u756A\u53F7",
|
|
3313
|
+
stateOverride: "\u72B6\u614B\u306E\u4E0A\u66F8\u304D",
|
|
3314
|
+
// 位置は「登場人物ごとの箱をどこに置くか」 の指定で、 箱が 1 つの図では置く先が無い
|
|
3315
|
+
posX: "\u4F4D\u7F6E (\u5EA7\u6A19)",
|
|
3316
|
+
posY: "\u4F4D\u7F6E (\u5EA7\u6A19)",
|
|
3317
|
+
posW: "\u5927\u304D\u3055",
|
|
3318
|
+
posH: "\u5927\u304D\u3055",
|
|
3319
|
+
scale: "\u500D\u7387",
|
|
3320
|
+
scaleKeys: "\u500D\u7387",
|
|
3321
|
+
posRel: "\u4F4D\u7F6E (\u76F8\u5BFE)",
|
|
3322
|
+
nodes: "\u4E2D\u306E\u7BB1\u3054\u3068\u306E\u6307\u5B9A",
|
|
3323
|
+
layoutPos: "\u914D\u7F6E\u306E\u305A\u3089\u3057"
|
|
3324
|
+
};
|
|
3325
|
+
function \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u3092\u66F8\u3044\u305F\u304B(a, \u6B04) {
|
|
3326
|
+
if (\u6B04 === "kind") return a.kindWritten === true;
|
|
3327
|
+
const v = a[\u6B04];
|
|
3328
|
+
if (typeof v === "boolean") return v;
|
|
3329
|
+
return v !== void 0;
|
|
3330
|
+
}
|
|
3331
|
+
function \u653E\u5C04\u306B\u51FA\u3059\u6587\u5B57(a) {
|
|
3332
|
+
const \u7D9A\u304D = [a.subtitle, a.value].map((x) => x?.trim()).filter((x) => !!x);
|
|
3333
|
+
return \u7D9A\u304D.length > 0 ? `${a.name} ${\u7D9A\u304D.join(" ")}` : a.name;
|
|
3334
|
+
}
|
|
3335
|
+
function compileMind(doc, onNotice) {
|
|
2078
3336
|
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
2079
|
-
const
|
|
2080
|
-
const
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
const \
|
|
2085
|
-
const
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
3337
|
+
const { w: W, h: H } = \u56F3\u8868\u306E\u5927\u304D\u3055.mind;
|
|
3338
|
+
const \u4F1D\u3048\u308B = (kind, \u540D, message, line = 0) => {
|
|
3339
|
+
onNotice?.({ kind, actor: \u540D, line, message });
|
|
3340
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
3341
|
+
};
|
|
3342
|
+
const \u898B\u672C\u3067\u306A\u3044 = [];
|
|
3343
|
+
for (const a of doc.actors) {
|
|
3344
|
+
if (a.partId !== void 0) {
|
|
3345
|
+
\u4F1D\u3048\u308B(
|
|
3346
|
+
"part-not-drawn",
|
|
3347
|
+
a.name,
|
|
3348
|
+
`type: mind \u3067\u306F\u898B\u672C (${a.partId}) \u3092\u4E2D\u5FC3\u306B\u3082\u679D\u306B\u3082\u3067\u304D\u307E\u305B\u3093\u3002 \u898B\u672C\u306F\u305D\u306E\u307E\u307E\u63CF\u304D\u3001 \u653E\u5C04\u306B\u306F\u8F09\u305B\u307E\u305B\u3093`,
|
|
3349
|
+
a.pos?.line ?? 0
|
|
3350
|
+
);
|
|
3351
|
+
continue;
|
|
3352
|
+
}
|
|
3353
|
+
\u898B\u672C\u3067\u306A\u3044.push(a);
|
|
3354
|
+
}
|
|
3355
|
+
const \u679D\u306E\u540D\u524D = new Set(\u898B\u672C\u3067\u306A\u3044.map((a) => slugify(a.name)));
|
|
3356
|
+
const \u89AA = \u77E2\u5370\u304B\u3089\u89AA\u3092\u6C7A\u3081\u308B(
|
|
3357
|
+
doc,
|
|
3358
|
+
"mind",
|
|
3359
|
+
\u679D\u306E\u540D\u524D,
|
|
3360
|
+
(\u540D, message, line) => (
|
|
3361
|
+
// 親にできなかった矢印は描かれない。 知らせの種別も「矢印を落とした」 にする
|
|
3362
|
+
\u4F1D\u3048\u308B("chart-edge-dropped", \u540D, message, line ?? 0)
|
|
3363
|
+
)
|
|
3364
|
+
);
|
|
3365
|
+
if (\u898B\u672C\u3067\u306A\u3044.length === 0) return b.build();
|
|
3366
|
+
b.lane("chart", { width: W + 64 });
|
|
3367
|
+
const slug\u5225 = /* @__PURE__ */ new Map();
|
|
3368
|
+
for (const a of \u898B\u672C\u3067\u306A\u3044) {
|
|
3369
|
+
const k = slugify(a.name);
|
|
3370
|
+
slug\u5225.set(k, [...slug\u5225.get(k) ?? [], a.name]);
|
|
3371
|
+
}
|
|
3372
|
+
for (const [k, \u7FA4] of slug\u5225) {
|
|
3373
|
+
if (\u7FA4.length > 1) {
|
|
3374
|
+
\u4F1D\u3048\u308B(
|
|
3375
|
+
"chart-value-unreadable",
|
|
3376
|
+
\u7FA4[0],
|
|
3377
|
+
`type: mind \u3067 ${\u7FA4.join(" / ")} \u304C\u540C\u3058 id (${k}) \u306B\u306A\u308A\u307E\u3059\u3002 \u540D\u524D\u3092\u5909\u3048\u3066\u304F\u3060\u3055\u3044`
|
|
3378
|
+
);
|
|
3379
|
+
}
|
|
2097
3380
|
}
|
|
2098
|
-
const root =
|
|
3381
|
+
const root = \u898B\u672C\u3067\u306A\u3044[0];
|
|
2099
3382
|
const rootId = slugify(root.name);
|
|
2100
|
-
const
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
}
|
|
2109
|
-
const
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
3383
|
+
for (const f of doc.flow) {
|
|
3384
|
+
if (slugify(f.to) !== rootId) continue;
|
|
3385
|
+
\u4F1D\u3048\u308B(
|
|
3386
|
+
"chart-edge-dropped",
|
|
3387
|
+
f.to,
|
|
3388
|
+
`type: mind \u3067\u4E2D\u5FC3 (${truncateForMessage(f.to)}) \u3092\u5B50\u306B\u306F\u3067\u304D\u307E\u305B\u3093 (${truncateForMessage(f.from)} -> ${truncateForMessage(f.to)} \u3092\u4F7F\u3044\u307E\u305B\u3093)\u3002 \u4E2D\u5FC3\u306F\u653E\u5C04\u306E\u771F\u3093\u4E2D\u306B\u7F6E\u304F 1 \u3064\u3060\u3051\u3067\u3059`,
|
|
3389
|
+
f.pos?.line ?? 0
|
|
3390
|
+
);
|
|
3391
|
+
}
|
|
3392
|
+
const \u63CF\u3051\u306A\u3044\u6B04 = (a) => {
|
|
3393
|
+
const out = [];
|
|
3394
|
+
for (const \u6B04 of Object.keys(\u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u306E\u540D\u524D)) {
|
|
3395
|
+
if (!\u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u3092\u66F8\u3044\u305F\u304B(a, \u6B04)) continue;
|
|
3396
|
+
const \u540D\u524D = \u653E\u5C04\u3067\u63CF\u3051\u306A\u3044\u6B04\u306E\u540D\u524D[\u6B04];
|
|
3397
|
+
if (!out.includes(\u540D\u524D)) out.push(\u540D\u524D);
|
|
3398
|
+
}
|
|
3399
|
+
return out;
|
|
3400
|
+
};
|
|
3401
|
+
const \u6D88\u3048\u305F\u6B04 = /* @__PURE__ */ new Map();
|
|
3402
|
+
const \u8A18\u9332\u3059\u308B = (a) => {
|
|
3403
|
+
const \u6B04 = \u63CF\u3051\u306A\u3044\u6B04(a);
|
|
3404
|
+
if (\u6B04.length > 0) \u6D88\u3048\u305F\u6B04.set(a.name, \u6B04);
|
|
3405
|
+
};
|
|
3406
|
+
const branches = [];
|
|
3407
|
+
const \u4F7F\u3063\u305F = /* @__PURE__ */ new Set([rootId]);
|
|
3408
|
+
\u8A18\u9332\u3059\u308B(root);
|
|
3409
|
+
if (root.tone) \u6D88\u3048\u305F\u6B04.set(root.name, [...\u6D88\u3048\u305F\u6B04.get(root.name) ?? [], "\u8272 (\u4E2D\u5FC3\u306F\u6301\u3066\u306A\u3044)"]);
|
|
3410
|
+
\u898B\u672C\u3067\u306A\u3044.slice(1).forEach((a, i) => {
|
|
3411
|
+
const id = slugify(a.name);
|
|
3412
|
+
if (\u4F7F\u3063\u305F.has(id)) {
|
|
3413
|
+
\u4F1D\u3048\u308B(
|
|
3414
|
+
"chart-value-unreadable",
|
|
3415
|
+
a.name,
|
|
3416
|
+
`type: mind \u3067 ${a.name} \u304C\u65E2\u306B\u3042\u308B id (${id}) \u3068\u91CD\u306A\u308A\u307E\u3059 (\u679D\u306B\u8F09\u305B\u307E\u305B\u3093)`,
|
|
3417
|
+
a.pos?.line ?? 0
|
|
3418
|
+
);
|
|
3419
|
+
return;
|
|
3420
|
+
}
|
|
3421
|
+
\u4F7F\u3063\u305F.add(id);
|
|
3422
|
+
\u8A18\u9332\u3059\u308B(a);
|
|
3423
|
+
branches.push({
|
|
3424
|
+
id,
|
|
3425
|
+
title: \u653E\u5C04\u306B\u51FA\u3059\u6587\u5B57(a),
|
|
3426
|
+
parent: \u89AA.get(id) ?? rootId,
|
|
3427
|
+
...a.tone ? { tone: a.tone } : {}
|
|
2122
3428
|
});
|
|
2123
|
-
counter.v += 1;
|
|
2124
3429
|
});
|
|
2125
|
-
if (
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
const fromId = slugify(s.from);
|
|
2133
|
-
const toId = slugify(s.to);
|
|
2134
|
-
b.edge(fromId, toId, {
|
|
2135
|
-
label: s.label,
|
|
2136
|
-
...s.sub ? { sub: s.sub } : {},
|
|
2137
|
-
...s.tone ? { tone: s.tone } : {},
|
|
2138
|
-
...s.style ? { style: s.style } : {}
|
|
2139
|
-
});
|
|
2140
|
-
}
|
|
3430
|
+
if (\u6D88\u3048\u305F\u6B04.size > 0) {
|
|
3431
|
+
const \u4E00\u89A7 = [...\u6D88\u3048\u305F\u6B04].map(([\u540D, \u6B04]) => `${\u540D} \u306E${\u6B04.join(" / ")}`).join("\u3001 ");
|
|
3432
|
+
\u4F1D\u3048\u308B(
|
|
3433
|
+
"chart-value-unreadable",
|
|
3434
|
+
[...\u6D88\u3048\u305F\u6B04.keys()][0],
|
|
3435
|
+
`type: mind \u306F\u540D\u524D\u3068\u526F\u984C / \u5024\u3001 \u679D\u306E\u8272\u3057\u304B\u63CF\u3051\u307E\u305B\u3093 (\u63CF\u304B\u306A\u3044\u6B04: ${\u4E00\u89A7})\u3002 \u3053\u308C\u3089\u3092\u63CF\u304F\u306A\u3089 type: tree \u304B type: flow \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044`
|
|
3436
|
+
);
|
|
2141
3437
|
}
|
|
3438
|
+
b.node(`${slugify(doc.title)}-chart`, {
|
|
3439
|
+
lane: "chart",
|
|
3440
|
+
stack: 0,
|
|
3441
|
+
kind: "mind-map",
|
|
3442
|
+
title: doc.title,
|
|
3443
|
+
...\u56F3\u306E\u5C0F\u898B\u51FA\u3057(doc),
|
|
3444
|
+
w: W,
|
|
3445
|
+
h: H,
|
|
3446
|
+
mindData: { rootId, rootTitle: \u653E\u5C04\u306B\u51FA\u3059\u6587\u5B57(root), branches }
|
|
3447
|
+
});
|
|
2142
3448
|
return b.build();
|
|
2143
3449
|
}
|
|
2144
|
-
function
|
|
3450
|
+
function mergeDuplicateDeclaredLanes(diagram2, \u8FFD\u52A0\u3057\u305F\u7E26\u5217) {
|
|
3451
|
+
for (const \u5BA3\u8A00 of \u8FFD\u52A0\u3057\u305F\u7E26\u5217) {
|
|
3452
|
+
const { id } = \u5BA3\u8A00;
|
|
3453
|
+
const \u540C\u4E00id\u306E\u7E26\u5217 = diagram2.lanes.filter((l) => l.id === id);
|
|
3454
|
+
if (\u540C\u4E00id\u306E\u7E26\u5217.length < 2) continue;
|
|
3455
|
+
const \u6B8B\u3059 = \u540C\u4E00id\u306E\u7E26\u5217.at(-1);
|
|
3456
|
+
if (\u6B8B\u3059 === void 0) continue;
|
|
3457
|
+
const \u5143\u306E\u4E2D\u5FC3X = (\u6B8B\u3059.x ?? 0) + \u6B8B\u3059.width / 2;
|
|
3458
|
+
if (\u5BA3\u8A00.x !== void 0) \u6B8B\u3059.x = \u5BA3\u8A00.x;
|
|
3459
|
+
if (\u5BA3\u8A00.width !== void 0) \u6B8B\u3059.width = \u5BA3\u8A00.width;
|
|
3460
|
+
if (\u5BA3\u8A00.label !== void 0) \u6B8B\u3059.label = \u5BA3\u8A00.label;
|
|
3461
|
+
if (\u5BA3\u8A00.contain !== void 0) \u6B8B\u3059.contain = \u5BA3\u8A00.contain;
|
|
3462
|
+
if (\u5BA3\u8A00.lifeline !== void 0) \u6B8B\u3059.lifeline = \u5BA3\u8A00.lifeline;
|
|
3463
|
+
const \u79FB\u52D5X = (\u6B8B\u3059.x ?? 0) + \u6B8B\u3059.width / 2 - \u5143\u306E\u4E2D\u5FC3X;
|
|
3464
|
+
for (const node of diagram2.nodes) {
|
|
3465
|
+
if (node.lane === id && node.posX !== void 0) node.posX += \u79FB\u52D5X;
|
|
3466
|
+
}
|
|
3467
|
+
for (let i = diagram2.lanes.length - 1; i >= 0; i -= 1) {
|
|
3468
|
+
if (diagram2.lanes[i]?.id === id && diagram2.lanes[i] !== \u6B8B\u3059) diagram2.lanes.splice(i, 1);
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
function reportEmptyDeclaredLanes(diagram2, \u8FFD\u52A0\u3057\u305F\u7E26\u5217, onNotice) {
|
|
3473
|
+
if (\u8FFD\u52A0\u3057\u305F\u7E26\u5217.length === 0) return;
|
|
3474
|
+
mergeDuplicateDeclaredLanes(diagram2, \u8FFD\u52A0\u3057\u305F\u7E26\u5217);
|
|
3475
|
+
if (!onNotice) return;
|
|
3476
|
+
const \u4F7F\u308F\u308C\u3066\u3044\u308B = new Set(diagram2.nodes.map((n) => n.lane));
|
|
3477
|
+
const \u3042\u308B\u7E26\u5217 = diagram2.lanes.map((l) => l.id).filter((x) => \u4F7F\u308F\u308C\u3066\u3044\u308B.has(x));
|
|
3478
|
+
for (const { id, pos } of \u8FFD\u52A0\u3057\u305F\u7E26\u5217) {
|
|
3479
|
+
if (\u4F7F\u308F\u308C\u3066\u3044\u308B.has(id)) continue;
|
|
3480
|
+
onNotice({
|
|
3481
|
+
kind: "lane-declared-empty",
|
|
3482
|
+
actor: id,
|
|
3483
|
+
line: pos?.line ?? 0,
|
|
3484
|
+
message: `lanes \u306B\u66F8\u3044\u305F ${truncateForMessage(id)} \u306F\u3069\u306E\u7BB1\u3082\u5165\u3089\u306A\u3044\u7E26\u5217\u3067\u3059 (\u65B0\u3057\u304F\u4F5C\u308A\u307E\u3057\u305F)`,
|
|
3485
|
+
hint: \u3042\u308B\u7E26\u5217.length > 0 ? `\u3053\u306E\u56F3\u304C\u6301\u3064\u7E26\u5217 = ${\u3042\u308B\u7E26\u5217.join(" / ")}` : "\u3053\u306E\u56F3\u306F\u7BB1\u306E\u5165\u3063\u305F\u7E26\u5217\u3092\u6301\u3061\u307E\u305B\u3093"
|
|
3486
|
+
});
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
function applyV05Extensions(diagram2, doc, \u8FFD\u52A0\u3057\u305F\u7E26\u5217out) {
|
|
2145
3490
|
const isSeqLike = doc.type === "sequence" || doc.type === "solidity";
|
|
2146
3491
|
for (const a of doc.actors) {
|
|
2147
3492
|
const dragonSlug = slugify(a.name);
|
|
@@ -2160,6 +3505,10 @@ function applyV05Extensions(diagram2, doc) {
|
|
|
2160
3505
|
if (a.eyebrow !== void 0) node.eyebrow = a.eyebrow;
|
|
2161
3506
|
if (a.value !== void 0) node.value = a.value;
|
|
2162
3507
|
if (a.rows !== void 0) node.rows = a.rows;
|
|
3508
|
+
if (!isSeqLike) {
|
|
3509
|
+
if (a.posW !== void 0) node.w = a.posW;
|
|
3510
|
+
if (a.posH !== void 0) node.h = a.posH;
|
|
3511
|
+
}
|
|
2163
3512
|
const drawn = isSeqLike && a.kindWritten !== false ? drawableKind(a.kind) : void 0;
|
|
2164
3513
|
if (drawn !== void 0) {
|
|
2165
3514
|
node.kind = drawn;
|
|
@@ -2183,6 +3532,7 @@ function applyV05Extensions(diagram2, doc) {
|
|
|
2183
3532
|
if (doc.animate && doc.animate.phases.length > 0 && diagram2.phases.length === 0) {
|
|
2184
3533
|
injectPhasesFallback(diagram2, doc);
|
|
2185
3534
|
}
|
|
3535
|
+
const \u8FFD\u52A0\u3057\u305F\u7E26\u5217 = \u8FFD\u52A0\u3057\u305F\u7E26\u5217out ?? [];
|
|
2186
3536
|
if (doc.lanes) {
|
|
2187
3537
|
for (const [id, laneOpt] of Object.entries(doc.lanes)) {
|
|
2188
3538
|
const lane = diagram2.lanes.find((l) => l.id === id);
|
|
@@ -2201,6 +3551,7 @@ function applyV05Extensions(diagram2, doc) {
|
|
|
2201
3551
|
contain: laneOpt.contain,
|
|
2202
3552
|
lifeline: laneOpt.lifeline
|
|
2203
3553
|
});
|
|
3554
|
+
\u8FFD\u52A0\u3057\u305F\u7E26\u5217.push(laneOpt);
|
|
2204
3555
|
}
|
|
2205
3556
|
}
|
|
2206
3557
|
}
|
|
@@ -2321,8 +3672,9 @@ function compileSequenceWithAnimate(doc) {
|
|
|
2321
3672
|
b.node(spacerId, { lane: id, stack: 1, kind: "card", title: "", w: 2, h: 40 });
|
|
2322
3673
|
});
|
|
2323
3674
|
doc.flow.forEach((s, idx) => {
|
|
2324
|
-
const fromLaneId = actorIds.get(s.from)
|
|
2325
|
-
const toLaneId = actorIds.get(s.to)
|
|
3675
|
+
const fromLaneId = actorIds.get(s.from);
|
|
3676
|
+
const toLaneId = actorIds.get(s.to);
|
|
3677
|
+
if (fromLaneId === void 0 || toLaneId === void 0) return;
|
|
2326
3678
|
const stack = idx + 2;
|
|
2327
3679
|
const fromBoxId = `s${idx}-${fromLaneId}`;
|
|
2328
3680
|
const toBoxId = `s${idx}-${toLaneId}`;
|
|
@@ -2336,11 +3688,7 @@ function compileSequenceWithAnimate(doc) {
|
|
|
2336
3688
|
label: s.label,
|
|
2337
3689
|
...s.sub ? { sub: s.sub } : {},
|
|
2338
3690
|
...s.tone ? { tone: s.tone } : {},
|
|
2339
|
-
...s.style ? { style: s.style } : {}
|
|
2340
|
-
...s.guard ? { guard: s.guard } : {},
|
|
2341
|
-
...s.cardinality ? { cardinality: s.cardinality } : {},
|
|
2342
|
-
...s.labelOffsetX !== void 0 ? { labelOffsetX: s.labelOffsetX } : {},
|
|
2343
|
-
...s.labelOffsetY !== void 0 ? { labelOffsetY: s.labelOffsetY } : {}
|
|
3691
|
+
...s.style ? { style: s.style } : {}
|
|
2344
3692
|
});
|
|
2345
3693
|
});
|
|
2346
3694
|
const footerStack = doc.flow.length + 2;
|
|
@@ -2348,12 +3696,20 @@ function compileSequenceWithAnimate(doc) {
|
|
|
2348
3696
|
const laneId = actorIds.get(a.name) ?? slugify(a.name);
|
|
2349
3697
|
const footerId = `${laneId}-footer`;
|
|
2350
3698
|
const actorW = Math.max(140, a.name.length * 22 + 52);
|
|
2351
|
-
b.node(footerId, {
|
|
3699
|
+
b.node(footerId, {
|
|
3700
|
+
lane: laneId,
|
|
3701
|
+
stack: footerStack,
|
|
3702
|
+
kind: "card",
|
|
3703
|
+
title: a.name,
|
|
3704
|
+
w: actorW,
|
|
3705
|
+
h: 72,
|
|
3706
|
+
role: "lifeline-footer"
|
|
3707
|
+
});
|
|
2352
3708
|
});
|
|
2353
|
-
for (const st of doc.animate
|
|
3709
|
+
for (const st of doc.animate?.states ?? []) {
|
|
2354
3710
|
b.state(st.name, { initial: st.initial });
|
|
2355
3711
|
}
|
|
2356
|
-
for (const p of doc.animate
|
|
3712
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2357
3713
|
b.phase(
|
|
2358
3714
|
slugify(p.name),
|
|
2359
3715
|
{
|
|
@@ -2432,7 +3788,7 @@ function slugLookup(byName, wanted) {
|
|
|
2432
3788
|
return hit;
|
|
2433
3789
|
}
|
|
2434
3790
|
function compileFlow(doc) {
|
|
2435
|
-
if (doc.animate && doc.animate.phases.length > 0) {
|
|
3791
|
+
if (doc.animate && doc.animate.phases.length > 0 || \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("flow", doc)) {
|
|
2436
3792
|
return compileGenericWithAnimate(doc, { kind: "flow", laneId: "main", laneWidth: 400 });
|
|
2437
3793
|
}
|
|
2438
3794
|
if (doc.actors.length === 0) {
|
|
@@ -2458,7 +3814,7 @@ function compileFlow(doc) {
|
|
|
2458
3814
|
return flowBuilder.build();
|
|
2459
3815
|
}
|
|
2460
3816
|
function compileSwimlane(doc) {
|
|
2461
|
-
if (doc.animate && doc.animate.phases.length > 0) {
|
|
3817
|
+
if (doc.animate && doc.animate.phases.length > 0 || \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("swimlane", doc)) {
|
|
2462
3818
|
return compileGenericWithAnimate(doc, { kind: "swimlane", laneWidth: 400 });
|
|
2463
3819
|
}
|
|
2464
3820
|
const swim = swimlane({
|
|
@@ -2492,11 +3848,17 @@ function compileSwimlane(doc) {
|
|
|
2492
3848
|
label: s.label,
|
|
2493
3849
|
...s.sub ? { sub: s.sub } : {},
|
|
2494
3850
|
...s.tone ? { tone: s.tone } : {},
|
|
2495
|
-
...s.style ? { style: s.style } : {}
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
3851
|
+
...s.style ? { style: s.style } : {}
|
|
3852
|
+
});
|
|
3853
|
+
}
|
|
3854
|
+
if (placedNodes.size === 0) {
|
|
3855
|
+
doc.actors.forEach((a, i) => {
|
|
3856
|
+
swim.node(slugify(a.name), {
|
|
3857
|
+
lane: swim.laneId(a.name),
|
|
3858
|
+
stack: 0,
|
|
3859
|
+
kind: a.kind ?? "actor",
|
|
3860
|
+
title: a.name
|
|
3861
|
+
});
|
|
2500
3862
|
});
|
|
2501
3863
|
}
|
|
2502
3864
|
return swim.build();
|
|
@@ -2528,6 +3890,14 @@ function compileEr(doc) {
|
|
|
2528
3890
|
}
|
|
2529
3891
|
return erBuilder.build();
|
|
2530
3892
|
}
|
|
3893
|
+
function \u59CB\u307E\u308A\u3068\u7D42\u308F\u308A\u306E\u6C7A\u3081\u65B9(doc) {
|
|
3894
|
+
const \u66F8\u3044\u305F\u59CB\u307E\u308A = doc.actors.some((a) => a.initial === true);
|
|
3895
|
+
const \u66F8\u3044\u305F\u7D42\u308F\u308A = doc.actors.some((a) => a.final === true);
|
|
3896
|
+
return {
|
|
3897
|
+
\u59CB\u307E\u308A: (a, idx) => \u66F8\u3044\u305F\u59CB\u307E\u308A ? a.initial === true : idx === 0,
|
|
3898
|
+
\u7D42\u308F\u308A: (a, idx) => \u66F8\u3044\u305F\u7D42\u308F\u308A ? a.final === true : idx === doc.actors.length - 1 && doc.actors.length > 1
|
|
3899
|
+
};
|
|
3900
|
+
}
|
|
2531
3901
|
function compileState(doc) {
|
|
2532
3902
|
if (doc.animate && doc.animate.phases.length > 0) {
|
|
2533
3903
|
return compileGenericWithAnimate(doc, { kind: "state", laneWidth: 360 });
|
|
@@ -2536,10 +3906,11 @@ function compileState(doc) {
|
|
|
2536
3906
|
id: slugify(doc.title),
|
|
2537
3907
|
topic: doc.title
|
|
2538
3908
|
});
|
|
3909
|
+
const \u6C7A\u3081\u65B9 = \u59CB\u307E\u308A\u3068\u7D42\u308F\u308A\u306E\u6C7A\u3081\u65B9(doc);
|
|
2539
3910
|
for (let i = 0; i < doc.actors.length; i++) {
|
|
2540
3911
|
const a = doc.actors[i];
|
|
2541
|
-
const initial = i
|
|
2542
|
-
const final = i
|
|
3912
|
+
const initial = \u6C7A\u3081\u65B9.\u59CB\u307E\u308A(a, i);
|
|
3913
|
+
const final = \u6C7A\u3081\u65B9.\u7D42\u308F\u308A(a, i);
|
|
2543
3914
|
fsm.state({
|
|
2544
3915
|
id: slugify(a.name),
|
|
2545
3916
|
title: a.name,
|
|
@@ -2559,7 +3930,7 @@ function compileState(doc) {
|
|
|
2559
3930
|
return fsm.build();
|
|
2560
3931
|
}
|
|
2561
3932
|
function compileTopology(doc) {
|
|
2562
|
-
if (doc.animate && doc.animate.phases.length > 0) {
|
|
3933
|
+
if (doc.animate && doc.animate.phases.length > 0 || \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F("topology", doc)) {
|
|
2563
3934
|
return compileGenericWithAnimate(doc, { kind: "topology", laneWidth: 460 });
|
|
2564
3935
|
}
|
|
2565
3936
|
if (doc.actors.length === 0) {
|
|
@@ -2588,11 +3959,42 @@ function compileTopology(doc) {
|
|
|
2588
3959
|
}
|
|
2589
3960
|
return topo.build();
|
|
2590
3961
|
}
|
|
3962
|
+
function \u5F8C\u308D\u3078\u623B\u308B\u77E2\u5370\u304B(kind, fromId, toId, \u7BB1\u306E\u4E26\u3073) {
|
|
3963
|
+
if (kind !== "state") return false;
|
|
3964
|
+
const \u5143 = \u7BB1\u306E\u4E26\u3073.get(fromId);
|
|
3965
|
+
const \u5148 = \u7BB1\u306E\u4E26\u3073.get(toId);
|
|
3966
|
+
if (\u5143 === void 0 || \u5148 === void 0) return false;
|
|
3967
|
+
return \u5148 < \u5143;
|
|
3968
|
+
}
|
|
3969
|
+
var \u7E26\u5217\u3092\u9078\u3079\u308B\u56F3\u7A2E = /* @__PURE__ */ new Set(["flow", "topology", "swimlane"]);
|
|
3970
|
+
function \u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F(kind, doc) {
|
|
3971
|
+
if (!\u7E26\u5217\u3092\u9078\u3079\u308B\u56F3\u7A2E.has(kind)) return false;
|
|
3972
|
+
const \u5BFE\u8C61 = doc.actors.filter((a) => a.partId === void 0);
|
|
3973
|
+
return \u5BFE\u8C61.length > 0 && \u5BFE\u8C61.every((a) => a.lane !== void 0);
|
|
3974
|
+
}
|
|
2591
3975
|
function compileGenericWithAnimate(doc, opts) {
|
|
2592
3976
|
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
2593
3977
|
const { kind, laneWidth } = opts;
|
|
2594
3978
|
const actorToNodeId = /* @__PURE__ */ new Map();
|
|
2595
|
-
if (kind
|
|
3979
|
+
if (\u66F8\u3044\u305F\u7E26\u5217\u306B\u7F6E\u304F(kind, doc)) {
|
|
3980
|
+
const \u4E26\u3073 = [];
|
|
3981
|
+
for (const a of doc.actors) {
|
|
3982
|
+
const lid = a.lane;
|
|
3983
|
+
if (lid !== void 0 && !\u4E26\u3073.includes(lid)) \u4E26\u3073.push(lid);
|
|
3984
|
+
}
|
|
3985
|
+
for (const lid of \u4E26\u3073) {
|
|
3986
|
+
b.lane(lid, { width: laneWidth, ...kind === "topology" ? { contain: true } : {} });
|
|
3987
|
+
}
|
|
3988
|
+
const \u7A4D\u3093\u3060\u6570 = /* @__PURE__ */ new Map();
|
|
3989
|
+
doc.actors.forEach((a, idx) => {
|
|
3990
|
+
const id = slugify(a.name);
|
|
3991
|
+
actorToNodeId.set(a.name, id);
|
|
3992
|
+
const lid = a.lane;
|
|
3993
|
+
const stack = \u7A4D\u3093\u3060\u6570.get(lid) ?? 0;
|
|
3994
|
+
\u7A4D\u3093\u3060\u6570.set(lid, stack + 1);
|
|
3995
|
+
b.node(id, { lane: lid, stack, kind: a.kind, title: a.name });
|
|
3996
|
+
});
|
|
3997
|
+
} else if (kind === "flow" || kind === "topology") {
|
|
2596
3998
|
const lid = opts.laneId ?? "main";
|
|
2597
3999
|
b.lane(lid, { width: laneWidth, label: doc.title, ...kind === "topology" ? { contain: true } : {} });
|
|
2598
4000
|
doc.actors.forEach((a, idx) => {
|
|
@@ -2601,13 +4003,15 @@ function compileGenericWithAnimate(doc, opts) {
|
|
|
2601
4003
|
b.node(id, { lane: lid, stack: idx, kind: a.kind, title: a.name });
|
|
2602
4004
|
});
|
|
2603
4005
|
} else {
|
|
4006
|
+
const \u898B\u51FA\u3057\u3092\u4ED8\u3051\u308B = kind === "swimlane";
|
|
4007
|
+
const \u6C7A\u3081\u65B92 = \u59CB\u307E\u308A\u3068\u7D42\u308F\u308A\u306E\u6C7A\u3081\u65B9(doc);
|
|
2604
4008
|
doc.actors.forEach((a, idx) => {
|
|
2605
4009
|
const lid = `lane-${slugify(a.name)}`;
|
|
2606
|
-
b.lane(lid, { width: laneWidth, label: a.name });
|
|
4010
|
+
b.lane(lid, { width: laneWidth, ...\u898B\u51FA\u3057\u3092\u4ED8\u3051\u308B ? { label: a.name } : {} });
|
|
2607
4011
|
const id = slugify(a.name);
|
|
2608
4012
|
actorToNodeId.set(a.name, id);
|
|
2609
|
-
const isInitial = kind === "state" && idx
|
|
2610
|
-
const isFinal = kind === "state" && idx
|
|
4013
|
+
const isInitial = kind === "state" && \u6C7A\u3081\u65B92.\u59CB\u307E\u308A(a, idx);
|
|
4014
|
+
const isFinal = kind === "state" && \u6C7A\u3081\u65B92.\u7D42\u308F\u308A(a, idx);
|
|
2611
4015
|
b.node(id, {
|
|
2612
4016
|
lane: lid,
|
|
2613
4017
|
stack: 0,
|
|
@@ -2618,29 +4022,28 @@ function compileGenericWithAnimate(doc, opts) {
|
|
|
2618
4022
|
});
|
|
2619
4023
|
});
|
|
2620
4024
|
}
|
|
4025
|
+
const \u7BB1\u306E\u4E26\u3073 = new Map([...actorToNodeId.values()].map((id, i) => [id, i]));
|
|
2621
4026
|
const edgeIds = [];
|
|
2622
4027
|
doc.flow.forEach((s, idx) => {
|
|
2623
|
-
const fromId = actorToNodeId.get(s.from)
|
|
2624
|
-
const toId = actorToNodeId.get(s.to)
|
|
4028
|
+
const fromId = actorToNodeId.get(s.from);
|
|
4029
|
+
const toId = actorToNodeId.get(s.to);
|
|
4030
|
+
if (fromId === void 0 || toId === void 0) return;
|
|
2625
4031
|
const edgeId = `e${idx}-${fromId}-${toId}`;
|
|
2626
4032
|
const labelWithCard = kind === "er" && s.cardinality && !s.label.includes(s.cardinality) ? s.label ? `${s.label} (${s.cardinality})` : `(${s.cardinality})` : s.label;
|
|
2627
4033
|
b.edge(fromId, toId, {
|
|
2628
4034
|
id: edgeId,
|
|
2629
4035
|
label: labelWithCard,
|
|
4036
|
+
...\u5F8C\u308D\u3078\u623B\u308B\u77E2\u5370\u304B(kind, fromId, toId, \u7BB1\u306E\u4E26\u3073) ? { routing: "back-detour" } : {},
|
|
2630
4037
|
...s.sub ? { sub: s.sub } : {},
|
|
2631
4038
|
...s.tone ? { tone: s.tone } : {},
|
|
2632
|
-
...s.style ? { style: s.style } : {}
|
|
2633
|
-
...s.guard ? { guard: s.guard } : {},
|
|
2634
|
-
...s.cardinality ? { cardinality: s.cardinality } : {},
|
|
2635
|
-
...s.labelOffsetX !== void 0 ? { labelOffsetX: s.labelOffsetX } : {},
|
|
2636
|
-
...s.labelOffsetY !== void 0 ? { labelOffsetY: s.labelOffsetY } : {}
|
|
4039
|
+
...s.style ? { style: s.style } : {}
|
|
2637
4040
|
});
|
|
2638
4041
|
edgeIds.push(edgeId);
|
|
2639
4042
|
});
|
|
2640
|
-
for (const st of doc.animate
|
|
4043
|
+
for (const st of doc.animate?.states ?? []) {
|
|
2641
4044
|
b.state(st.name, { initial: st.initial });
|
|
2642
4045
|
}
|
|
2643
|
-
for (const p of doc.animate
|
|
4046
|
+
for (const p of doc.animate?.phases ?? []) {
|
|
2644
4047
|
b.phase(
|
|
2645
4048
|
slugify(p.name),
|
|
2646
4049
|
{
|
|
@@ -2683,51 +4086,284 @@ function resolveHighlightGeneric(phase, doc, actorToNodeId, edgeIds) {
|
|
|
2683
4086
|
}
|
|
2684
4087
|
continue;
|
|
2685
4088
|
}
|
|
2686
|
-
const nodeId = actorToNodeId.get(entry.name) ?? slugLookup(actorToNodeId, entry.name);
|
|
2687
|
-
if (nodeId) {
|
|
2688
|
-
out.push(nodeId);
|
|
4089
|
+
const nodeId = actorToNodeId.get(entry.name) ?? slugLookup(actorToNodeId, entry.name);
|
|
4090
|
+
if (nodeId) {
|
|
4091
|
+
out.push(nodeId);
|
|
4092
|
+
}
|
|
4093
|
+
}
|
|
4094
|
+
return out;
|
|
4095
|
+
}
|
|
4096
|
+
var ID_MAX = 64;
|
|
4097
|
+
function slugify(s) {
|
|
4098
|
+
return s.toLowerCase().normalize("NFKC").replace(/[^a-z0-9ぁ-んァ-ヶ一-龯\-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, ID_MAX) || "n";
|
|
4099
|
+
}
|
|
4100
|
+
var CARDINALITY_PATTERNS = [
|
|
4101
|
+
[/1:1/, "1:1"],
|
|
4102
|
+
[/1:N/i, "1:N"],
|
|
4103
|
+
[/N:1/i, "N:1"],
|
|
4104
|
+
[/N:M/i, "N:M"],
|
|
4105
|
+
[/0\.\.1/, "0..1"],
|
|
4106
|
+
[/1\.\.\*/, "1..*"]
|
|
4107
|
+
];
|
|
4108
|
+
function boundedCardinalityRegExp(pattern, extraFlags = "") {
|
|
4109
|
+
const base = pattern.flags.includes("i") ? "i" : "";
|
|
4110
|
+
return new RegExp(`(?<![A-Za-z0-9_])(?:${pattern.source})(?![A-Za-z0-9_])`, base + extraFlags);
|
|
4111
|
+
}
|
|
4112
|
+
function parseCardinalityFromLabel(label) {
|
|
4113
|
+
for (const [pattern, card] of CARDINALITY_PATTERNS) {
|
|
4114
|
+
if (boundedCardinalityRegExp(pattern).test(label)) return card;
|
|
4115
|
+
}
|
|
4116
|
+
return null;
|
|
4117
|
+
}
|
|
4118
|
+
var HORIZONTAL_WS = " \\t\\u3000";
|
|
4119
|
+
var HWS = `[${HORIZONTAL_WS}]`;
|
|
4120
|
+
function stripCardinality(label) {
|
|
4121
|
+
let r = label;
|
|
4122
|
+
let removed = false;
|
|
4123
|
+
for (const [pattern] of CARDINALITY_PATTERNS) {
|
|
4124
|
+
const src = pattern.source;
|
|
4125
|
+
const flags = pattern.flags.includes("i") ? "gi" : "g";
|
|
4126
|
+
const before = r;
|
|
4127
|
+
r = r.replace(new RegExp(`\\(${HWS}*${src}${HWS}*\\)`, flags), "");
|
|
4128
|
+
r = r.replace(boundedCardinalityRegExp(pattern, "g"), "");
|
|
4129
|
+
if (r !== before) removed = true;
|
|
4130
|
+
}
|
|
4131
|
+
if (!removed) return label;
|
|
4132
|
+
r = r.replace(new RegExp(`${HWS}{2,}`, "g"), " ").replace(new RegExp(`${HWS}*([\\r\\n])${HWS}*`, "g"), "$1").replace(new RegExp(`^${HWS}+|${HWS}+$`, "g"), "");
|
|
4133
|
+
const hasVisible = /[^\p{White_Space}\p{Cf}\p{Cc}\p{Default_Ignorable_Code_Point}]/u.test(r);
|
|
4134
|
+
return hasVisible ? r : label;
|
|
4135
|
+
}
|
|
4136
|
+
|
|
4137
|
+
// src/value-syntax.ts
|
|
4138
|
+
var VALUE_NAME_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
4139
|
+
var VALUE_FNS = /* @__PURE__ */ new Set(["min", "max"]);
|
|
4140
|
+
function isValueName(name) {
|
|
4141
|
+
return VALUE_NAME_RE.test(name);
|
|
4142
|
+
}
|
|
4143
|
+
function valueNameIssue(name) {
|
|
4144
|
+
return {
|
|
4145
|
+
message: `invalid value name: "${name}"`,
|
|
4146
|
+
hint: "\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046 (states \u3068\u540C\u3058\u898F\u5247)"
|
|
4147
|
+
};
|
|
4148
|
+
}
|
|
4149
|
+
var TRIGGER_OPS = [">=", "<=", "==", "!=", ">", "<"];
|
|
4150
|
+
function parseDurationMs(text) {
|
|
4151
|
+
const m = text.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s)?$/);
|
|
4152
|
+
if (!m) return null;
|
|
4153
|
+
const n = parseFloat(m[1] ?? "0");
|
|
4154
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
4155
|
+
const unit = m[2] ?? "s";
|
|
4156
|
+
const durationMs = unit === "ms" ? Math.round(n) : Math.round(n * 1e3);
|
|
4157
|
+
return durationMs > 0 ? durationMs : null;
|
|
4158
|
+
}
|
|
4159
|
+
function splitOutsideQuotes(body) {
|
|
4160
|
+
const out = [];
|
|
4161
|
+
let cur = "";
|
|
4162
|
+
let quote = null;
|
|
4163
|
+
for (const ch of body) {
|
|
4164
|
+
if (quote) {
|
|
4165
|
+
if (ch === quote) quote = null;
|
|
4166
|
+
cur += ch;
|
|
4167
|
+
continue;
|
|
4168
|
+
}
|
|
4169
|
+
if (ch === '"' || ch === "'") {
|
|
4170
|
+
quote = ch;
|
|
4171
|
+
cur += ch;
|
|
4172
|
+
continue;
|
|
4173
|
+
}
|
|
4174
|
+
if (ch === ",") {
|
|
4175
|
+
out.push(cur);
|
|
4176
|
+
cur = "";
|
|
4177
|
+
continue;
|
|
4178
|
+
}
|
|
4179
|
+
cur += ch;
|
|
4180
|
+
}
|
|
4181
|
+
out.push(cur);
|
|
4182
|
+
return out.map((s) => s.trim()).filter((s) => s !== "");
|
|
4183
|
+
}
|
|
4184
|
+
function unquote(s) {
|
|
4185
|
+
const t = s.trim();
|
|
4186
|
+
if (t.length >= 2 && (t[0] === '"' || t[0] === "'") && t[t.length - 1] === t[0]) {
|
|
4187
|
+
return t.slice(1, -1);
|
|
4188
|
+
}
|
|
4189
|
+
return t;
|
|
4190
|
+
}
|
|
4191
|
+
function parseTriggerExpression(raw, name) {
|
|
4192
|
+
const text = raw.trim();
|
|
4193
|
+
const stepMatch = text.match(/^step\s+(.+)$/);
|
|
4194
|
+
if (stepMatch) {
|
|
4195
|
+
const step = unquote(stepMatch[1] ?? "");
|
|
4196
|
+
if (step === "") {
|
|
4197
|
+
return { message: `trigger \u306E\u6BB5\u540D\u304C\u7A7A\u3067\u3059 ("${name}")`, hint: '`trigger: step "\u53D6\u8FBC\u307F"` \u306E\u5F62\u3067\u6BB5\u306E\u540D\u524D\u3092\u66F8\u304F' };
|
|
4198
|
+
}
|
|
4199
|
+
return { kind: "step", step };
|
|
4200
|
+
}
|
|
4201
|
+
for (const op of TRIGGER_OPS) {
|
|
4202
|
+
const at = text.indexOf(op);
|
|
4203
|
+
if (at < 0) continue;
|
|
4204
|
+
const source = text.slice(0, at).trim();
|
|
4205
|
+
const rhs = text.slice(at + op.length).trim();
|
|
4206
|
+
if (!isValueName(source)) {
|
|
4207
|
+
return {
|
|
4208
|
+
message: `trigger \u304C\u898B\u5F35\u308B\u5024\u306E\u540D\u524D\u304C\u4F7F\u3048\u307E\u305B\u3093: "${source}" ("${name}")`,
|
|
4209
|
+
hint: "\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046"
|
|
4210
|
+
};
|
|
4211
|
+
}
|
|
4212
|
+
const threshold = Number(rhs);
|
|
4213
|
+
if (rhs === "" || !Number.isFinite(threshold)) {
|
|
4214
|
+
return {
|
|
4215
|
+
message: `trigger \u306E\u5883\u76EE\u304C\u6570\u3067\u306F\u3042\u308A\u307E\u305B\u3093: "${rhs}" ("${name}")`,
|
|
4216
|
+
hint: "`trigger: vDone >= 100` \u306E\u3088\u3046\u306B\u6570\u3067\u66F8\u304F"
|
|
4217
|
+
};
|
|
4218
|
+
}
|
|
4219
|
+
return { kind: "reaches", source, op, threshold };
|
|
4220
|
+
}
|
|
4221
|
+
return {
|
|
4222
|
+
message: `trigger \u306E\u5F62\u304C\u8AAD\u3081\u307E\u305B\u3093: "${text}" ("${name}")`,
|
|
4223
|
+
hint: '`step "\u53D6\u8FBC\u307F"` \u304B `vDone >= 100` \u306E\u5F62\u3067\u66F8\u304F'
|
|
4224
|
+
};
|
|
4225
|
+
}
|
|
4226
|
+
function isTriggerBody(raw) {
|
|
4227
|
+
const t = raw.trim();
|
|
4228
|
+
if (!t.startsWith("{") || !t.endsWith("}") || t.length < 2) return false;
|
|
4229
|
+
const inner = t.slice(1, -1);
|
|
4230
|
+
let quote = null;
|
|
4231
|
+
for (const ch of inner) {
|
|
4232
|
+
if (quote) {
|
|
4233
|
+
if (ch === quote) quote = null;
|
|
4234
|
+
continue;
|
|
4235
|
+
}
|
|
4236
|
+
if (ch === '"' || ch === "'") {
|
|
4237
|
+
quote = ch;
|
|
4238
|
+
continue;
|
|
2689
4239
|
}
|
|
4240
|
+
if (ch === ":") return true;
|
|
2690
4241
|
}
|
|
2691
|
-
return
|
|
2692
|
-
}
|
|
2693
|
-
function slugify(s) {
|
|
2694
|
-
return s.toLowerCase().normalize("NFKC").replace(/[^a-z0-9ぁ-んァ-ヶ一-龯\-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "n";
|
|
2695
|
-
}
|
|
2696
|
-
var CARDINALITY_PATTERNS = [
|
|
2697
|
-
[/1:1/, "1:1"],
|
|
2698
|
-
[/1:N/i, "1:N"],
|
|
2699
|
-
[/N:1/i, "N:1"],
|
|
2700
|
-
[/N:M/i, "N:M"],
|
|
2701
|
-
[/0\.\.1/, "0..1"],
|
|
2702
|
-
[/1\.\.\*/, "1..*"]
|
|
2703
|
-
];
|
|
2704
|
-
function boundedCardinalityRegExp(pattern, extraFlags = "") {
|
|
2705
|
-
const base = pattern.flags.includes("i") ? "i" : "";
|
|
2706
|
-
return new RegExp(`(?<![A-Za-z0-9_])(?:${pattern.source})(?![A-Za-z0-9_])`, base + extraFlags);
|
|
4242
|
+
return false;
|
|
2707
4243
|
}
|
|
2708
|
-
function
|
|
2709
|
-
|
|
2710
|
-
|
|
4244
|
+
function parseValueTriggerBody(body, name) {
|
|
4245
|
+
const issues = [];
|
|
4246
|
+
const seen = /* @__PURE__ */ new Map();
|
|
4247
|
+
for (const part of splitOutsideQuotes(body)) {
|
|
4248
|
+
const at = part.indexOf(":");
|
|
4249
|
+
if (at < 0) {
|
|
4250
|
+
issues.push({ message: `"${part}" \u306F key: value \u306E\u5F62\u3067\u306F\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: "`trigger: ... , to: 100, dur: 2s` \u306E\u5F62\u3067\u66F8\u304F" });
|
|
4251
|
+
continue;
|
|
4252
|
+
}
|
|
4253
|
+
const key = part.slice(0, at).trim().toLowerCase();
|
|
4254
|
+
const value = part.slice(at + 1).trim();
|
|
4255
|
+
if (seen.has(key)) {
|
|
4256
|
+
issues.push({ message: `"${key}" \u3092 2 \u5EA6\u66F8\u3044\u3066\u3044\u307E\u3059 ("${name}")`, hint: "\u540C\u3058\u9805\u76EE\u306F 1 \u5EA6\u3060\u3051\u66F8\u304F" });
|
|
4257
|
+
continue;
|
|
4258
|
+
}
|
|
4259
|
+
seen.set(key, value);
|
|
2711
4260
|
}
|
|
2712
|
-
|
|
4261
|
+
const known = /* @__PURE__ */ new Set(["trigger", "to", "dur"]);
|
|
4262
|
+
for (const key of seen.keys()) {
|
|
4263
|
+
if (known.has(key)) continue;
|
|
4264
|
+
issues.push({
|
|
4265
|
+
message: `"${key}" \u306F values \u306B\u66F8\u3051\u307E\u305B\u3093 ("${name}")`,
|
|
4266
|
+
hint: `\u66F8\u3051\u308B\u306E\u306F ${[...known].join(" / ")} \u3060\u3051`
|
|
4267
|
+
});
|
|
4268
|
+
}
|
|
4269
|
+
const triggerRaw = seen.get("trigger");
|
|
4270
|
+
let trigger = null;
|
|
4271
|
+
if (triggerRaw === void 0) {
|
|
4272
|
+
issues.push({ message: `trigger \u304C\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: '`trigger: step "\u53D6\u8FBC\u307F"` \u304B `trigger: vDone >= 100` \u3092\u66F8\u304F' });
|
|
4273
|
+
} else {
|
|
4274
|
+
const parsed = parseTriggerExpression(triggerRaw, name);
|
|
4275
|
+
if ("message" in parsed) issues.push(parsed);
|
|
4276
|
+
else trigger = parsed;
|
|
4277
|
+
}
|
|
4278
|
+
const toRaw = seen.get("to");
|
|
4279
|
+
let to = 0;
|
|
4280
|
+
if (toRaw === void 0) {
|
|
4281
|
+
issues.push({ message: `to \u304C\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: "`to: 100` \u306E\u3088\u3046\u306B\u52D5\u3044\u305F\u5148\u306E\u5024\u3092\u66F8\u304F" });
|
|
4282
|
+
} else {
|
|
4283
|
+
to = Number(unquote(toRaw));
|
|
4284
|
+
if (!Number.isFinite(to)) {
|
|
4285
|
+
issues.push({ message: `to \u304C\u6570\u3067\u306F\u3042\u308A\u307E\u305B\u3093: "${toRaw}" ("${name}")`, hint: "`to: 100` \u306E\u3088\u3046\u306B\u6570\u3067\u66F8\u304F" });
|
|
4286
|
+
}
|
|
4287
|
+
}
|
|
4288
|
+
const durRaw = seen.get("dur");
|
|
4289
|
+
let durationMs = 0;
|
|
4290
|
+
if (durRaw === void 0) {
|
|
4291
|
+
issues.push({ message: `dur \u304C\u3042\u308A\u307E\u305B\u3093 ("${name}")`, hint: "`dur: 2s` \u306E\u3088\u3046\u306B\u52D5\u304F\u9577\u3055\u3092\u66F8\u304F" });
|
|
4292
|
+
} else {
|
|
4293
|
+
const parsedDur = parseDurationMs(unquote(durRaw));
|
|
4294
|
+
if (parsedDur === null) {
|
|
4295
|
+
issues.push({ message: `dur \u304C\u8AAD\u3081\u307E\u305B\u3093: "${durRaw}" ("${name}")`, hint: "`2s` / `1.5s` / `500ms` \u306E\u5F62\u3067\u3001 0 \u3088\u308A\u5927\u304D\u3044\u9577\u3055\u3092\u66F8\u304F" });
|
|
4296
|
+
} else {
|
|
4297
|
+
durationMs = parsedDur;
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
if (issues.length > 0 || trigger === null) return { spec: null, issues };
|
|
4301
|
+
return { spec: { trigger, to, durationMs }, issues: [] };
|
|
2713
4302
|
}
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
let
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
4303
|
+
function checkValueExpression(expression, name) {
|
|
4304
|
+
const issues = [];
|
|
4305
|
+
const refRe = /\{([^}]*)\}/g;
|
|
4306
|
+
let m;
|
|
4307
|
+
while ((m = refRe.exec(expression)) !== null) {
|
|
4308
|
+
const ref = (m[1] ?? "").trim();
|
|
4309
|
+
if (!VALUE_NAME_RE.test(ref)) {
|
|
4310
|
+
issues.push({
|
|
4311
|
+
message: `invalid reference "{${ref}}" in "${name}"`,
|
|
4312
|
+
hint: "\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046"
|
|
4313
|
+
});
|
|
4314
|
+
}
|
|
2726
4315
|
}
|
|
2727
|
-
if (!
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
4316
|
+
if (expression.includes("{") && !expression.includes("}")) {
|
|
4317
|
+
issues.push({ message: `unclosed "{" in "${name}"`, hint: "`{\u540D\u524D}` \u306E\u5F62\u3067\u9589\u3058\u308B" });
|
|
4318
|
+
}
|
|
4319
|
+
const outside = expression.replace(/\{[^}]*\}/g, " ");
|
|
4320
|
+
if (outside.includes("%")) {
|
|
4321
|
+
issues.push({ message: `"%" \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`, hint: "\u56DB\u5247 (+ - * /) \u3060\u3051\u3092\u4F7F\u3046" });
|
|
4322
|
+
}
|
|
4323
|
+
if (outside.includes("?")) {
|
|
4324
|
+
issues.push({
|
|
4325
|
+
message: `\u6761\u4EF6\u5206\u5C90 (?:) \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`,
|
|
4326
|
+
hint: "\u6BD4\u8F03\u306E\u7D50\u679C\u306F\u771F = 1 / \u507D = 0 \u306E\u6570\u306B\u306A\u308B\u306E\u3067\u3001 \u639B\u3051\u7B97\u3067\u5207\u308A\u66FF\u3048\u308B"
|
|
4327
|
+
});
|
|
4328
|
+
}
|
|
4329
|
+
for (const fn of outside.matchAll(/[a-zA-Z_][a-zA-Z0-9_.]*/g)) {
|
|
4330
|
+
const word = fn[0];
|
|
4331
|
+
if (VALUE_FNS.has(word)) continue;
|
|
4332
|
+
issues.push({
|
|
4333
|
+
message: `"${word}" \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`,
|
|
4334
|
+
hint: word.startsWith("Math.") ? "min / max \u306F Math. \u3092\u4ED8\u3051\u305A\u306B\u66F8\u304F" : `\u4F7F\u3048\u308B\u306E\u306F ${[...VALUE_FNS].join(" / ")} \u3060\u3051\u3002 \u5024\u306F {\u540D\u524D} \u3067\u8AAD\u3080`
|
|
4335
|
+
});
|
|
4336
|
+
}
|
|
4337
|
+
const stray = outside.replace(/[a-zA-Z_][a-zA-Z0-9_.]*/g, " ").match(/[^0-9.,+\-*/()<>=!\s]/g);
|
|
4338
|
+
if (stray) {
|
|
4339
|
+
issues.push({
|
|
4340
|
+
message: `"${[...new Set(stray)].join("")}" \u306F\u5F0F\u306B\u66F8\u3051\u306A\u3044 ("${name}")`,
|
|
4341
|
+
hint: "\u56DB\u5247 (+ - * /) / \u62EC\u5F27 / \u6BD4\u8F03 (> >= < <= == !=) / min / max \u3060\u3051\u3092\u4F7F\u3046"
|
|
4342
|
+
});
|
|
4343
|
+
}
|
|
4344
|
+
return issues;
|
|
4345
|
+
}
|
|
4346
|
+
|
|
4347
|
+
// src/v05/parser.ts
|
|
4348
|
+
var TOP_LEVEL_KEYS = [
|
|
4349
|
+
"title",
|
|
4350
|
+
"type",
|
|
4351
|
+
"actors",
|
|
4352
|
+
"flow",
|
|
4353
|
+
"states",
|
|
4354
|
+
"values",
|
|
4355
|
+
"animation",
|
|
4356
|
+
"viewport",
|
|
4357
|
+
"lanes",
|
|
4358
|
+
"groups",
|
|
4359
|
+
// 図全体を 1 箱にする図種で、 その箱の上に出す小見出し (#1247)
|
|
4360
|
+
"eyebrow",
|
|
4361
|
+
// 2 軸で仕分ける図の軸の名前 (#1251)
|
|
4362
|
+
"axes"
|
|
4363
|
+
];
|
|
4364
|
+
var LANE_ID_ENTRY = /^([\p{L}\p{N}_-]+)\s*:\s*\{([^}]*)\}\s*$/u;
|
|
4365
|
+
function isTopLevelKey(key) {
|
|
4366
|
+
return TOP_LEVEL_KEYS.includes(key);
|
|
2731
4367
|
}
|
|
2732
4368
|
var PRESET_TYPES = /* @__PURE__ */ new Set([
|
|
2733
4369
|
"sequence",
|
|
@@ -2740,6 +4376,12 @@ var PRESET_TYPES = /* @__PURE__ */ new Set([
|
|
|
2740
4376
|
"gantt",
|
|
2741
4377
|
"class",
|
|
2742
4378
|
"pie",
|
|
4379
|
+
"bar",
|
|
4380
|
+
"line",
|
|
4381
|
+
"funnel",
|
|
4382
|
+
"tree",
|
|
4383
|
+
"journey",
|
|
4384
|
+
"quadrant",
|
|
2743
4385
|
"c4",
|
|
2744
4386
|
"mind"
|
|
2745
4387
|
]);
|
|
@@ -2790,9 +4432,14 @@ function parseTextDslV05(src) {
|
|
|
2790
4432
|
const lines = tokenize(src);
|
|
2791
4433
|
let title = null;
|
|
2792
4434
|
let type = null;
|
|
4435
|
+
let eyebrow = null;
|
|
4436
|
+
let eyebrowLine = 0;
|
|
4437
|
+
let axes = void 0;
|
|
4438
|
+
let axesLine = 0;
|
|
2793
4439
|
let actors = [];
|
|
2794
4440
|
const flow2 = [];
|
|
2795
4441
|
let animate = void 0;
|
|
4442
|
+
const values = [];
|
|
2796
4443
|
let viewport = void 0;
|
|
2797
4444
|
let lanesMap = void 0;
|
|
2798
4445
|
let groupsMap = void 0;
|
|
@@ -2804,11 +4451,11 @@ function parseTextDslV05(src) {
|
|
|
2804
4451
|
continue;
|
|
2805
4452
|
}
|
|
2806
4453
|
const head = matchTopHeader(line.trimmed);
|
|
2807
|
-
if (!head) {
|
|
4454
|
+
if (!head || !isTopLevelKey(head.key)) {
|
|
2808
4455
|
errors.push({
|
|
2809
4456
|
line: line.no,
|
|
2810
4457
|
message: `unknown top-level key: "${line.trimmed}"`,
|
|
2811
|
-
hint:
|
|
4458
|
+
hint: `expected one of: ${TOP_LEVEL_KEYS.join(", ")}`
|
|
2812
4459
|
});
|
|
2813
4460
|
i += 1;
|
|
2814
4461
|
continue;
|
|
@@ -2821,6 +4468,13 @@ function parseTextDslV05(src) {
|
|
|
2821
4468
|
i += 1;
|
|
2822
4469
|
continue;
|
|
2823
4470
|
}
|
|
4471
|
+
if (head.key === "eyebrow") {
|
|
4472
|
+
const v = (head.value ?? "").trim();
|
|
4473
|
+
eyebrow = v.length > 0 ? v : null;
|
|
4474
|
+
eyebrowLine = line.no;
|
|
4475
|
+
i += 1;
|
|
4476
|
+
continue;
|
|
4477
|
+
}
|
|
2824
4478
|
if (head.key === "type") {
|
|
2825
4479
|
const v = (head.value ?? "").trim().toLowerCase();
|
|
2826
4480
|
if (!PRESET_TYPES.has(v)) {
|
|
@@ -2895,6 +4549,25 @@ function parseTextDslV05(src) {
|
|
|
2895
4549
|
i = next;
|
|
2896
4550
|
continue;
|
|
2897
4551
|
}
|
|
4552
|
+
if (head.key === "values") {
|
|
4553
|
+
const inline = head.value?.trim();
|
|
4554
|
+
if (inline) {
|
|
4555
|
+
errors.push({
|
|
4556
|
+
line: line.no,
|
|
4557
|
+
message: "values \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
|
|
4558
|
+
hint: '\u5F0F\u306B `,` \u304C\u5165\u308B\u305F\u3081\u3002 \u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `waiting: "{inflow} - {done}"` \u306E\u5F62\u3067\u4E26\u3079\u308B'
|
|
4559
|
+
});
|
|
4560
|
+
i += 1;
|
|
4561
|
+
continue;
|
|
4562
|
+
}
|
|
4563
|
+
const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
|
|
4564
|
+
for (const it of items) {
|
|
4565
|
+
const v = parseValueEntry(it.trimmed.replace(/^-\s*/, ""), it.no, errors);
|
|
4566
|
+
if (v) values.push(v);
|
|
4567
|
+
}
|
|
4568
|
+
i = next;
|
|
4569
|
+
continue;
|
|
4570
|
+
}
|
|
2898
4571
|
if (head.key === "animation") {
|
|
2899
4572
|
const { items: stepBlocks, next } = collectAnimationSteps(lines, i + 1, line.indent);
|
|
2900
4573
|
animate = ensureAnimate(animate, line.no);
|
|
@@ -2943,11 +4616,42 @@ function parseTextDslV05(src) {
|
|
|
2943
4616
|
i = next;
|
|
2944
4617
|
continue;
|
|
2945
4618
|
}
|
|
4619
|
+
if (head.key === "axes") {
|
|
4620
|
+
if (head.value !== null && head.value.trim() !== "") {
|
|
4621
|
+
errors.push({
|
|
4622
|
+
line: line.no,
|
|
4623
|
+
message: "axes \u306F 1 \u884C\u306B\u307E\u3068\u3081\u3066\u66F8\u3051\u306A\u3044",
|
|
4624
|
+
hint: '\u6B21\u306E\u884C\u304B\u3089\u5B57\u4E0B\u3052\u3057\u3066 `x: { left: "...", right: "..." }` \u306E\u5F62\u3067\u4E26\u3079\u308B'
|
|
4625
|
+
});
|
|
4626
|
+
i += 1;
|
|
4627
|
+
continue;
|
|
4628
|
+
}
|
|
4629
|
+
const { items, next } = collectIndentedRaw(lines, i + 1, line.indent);
|
|
4630
|
+
axesLine = line.no;
|
|
4631
|
+
const \u7D44\u307F\u7ACB\u3066 = {};
|
|
4632
|
+
for (const it of items) {
|
|
4633
|
+
const m = it.trimmed.match(/^(x|y)\s*:\s*\{([^}]*)\}\s*$/);
|
|
4634
|
+
if (!m) {
|
|
4635
|
+
errors.push({
|
|
4636
|
+
line: it.no,
|
|
4637
|
+
message: `invalid axes entry: "${it.trimmed}"`,
|
|
4638
|
+
hint: 'use `x: { left: "...", right: "..." }` or `y: { bottom: "...", top: "..." }`'
|
|
4639
|
+
});
|
|
4640
|
+
continue;
|
|
4641
|
+
}
|
|
4642
|
+
const opts = parseInlineMapping(m[2] ?? "");
|
|
4643
|
+
if (m[1] === "x") \u7D44\u307F\u7ACB\u3066.x = { left: opts.left, right: opts.right };
|
|
4644
|
+
else \u7D44\u307F\u7ACB\u3066.y = { bottom: opts.bottom, top: opts.top };
|
|
4645
|
+
}
|
|
4646
|
+
axes = \u7D44\u307F\u7ACB\u3066.x !== void 0 || \u7D44\u307F\u7ACB\u3066.y !== void 0 ? \u7D44\u307F\u7ACB\u3066 : void 0;
|
|
4647
|
+
i = next;
|
|
4648
|
+
continue;
|
|
4649
|
+
}
|
|
2946
4650
|
if (head.key === "lanes") {
|
|
2947
4651
|
const { items, next } = collectIndentedList(lines, i + 1, line.indent);
|
|
2948
4652
|
lanesMap = {};
|
|
2949
4653
|
for (const it of items) {
|
|
2950
|
-
const m = it.trimmed.match(
|
|
4654
|
+
const m = it.trimmed.match(LANE_ID_ENTRY);
|
|
2951
4655
|
if (m) {
|
|
2952
4656
|
const id = m[1];
|
|
2953
4657
|
const opts = parseInlineMapping(m[2]);
|
|
@@ -2975,7 +4679,7 @@ function parseTextDslV05(src) {
|
|
|
2975
4679
|
const { items, next } = collectIndentedList(lines, i + 1, line.indent);
|
|
2976
4680
|
groupsMap = {};
|
|
2977
4681
|
for (const it of items) {
|
|
2978
|
-
const m = it.trimmed.match(
|
|
4682
|
+
const m = it.trimmed.match(LANE_ID_ENTRY);
|
|
2979
4683
|
if (m) {
|
|
2980
4684
|
const id = m[1];
|
|
2981
4685
|
const opts = parseInlineMapping(m[2]);
|
|
@@ -3007,9 +4711,12 @@ function parseTextDslV05(src) {
|
|
|
3007
4711
|
doc: {
|
|
3008
4712
|
title,
|
|
3009
4713
|
type,
|
|
4714
|
+
...eyebrow !== null ? { eyebrow, eyebrowPos: { line: eyebrowLine } } : {},
|
|
4715
|
+
...axes !== void 0 ? { axes, axesPos: { line: axesLine } } : {},
|
|
3010
4716
|
actors,
|
|
3011
4717
|
flow: flow2,
|
|
3012
4718
|
animate,
|
|
4719
|
+
...values.length > 0 ? { values } : {},
|
|
3013
4720
|
viewport,
|
|
3014
4721
|
lanes: lanesMap,
|
|
3015
4722
|
groups: groupsMap,
|
|
@@ -3274,6 +4981,7 @@ function applyContinuationLines(actor, rest, errors) {
|
|
|
3274
4981
|
const state = { ...actor.stateOverride ?? {} };
|
|
3275
4982
|
let touchedState = false;
|
|
3276
4983
|
const scaleWritten = /* @__PURE__ */ new Map();
|
|
4984
|
+
const \u56F3\u7A2E\u3054\u3068\u306E\u6B04 = /* @__PURE__ */ new Map();
|
|
3277
4985
|
const unknownKeys = [];
|
|
3278
4986
|
for (const ln of rest) {
|
|
3279
4987
|
const idx = ln.trimmed.indexOf(":");
|
|
@@ -3362,6 +5070,12 @@ function applyContinuationLines(actor, rest, errors) {
|
|
|
3362
5070
|
});
|
|
3363
5071
|
break;
|
|
3364
5072
|
}
|
|
5073
|
+
case "touchpoint":
|
|
5074
|
+
case "opportunity":
|
|
5075
|
+
case "owner":
|
|
5076
|
+
case "end":
|
|
5077
|
+
\u56F3\u7A2E\u3054\u3068\u306E\u6B04.set(key, stripQuotes(raw));
|
|
5078
|
+
break;
|
|
3365
5079
|
case "lane":
|
|
3366
5080
|
out.lane = stripQuotes(raw);
|
|
3367
5081
|
break;
|
|
@@ -3380,6 +5094,17 @@ function applyContinuationLines(actor, rest, errors) {
|
|
|
3380
5094
|
out.scale = s.scale;
|
|
3381
5095
|
out.scaleKeys = [.../* @__PURE__ */ new Set([...actor.scaleKeys ?? [], ...s.keys])];
|
|
3382
5096
|
}
|
|
5097
|
+
for (const [key, v] of \u56F3\u7A2E\u3054\u3068\u306E\u6B04) {
|
|
5098
|
+
if (out.partId !== void 0) {
|
|
5099
|
+
state[key] = coerceStateValue(v);
|
|
5100
|
+
touchedState = true;
|
|
5101
|
+
continue;
|
|
5102
|
+
}
|
|
5103
|
+
if (key === "touchpoint") out.touchpoint = v;
|
|
5104
|
+
else if (key === "opportunity") out.opportunity = v;
|
|
5105
|
+
else if (key === "owner") out.owner = v;
|
|
5106
|
+
else out.end = v;
|
|
5107
|
+
}
|
|
3383
5108
|
if (out.partId !== void 0) {
|
|
3384
5109
|
if (touchedState) out.stateOverride = state;
|
|
3385
5110
|
return out;
|
|
@@ -3412,7 +5137,13 @@ var ACTOR_ITEM_KEYS = /* @__PURE__ */ new Set([
|
|
|
3412
5137
|
"\u500D\u7387",
|
|
3413
5138
|
"scale",
|
|
3414
5139
|
"lane",
|
|
3415
|
-
"stack"
|
|
5140
|
+
"stack",
|
|
5141
|
+
// 体験の道筋の欄 (#1251)
|
|
5142
|
+
"touchpoint",
|
|
5143
|
+
"opportunity",
|
|
5144
|
+
// 工程の並びの欄 (#1251)
|
|
5145
|
+
"owner",
|
|
5146
|
+
"end"
|
|
3416
5147
|
]);
|
|
3417
5148
|
function validateRelativePositions(actors, errors) {
|
|
3418
5149
|
const named = new Set(actors.map((a) => a.name));
|
|
@@ -3511,6 +5242,9 @@ var ACTOR_RESERVED_FIELDS = /* @__PURE__ */ new Set([
|
|
|
3511
5242
|
"initial",
|
|
3512
5243
|
"final",
|
|
3513
5244
|
"state",
|
|
5245
|
+
// 体験の道筋の欄 (`touchpoint` / `opportunity`) はここに載せない (#1251 Round 1 の指摘)。
|
|
5246
|
+
// 載せるとパーツで同じ名前の状態を書いた時に横取りされる = 既に動いている見本が静かに変わる。
|
|
5247
|
+
// パーツでない箱でだけ道筋の欄として読む (`parseActor` / `applyContinuationLines` が分岐する)
|
|
3514
5248
|
// canvas pivot 新 spec = 絶対座標 4 field (dragon canvas pivot spec §layout-role-conversion)
|
|
3515
5249
|
"posX",
|
|
3516
5250
|
"posY",
|
|
@@ -3617,6 +5351,12 @@ var INLINE_ACTOR_KEYS = /* @__PURE__ */ new Set([
|
|
|
3617
5351
|
"final",
|
|
3618
5352
|
"tone",
|
|
3619
5353
|
"nodes",
|
|
5354
|
+
// 体験の道筋の欄 (#1251)。 他の図種では組み立て側が知らせる
|
|
5355
|
+
"touchpoint",
|
|
5356
|
+
"opportunity",
|
|
5357
|
+
// 工程の並びの欄 (#1251)
|
|
5358
|
+
"owner",
|
|
5359
|
+
"end",
|
|
3620
5360
|
"posX",
|
|
3621
5361
|
"posY",
|
|
3622
5362
|
"posW",
|
|
@@ -3626,6 +5366,15 @@ var INLINE_ACTOR_KEYS = /* @__PURE__ */ new Set([
|
|
|
3626
5366
|
"scale",
|
|
3627
5367
|
"\u500D\u7387"
|
|
3628
5368
|
]);
|
|
5369
|
+
var FLOW_INLINE_READERS = {
|
|
5370
|
+
sub: (v) => v,
|
|
5371
|
+
guard: (v) => v,
|
|
5372
|
+
cardinality: (v) => v,
|
|
5373
|
+
labelOffsetX: (v) => numberOrUndef(v),
|
|
5374
|
+
labelOffsetY: (v) => numberOrUndef(v),
|
|
5375
|
+
overlay: (v) => boolOrUndef(v)
|
|
5376
|
+
};
|
|
5377
|
+
var FLOW_INLINE_KEYS = Object.keys(FLOW_INLINE_READERS);
|
|
3629
5378
|
function reportUnknownInlineKeys(isPart, inner, line, errors) {
|
|
3630
5379
|
if (isPart) return;
|
|
3631
5380
|
for (const field of splitInlineFields(inner)) {
|
|
@@ -3663,6 +5412,12 @@ function parseActor2(line, errors) {
|
|
|
3663
5412
|
kindWritten: kindRaw !== "" && !isPart,
|
|
3664
5413
|
subtitle: opts.subtitle,
|
|
3665
5414
|
eyebrow: opts.eyebrow,
|
|
5415
|
+
// パーツでは状態の上書きとして意味を持つため、道筋の欄として横取りしない (#1251)
|
|
5416
|
+
touchpoint: isPart ? void 0 : opts.touchpoint,
|
|
5417
|
+
opportunity: isPart ? void 0 : opts.opportunity,
|
|
5418
|
+
// 見本では状態の上書きとして意味を持つため横取りしない (#1251)
|
|
5419
|
+
owner: isPart ? void 0 : opts.owner,
|
|
5420
|
+
end: isPart ? void 0 : opts.end,
|
|
3666
5421
|
value: opts.value,
|
|
3667
5422
|
rows: opts.rows ? opts.rows.replace(/^\[|\]$/g, "").split(/,(?![^[]*\])/).map((x) => stripQuotes(x.trim())).filter(Boolean) : void 0,
|
|
3668
5423
|
lane: opts.lane,
|
|
@@ -3728,21 +5483,19 @@ function parseFlowStep(line, no) {
|
|
|
3728
5483
|
let label = "";
|
|
3729
5484
|
let tone;
|
|
3730
5485
|
let style;
|
|
3731
|
-
|
|
3732
|
-
let guard;
|
|
3733
|
-
let cardinality;
|
|
3734
|
-
let labelOffsetX;
|
|
3735
|
-
let labelOffsetY;
|
|
5486
|
+
const \u4E2D\u62EC\u5F27 = {};
|
|
3736
5487
|
const mapMatch = rest.match(/\s*\{([^}]*)\}\s*$/);
|
|
3737
5488
|
if (mapMatch) {
|
|
3738
5489
|
const opts = parseInlineMapping(mapMatch[1]);
|
|
3739
|
-
|
|
3740
|
-
guard = opts.guard;
|
|
3741
|
-
cardinality = opts.cardinality;
|
|
3742
|
-
labelOffsetX = numberOrUndef(opts.labelOffsetX);
|
|
3743
|
-
labelOffsetY = numberOrUndef(opts.labelOffsetY);
|
|
5490
|
+
for (const k of FLOW_INLINE_KEYS) \u4E2D\u62EC\u5F27[k] = FLOW_INLINE_READERS[k](opts[k]);
|
|
3744
5491
|
rest = rest.slice(0, mapMatch.index ?? 0).trim();
|
|
3745
5492
|
}
|
|
5493
|
+
const sub = \u4E2D\u62EC\u5F27.sub;
|
|
5494
|
+
const guard = \u4E2D\u62EC\u5F27.guard;
|
|
5495
|
+
const cardinality = \u4E2D\u62EC\u5F27.cardinality;
|
|
5496
|
+
const labelOffsetX = \u4E2D\u62EC\u5F27.labelOffsetX;
|
|
5497
|
+
const labelOffsetY = \u4E2D\u62EC\u5F27.labelOffsetY;
|
|
5498
|
+
const overlay = \u4E2D\u62EC\u5F27.overlay;
|
|
3746
5499
|
const optMatch = rest.match(/\s*\(([^)]*)\)\s*$/);
|
|
3747
5500
|
if (optMatch) {
|
|
3748
5501
|
const opts = (optMatch[1] ?? "").split(",").map((s) => s.trim());
|
|
@@ -3791,19 +5544,72 @@ function parseFlowStep(line, no) {
|
|
|
3791
5544
|
cardinality,
|
|
3792
5545
|
labelOffsetX,
|
|
3793
5546
|
labelOffsetY,
|
|
5547
|
+
overlay,
|
|
3794
5548
|
pos: { line: line.no }
|
|
3795
5549
|
};
|
|
3796
5550
|
}
|
|
3797
5551
|
function parseStateEntry(text, lineNo) {
|
|
3798
|
-
const m = text.match(/^([
|
|
5552
|
+
const m = text.match(/^([^:]+?)\s*:\s*(.+)$/);
|
|
3799
5553
|
if (!m) return null;
|
|
3800
|
-
const name = m[1] ?? "";
|
|
5554
|
+
const name = (m[1] ?? "").trim();
|
|
5555
|
+
if (!isValueName(name)) return null;
|
|
3801
5556
|
const raw = (m[2] ?? "").trim();
|
|
3802
5557
|
const stripped = stripQuotes(raw);
|
|
3803
5558
|
const asNum = Number(stripped);
|
|
3804
5559
|
const initial = Number.isFinite(asNum) && stripped !== "" && !isNaN(asNum) ? asNum : stripped;
|
|
3805
5560
|
return { name, initial, pos: { line: lineNo } };
|
|
3806
5561
|
}
|
|
5562
|
+
function collectIndentedRaw(lines, start, parentIndent) {
|
|
5563
|
+
const items = [];
|
|
5564
|
+
let i = start;
|
|
5565
|
+
while (i < lines.length) {
|
|
5566
|
+
const ln = lines[i];
|
|
5567
|
+
if (!ln || !ln.trimmed || ln.trimmed.startsWith("#")) {
|
|
5568
|
+
i += 1;
|
|
5569
|
+
continue;
|
|
5570
|
+
}
|
|
5571
|
+
if (ln.indent <= parentIndent) break;
|
|
5572
|
+
items.push(ln);
|
|
5573
|
+
i += 1;
|
|
5574
|
+
}
|
|
5575
|
+
return { items, next: i };
|
|
5576
|
+
}
|
|
5577
|
+
function parseValueEntry(text, lineNo, errors) {
|
|
5578
|
+
const m = text.match(/^([^:]+?)\s*:\s*(.+)$/);
|
|
5579
|
+
if (!m) {
|
|
5580
|
+
errors.push({
|
|
5581
|
+
line: lineNo,
|
|
5582
|
+
message: `invalid value entry: "${text}"`,
|
|
5583
|
+
hint: '`waiting: "{inflow} - {done}"` \u306E\u5F62\u3067\u66F8\u304F'
|
|
5584
|
+
});
|
|
5585
|
+
return null;
|
|
5586
|
+
}
|
|
5587
|
+
const name = (m[1] ?? "").trim();
|
|
5588
|
+
if (!isValueName(name)) {
|
|
5589
|
+
errors.push({ line: lineNo, ...valueNameIssue(name) });
|
|
5590
|
+
return null;
|
|
5591
|
+
}
|
|
5592
|
+
const rest = (m[2] ?? "").trim();
|
|
5593
|
+
if (isTriggerBody(rest)) {
|
|
5594
|
+
const { spec, issues: issues2 } = parseValueTriggerBody(rest.slice(1, -1), name);
|
|
5595
|
+
if (spec === null) {
|
|
5596
|
+
for (const issue of issues2) errors.push({ line: lineNo, ...issue });
|
|
5597
|
+
return null;
|
|
5598
|
+
}
|
|
5599
|
+
return { name, trigger: spec.trigger, to: spec.to, durationMs: spec.durationMs, pos: { line: lineNo } };
|
|
5600
|
+
}
|
|
5601
|
+
const expression = stripQuotes(rest);
|
|
5602
|
+
if (expression === "") {
|
|
5603
|
+
errors.push({ line: lineNo, message: `empty expression for "${name}"`, hint: '`"{a} + {b}"` \u306E\u3088\u3046\u306B\u5F0F\u3092\u66F8\u304F' });
|
|
5604
|
+
return null;
|
|
5605
|
+
}
|
|
5606
|
+
const issues = checkValueExpression(expression, name);
|
|
5607
|
+
if (issues.length > 0) {
|
|
5608
|
+
for (const issue of issues) errors.push({ line: lineNo, ...issue });
|
|
5609
|
+
return null;
|
|
5610
|
+
}
|
|
5611
|
+
return { name, expression, pos: { line: lineNo } };
|
|
5612
|
+
}
|
|
3807
5613
|
function splitTopLevelCommas(s) {
|
|
3808
5614
|
return s.split(",").map((x) => x.trim()).filter(Boolean);
|
|
3809
5615
|
}
|
|
@@ -3927,12 +5733,23 @@ function parseStepHead(s) {
|
|
|
3927
5733
|
function parseFocusList(s) {
|
|
3928
5734
|
let body = s.trim();
|
|
3929
5735
|
if (body.startsWith("[") && body.endsWith("]")) body = body.slice(1, -1);
|
|
3930
|
-
const
|
|
5736
|
+
const groups = [];
|
|
5737
|
+
let group = [];
|
|
3931
5738
|
let buf = "";
|
|
3932
5739
|
let quote = null;
|
|
5740
|
+
const pushFragment = (quoted) => {
|
|
5741
|
+
if (buf.trim()) group.push({ text: buf, quoted });
|
|
5742
|
+
buf = "";
|
|
5743
|
+
};
|
|
5744
|
+
const pushGroup = () => {
|
|
5745
|
+
pushFragment(false);
|
|
5746
|
+
if (group.length > 0) groups.push(group);
|
|
5747
|
+
group = [];
|
|
5748
|
+
};
|
|
3933
5749
|
for (const ch of body) {
|
|
3934
5750
|
if (quote) {
|
|
3935
5751
|
if (ch === quote) {
|
|
5752
|
+
pushFragment(true);
|
|
3936
5753
|
quote = null;
|
|
3937
5754
|
continue;
|
|
3938
5755
|
}
|
|
@@ -3940,41 +5757,49 @@ function parseFocusList(s) {
|
|
|
3940
5757
|
continue;
|
|
3941
5758
|
}
|
|
3942
5759
|
if (ch === '"' || ch === "'") {
|
|
3943
|
-
|
|
3944
|
-
|
|
5760
|
+
if (!buf || /\s$/.test(buf)) {
|
|
5761
|
+
pushFragment(false);
|
|
5762
|
+
quote = ch;
|
|
5763
|
+
continue;
|
|
5764
|
+
}
|
|
3945
5765
|
}
|
|
3946
5766
|
if (ch === ",") {
|
|
3947
|
-
|
|
3948
|
-
if (t) parts.push(t);
|
|
3949
|
-
buf = "";
|
|
5767
|
+
pushGroup();
|
|
3950
5768
|
continue;
|
|
3951
5769
|
}
|
|
3952
5770
|
buf += ch;
|
|
3953
5771
|
}
|
|
3954
|
-
|
|
3955
|
-
if (
|
|
5772
|
+
pushFragment(quote !== null);
|
|
5773
|
+
if (group.length > 0) groups.push(group);
|
|
3956
5774
|
const out = [];
|
|
3957
|
-
for (const
|
|
3958
|
-
|
|
3959
|
-
|
|
5775
|
+
for (const fragments of groups) {
|
|
5776
|
+
const whole = fragments.map(({ text }) => text).join("").trim();
|
|
5777
|
+
if (fragments.every(({ quoted }) => !quoted) && /[-→][>]?/.test(whole) && /\s/.test(whole)) {
|
|
5778
|
+
out.push(whole);
|
|
3960
5779
|
continue;
|
|
3961
5780
|
}
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
5781
|
+
for (const { text, quoted } of fragments) {
|
|
5782
|
+
const p = text.trim();
|
|
5783
|
+
if (!p) continue;
|
|
5784
|
+
if (quoted) {
|
|
5785
|
+
out.push(p);
|
|
5786
|
+
} else {
|
|
5787
|
+
for (const x of p.split(/\s+/)) {
|
|
5788
|
+
if (x) out.push(x);
|
|
5789
|
+
}
|
|
3965
5790
|
}
|
|
3966
|
-
continue;
|
|
3967
5791
|
}
|
|
3968
|
-
out.push(p);
|
|
3969
5792
|
}
|
|
3970
5793
|
return out;
|
|
3971
5794
|
}
|
|
3972
5795
|
function parseTweenLine(s, lineNo) {
|
|
3973
5796
|
const cleaned = s.replace(/^-\s*/, "").trim();
|
|
3974
|
-
const m = cleaned.match(/^([
|
|
5797
|
+
const m = cleaned.match(/^([^:\s]+)\s*[:\s]\s*(-?\d+(?:\.\d+)?)\s*->\s*(-?\d+(?:\.\d+)?)$/);
|
|
3975
5798
|
if (!m) return null;
|
|
5799
|
+
const state = m[1] ?? "";
|
|
5800
|
+
if (!isValueName(state)) return null;
|
|
3976
5801
|
return {
|
|
3977
|
-
state
|
|
5802
|
+
state,
|
|
3978
5803
|
from: parseFloat(m[2] ?? "0"),
|
|
3979
5804
|
to: parseFloat(m[3] ?? "0"),
|
|
3980
5805
|
pos: { line: lineNo }
|
|
@@ -3982,13 +5807,15 @@ function parseTweenLine(s, lineNo) {
|
|
|
3982
5807
|
}
|
|
3983
5808
|
function parseSetLine(s, lineNo) {
|
|
3984
5809
|
const cleaned = s.replace(/^-\s*/, "").trim();
|
|
3985
|
-
const m = cleaned.match(/^([
|
|
5810
|
+
const m = cleaned.match(/^([^:\s]+)\s*[:\s]\s*(.+)$/);
|
|
3986
5811
|
if (!m) return null;
|
|
5812
|
+
const state = m[1] ?? "";
|
|
5813
|
+
if (!isValueName(state)) return null;
|
|
3987
5814
|
const raw = (m[2] ?? "").trim();
|
|
3988
5815
|
const stripped = stripQuotes(raw);
|
|
3989
5816
|
const asNum = Number(stripped);
|
|
3990
5817
|
const value = Number.isFinite(asNum) && stripped !== "" && !isNaN(asNum) ? asNum : stripped;
|
|
3991
|
-
return { state
|
|
5818
|
+
return { state, value, pos: { line: lineNo } };
|
|
3992
5819
|
}
|
|
3993
5820
|
|
|
3994
5821
|
// src/notation-lint.ts
|
|
@@ -4038,7 +5865,6 @@ var KIND_TO_JA = {
|
|
|
4038
5865
|
tree: "\u968E\u5C64\u30C4\u30EA\u30FC",
|
|
4039
5866
|
userJourney: "\u30E6\u30FC\u30B6\u30FC\u30B8\u30E3\u30FC\u30CB\u30FC",
|
|
4040
5867
|
mindMap: "\u30DE\u30A4\u30F3\u30C9\u30DE\u30C3\u30D7",
|
|
4041
|
-
mindMapRadial: "\u653E\u5C04\u72B6\u30DE\u30A4\u30F3\u30C9\u30DE\u30C3\u30D7",
|
|
4042
5868
|
funnel: "\u30D5\u30A1\u30CD\u30EB (\u6BB5\u968E\u5225\u96E2\u8131)",
|
|
4043
5869
|
quadrant: "\u56DB\u8C61\u9650\u30DE\u30C8\u30EA\u30AF\u30B9",
|
|
4044
5870
|
gantt: "\u30AC\u30F3\u30C8\u30C1\u30E3\u30FC\u30C8",
|
|
@@ -4047,7 +5873,7 @@ var KIND_TO_JA = {
|
|
|
4047
5873
|
};
|
|
4048
5874
|
function applyTopicAutoFix(topic) {
|
|
4049
5875
|
const kindMatch = topic.match(
|
|
4050
|
-
/^\s*(chart|flow|swimlane|sequence|topology|er|stateMachine2?|infrastructure|classDiagram|tree|userJourney|mindMap
|
|
5876
|
+
/^\s*(chart|flow|swimlane|sequence|topology|er|stateMachine2?|infrastructure|classDiagram|tree|userJourney|mindMap|funnel|quadrant|gantt|flowchart|network|line chart|pie chart|bar chart)\b/i
|
|
4051
5877
|
);
|
|
4052
5878
|
if (kindMatch) {
|
|
4053
5879
|
const kind = kindMatch[1].toLowerCase();
|
|
@@ -4133,7 +5959,7 @@ function ruleGanttUnknownDependsOn(d) {
|
|
|
4133
5959
|
function ruleMindMapParentReference(d) {
|
|
4134
5960
|
const out = [];
|
|
4135
5961
|
for (const n of d.nodes) {
|
|
4136
|
-
if (
|
|
5962
|
+
if (n.kind === "mind-map" && n.mindData) {
|
|
4137
5963
|
const known = /* @__PURE__ */ new Set([n.mindData.rootId]);
|
|
4138
5964
|
for (const b of n.mindData.branches) known.add(b.id);
|
|
4139
5965
|
for (const b of n.mindData.branches) {
|
|
@@ -4209,7 +6035,10 @@ function ruleFunnelMonotonicCount(d) {
|
|
|
4209
6035
|
if (n.kind === "funnel-stages" && n.funnelData) {
|
|
4210
6036
|
const stages = n.funnelData;
|
|
4211
6037
|
for (let i = 1; i < stages.length; i++) {
|
|
4212
|
-
|
|
6038
|
+
const \u4ECA = stages[i].count;
|
|
6039
|
+
const \u524D = stages[i - 1].count;
|
|
6040
|
+
if (typeof \u4ECA !== "number" || typeof \u524D !== "number") continue;
|
|
6041
|
+
if (\u4ECA > \u524D) {
|
|
4213
6042
|
out.push({
|
|
4214
6043
|
rule: "funnel-increasing-count",
|
|
4215
6044
|
severity: "warn",
|
|
@@ -4297,7 +6126,7 @@ function matchActorHead(line) {
|
|
|
4297
6126
|
indentText: indentText2,
|
|
4298
6127
|
indent: indentText2.length,
|
|
4299
6128
|
rawName: rawName2,
|
|
4300
|
-
name:
|
|
6129
|
+
name: unquote2(rawName2),
|
|
4301
6130
|
hasColon: true,
|
|
4302
6131
|
rest: rest.trimEnd()
|
|
4303
6132
|
};
|
|
@@ -4310,21 +6139,21 @@ function matchActorHead(line) {
|
|
|
4310
6139
|
indentText,
|
|
4311
6140
|
indent: indentText.length,
|
|
4312
6141
|
rawName,
|
|
4313
|
-
name:
|
|
6142
|
+
name: unquote2(rawName),
|
|
4314
6143
|
hasColon: false,
|
|
4315
6144
|
rest: ""
|
|
4316
6145
|
};
|
|
4317
6146
|
}
|
|
4318
|
-
function
|
|
6147
|
+
function unquote2(raw) {
|
|
4319
6148
|
if (!raw.startsWith('"') || !raw.endsWith('"') || raw.length < 2) return raw;
|
|
4320
6149
|
return raw.slice(1, -1).replace(/\\(.)/g, "$1");
|
|
4321
6150
|
}
|
|
4322
6151
|
function upsertAtToken(rest, x, y) {
|
|
4323
|
-
const kept =
|
|
6152
|
+
const kept = splitOutsideQuotes2(rest).filter((t) => !/^@-?\d+(\.\d+)?\s*[,、]\s*-?\d+(\.\d+)?$/.test(t));
|
|
4324
6153
|
kept.push(`@${x},${y}`);
|
|
4325
6154
|
return kept.join(" ");
|
|
4326
6155
|
}
|
|
4327
|
-
function
|
|
6156
|
+
function splitOutsideQuotes2(s) {
|
|
4328
6157
|
const out = [];
|
|
4329
6158
|
let buf = "";
|
|
4330
6159
|
let quote = null;
|
|
@@ -4451,20 +6280,7 @@ var VALID_KIND_SET = /* @__PURE__ */ new Set([
|
|
|
4451
6280
|
"library",
|
|
4452
6281
|
"interface"
|
|
4453
6282
|
]);
|
|
4454
|
-
var VALID_PRESETS = [
|
|
4455
|
-
"sequence",
|
|
4456
|
-
"flow",
|
|
4457
|
-
"swimlane",
|
|
4458
|
-
"er",
|
|
4459
|
-
"state",
|
|
4460
|
-
"topology",
|
|
4461
|
-
"solidity",
|
|
4462
|
-
"gantt",
|
|
4463
|
-
"class",
|
|
4464
|
-
"pie",
|
|
4465
|
-
"c4",
|
|
4466
|
-
"mind"
|
|
4467
|
-
];
|
|
6283
|
+
var VALID_PRESETS = [...PRESET_TYPES];
|
|
4468
6284
|
function validateLayoutPos(v, path, errors) {
|
|
4469
6285
|
if (v === void 0) return;
|
|
4470
6286
|
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
@@ -4479,15 +6295,122 @@ function validateLayoutPos(v, path, errors) {
|
|
|
4479
6295
|
errors.push({ path: `${path}.y`, message: "pos.y must be a finite number" });
|
|
4480
6296
|
}
|
|
4481
6297
|
}
|
|
6298
|
+
var \u5199\u3057\u306E\u6700\u5927\u306E\u6DF1\u3055 = 64;
|
|
6299
|
+
var \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570 = 5e6;
|
|
6300
|
+
var \u5199\u305B\u306A\u3044 = class extends Error {
|
|
6301
|
+
constructor(path, \u7406\u7531) {
|
|
6302
|
+
super(`${path}: ${\u7406\u7531}`);
|
|
6303
|
+
this.path = path;
|
|
6304
|
+
this.\u7406\u7531 = \u7406\u7531;
|
|
6305
|
+
}
|
|
6306
|
+
path;
|
|
6307
|
+
\u7406\u7531;
|
|
6308
|
+
};
|
|
6309
|
+
function \u7D20\u306E\u30C7\u30FC\u30BF\u306B\u5199\u3059(root) {
|
|
6310
|
+
const \u5199\u3057\u6E08 = /* @__PURE__ */ new WeakMap();
|
|
6311
|
+
let \u9805\u76EE\u6570 = 0;
|
|
6312
|
+
let \u8AAD\u3093\u3067\u3044\u308B\u5834\u6240 = "$";
|
|
6313
|
+
const \u5668\u3092\u4F5C\u308B = (v, \u6DF1\u3055, path) => {
|
|
6314
|
+
\u9805\u76EE\u6570 += 1;
|
|
6315
|
+
if (\u9805\u76EE\u6570 > \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570) {
|
|
6316
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u9805\u76EE\u304C\u591A\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570})`);
|
|
6317
|
+
}
|
|
6318
|
+
if (v === null || typeof v !== "object") return { \u5024: v, \u67A0: null };
|
|
6319
|
+
const \u65E2\u306B\u3042\u308B = \u5199\u3057\u6E08.get(v);
|
|
6320
|
+
if (\u65E2\u306B\u3042\u308B !== void 0) return { \u5024: \u65E2\u306B\u3042\u308B, \u67A0: null };
|
|
6321
|
+
if (\u6DF1\u3055 >= \u5199\u3057\u306E\u6700\u5927\u306E\u6DF1\u3055) {
|
|
6322
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u5165\u308C\u5B50\u304C\u6DF1\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u6DF1\u3055})`);
|
|
6323
|
+
}
|
|
6324
|
+
\u8AAD\u3093\u3067\u3044\u308B\u5834\u6240 = path;
|
|
6325
|
+
const \u4E26\u3073\u304B = Array.isArray(v);
|
|
6326
|
+
const \u5668 = \u4E26\u3073\u304B ? [] : {};
|
|
6327
|
+
\u5199\u3057\u6E08.set(v, \u5668);
|
|
6328
|
+
if (\u4E26\u3073\u304B) {
|
|
6329
|
+
const \u751F\u306E\u9577\u3055 = +v.length;
|
|
6330
|
+
const \u9577\u3055 = Number.isNaN(\u751F\u306E\u9577\u3055) ? 0 : Math.min(Math.max(Math.trunc(\u751F\u306E\u9577\u3055), 0), Number.MAX_SAFE_INTEGER);
|
|
6331
|
+
\u9805\u76EE\u6570 += \u9577\u3055;
|
|
6332
|
+
if (\u9805\u76EE\u6570 > \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570) {
|
|
6333
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u9805\u76EE\u304C\u591A\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570})`);
|
|
6334
|
+
}
|
|
6335
|
+
return { \u5024: \u5668, \u67A0: { \u5143: v, \u5668, \u540D\u524D\u306E\u4E26\u3073: null, \u9577\u3055, \u6B21: 0, \u6DF1\u3055, path } };
|
|
6336
|
+
}
|
|
6337
|
+
const \u540D\u524D\u306E\u4E26\u3073 = Object.keys(v);
|
|
6338
|
+
\u9805\u76EE\u6570 += \u540D\u524D\u306E\u4E26\u3073.length;
|
|
6339
|
+
if (\u9805\u76EE\u6570 > \u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570) {
|
|
6340
|
+
throw new \u5199\u305B\u306A\u3044(path, `\u9805\u76EE\u304C\u591A\u3059\u304E\u308B (\u4E0A\u9650 ${\u5199\u3057\u306E\u6700\u5927\u306E\u9805\u76EE\u6570})`);
|
|
6341
|
+
}
|
|
6342
|
+
return { \u5024: \u5668, \u67A0: { \u5143: v, \u5668, \u540D\u524D\u306E\u4E26\u3073, \u9577\u3055: \u540D\u524D\u306E\u4E26\u3073.length, \u6B21: 0, \u6DF1\u3055, path } };
|
|
6343
|
+
};
|
|
6344
|
+
try {
|
|
6345
|
+
const \u5148\u982D = \u5668\u3092\u4F5C\u308B(root, 0, "$");
|
|
6346
|
+
const \u7A4D\u307F = \u5148\u982D.\u67A0 ? [\u5148\u982D.\u67A0] : [];
|
|
6347
|
+
while (\u7A4D\u307F.length > 0) {
|
|
6348
|
+
const \u4ECA = \u7A4D\u307F[\u7A4D\u307F.length - 1];
|
|
6349
|
+
if (\u4ECA.\u6B21 >= \u4ECA.\u9577\u3055) {
|
|
6350
|
+
\u7A4D\u307F.pop();
|
|
6351
|
+
continue;
|
|
6352
|
+
}
|
|
6353
|
+
const key = \u4ECA.\u540D\u524D\u306E\u4E26\u3073 === null ? String(\u4ECA.\u6B21) : \u4ECA.\u540D\u524D\u306E\u4E26\u3073[\u4ECA.\u6B21];
|
|
6354
|
+
\u4ECA.\u6B21 += 1;
|
|
6355
|
+
const \u5B50\u306Epath = \u4ECA.\u540D\u524D\u306E\u4E26\u3073 === null ? `${\u4ECA.path}[${key}]` : `${\u4ECA.path}.${key}`;
|
|
6356
|
+
\u8AAD\u3093\u3067\u3044\u308B\u5834\u6240 = \u5B50\u306Epath;
|
|
6357
|
+
const \u751F\u306E\u5024 = \u4ECA.\u5143[key];
|
|
6358
|
+
const \u5B50 = \u5668\u3092\u4F5C\u308B(\u751F\u306E\u5024, \u4ECA.\u6DF1\u3055 + 1, \u5B50\u306Epath);
|
|
6359
|
+
if (Array.isArray(\u4ECA.\u5668)) \u4ECA.\u5668.push(\u5B50.\u5024);
|
|
6360
|
+
else {
|
|
6361
|
+
Object.defineProperty(\u4ECA.\u5668, key, {
|
|
6362
|
+
value: \u5B50.\u5024,
|
|
6363
|
+
enumerable: true,
|
|
6364
|
+
writable: true,
|
|
6365
|
+
configurable: true
|
|
6366
|
+
});
|
|
6367
|
+
}
|
|
6368
|
+
if (\u5B50.\u67A0) \u7A4D\u307F.push(\u5B50.\u67A0);
|
|
6369
|
+
}
|
|
6370
|
+
return { ok: true, value: \u5148\u982D.\u5024 };
|
|
6371
|
+
} catch (e) {
|
|
6372
|
+
if (e instanceof \u5199\u305B\u306A\u3044) {
|
|
6373
|
+
return { ok: false, error: { path: e.path, message: e.\u7406\u7531 } };
|
|
6374
|
+
}
|
|
6375
|
+
return {
|
|
6376
|
+
ok: false,
|
|
6377
|
+
error: {
|
|
6378
|
+
path: \u8AAD\u3093\u3067\u3044\u308B\u5834\u6240,
|
|
6379
|
+
message: "\u5165\u529B\u3092\u8AAD\u307F\u53D6\u308C\u306A\u3044",
|
|
6380
|
+
hint: e instanceof Error ? e.message : String(e)
|
|
6381
|
+
}
|
|
6382
|
+
};
|
|
6383
|
+
}
|
|
6384
|
+
}
|
|
4482
6385
|
function validateJson(json) {
|
|
4483
6386
|
const errors = [];
|
|
4484
|
-
|
|
6387
|
+
let root\u304Cobject\u304B;
|
|
6388
|
+
try {
|
|
6389
|
+
root\u304Cobject\u304B = !!json && typeof json === "object" && !Array.isArray(json);
|
|
6390
|
+
} catch (e) {
|
|
6391
|
+
return {
|
|
6392
|
+
ok: false,
|
|
6393
|
+
errors: [
|
|
6394
|
+
{
|
|
6395
|
+
path: "$",
|
|
6396
|
+
message: "\u5165\u529B\u3092\u8AAD\u307F\u53D6\u308C\u306A\u3044",
|
|
6397
|
+
hint: e instanceof Error ? e.message : String(e)
|
|
6398
|
+
}
|
|
6399
|
+
]
|
|
6400
|
+
};
|
|
6401
|
+
}
|
|
6402
|
+
if (!root\u304Cobject\u304B) {
|
|
4485
6403
|
return { ok: false, errors: [{ path: "$", message: "root must be a JSON object" }] };
|
|
4486
6404
|
}
|
|
4487
|
-
const
|
|
6405
|
+
const \u5199\u3057 = \u7D20\u306E\u30C7\u30FC\u30BF\u306B\u5199\u3059(json);
|
|
6406
|
+
if (!\u5199\u3057.ok) return { ok: false, errors: [\u5199\u3057.error] };
|
|
6407
|
+
const j = \u5199\u3057.value;
|
|
4488
6408
|
if (typeof j.title !== "string" || j.title.length === 0) {
|
|
4489
6409
|
errors.push({ path: "$.title", message: "title must be a non-empty string" });
|
|
4490
6410
|
}
|
|
6411
|
+
if (j.eyebrow !== void 0 && typeof j.eyebrow !== "string") {
|
|
6412
|
+
errors.push({ path: "$.eyebrow", message: "eyebrow must be a string if present" });
|
|
6413
|
+
}
|
|
4491
6414
|
if (j.layout !== void 0 && j.layout !== "auto" && j.layout !== "manual") {
|
|
4492
6415
|
errors.push({ path: "$.layout", message: 'layout must be "auto" or "manual" if present' });
|
|
4493
6416
|
}
|
|
@@ -4567,12 +6490,109 @@ function validateJson(json) {
|
|
|
4567
6490
|
if (typeof po.step !== "string" || po.step.length === 0) {
|
|
4568
6491
|
errors.push({ path: `$.animation[${i}].step`, message: "phase.step must be a non-empty string" });
|
|
4569
6492
|
}
|
|
6493
|
+
validatePhaseMotion(po, i, errors);
|
|
4570
6494
|
});
|
|
4571
6495
|
}
|
|
4572
6496
|
}
|
|
6497
|
+
validateStates(j.states, errors);
|
|
6498
|
+
validateValues(j.values, errors);
|
|
4573
6499
|
if (errors.length > 0) return { ok: false, errors };
|
|
4574
6500
|
return { ok: true, data: j };
|
|
4575
6501
|
}
|
|
6502
|
+
function validatePhaseMotion(po, i, errors) {
|
|
6503
|
+
if (po.tween !== void 0) {
|
|
6504
|
+
if (!po.tween || typeof po.tween !== "object" || Array.isArray(po.tween)) {
|
|
6505
|
+
errors.push({
|
|
6506
|
+
path: `$.animation[${i}].tween`,
|
|
6507
|
+
message: "tween must be a plain object of state -> [from, to]"
|
|
6508
|
+
});
|
|
6509
|
+
} else {
|
|
6510
|
+
for (const [name, range] of Object.entries(po.tween)) {
|
|
6511
|
+
const path = `$.animation[${i}].tween.${name}`;
|
|
6512
|
+
if (!isValueName(name)) errors.push({ path, ...valueNameIssue(name) });
|
|
6513
|
+
if (!Array.isArray(range) || range.length !== 2) {
|
|
6514
|
+
errors.push({ path, message: "tween value must be [from, to]" });
|
|
6515
|
+
continue;
|
|
6516
|
+
}
|
|
6517
|
+
for (const v of range) {
|
|
6518
|
+
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
6519
|
+
errors.push({ path, message: "tween value must be finite numbers", hint: `got ${typeof v}` });
|
|
6520
|
+
break;
|
|
6521
|
+
}
|
|
6522
|
+
}
|
|
6523
|
+
}
|
|
6524
|
+
}
|
|
6525
|
+
}
|
|
6526
|
+
if (po.set !== void 0) {
|
|
6527
|
+
if (!po.set || typeof po.set !== "object" || Array.isArray(po.set)) {
|
|
6528
|
+
errors.push({
|
|
6529
|
+
path: `$.animation[${i}].set`,
|
|
6530
|
+
message: "set must be a plain object of state -> value"
|
|
6531
|
+
});
|
|
6532
|
+
} else {
|
|
6533
|
+
for (const [name, value] of Object.entries(po.set)) {
|
|
6534
|
+
const path = `$.animation[${i}].set.${name}`;
|
|
6535
|
+
if (!isValueName(name)) errors.push({ path, ...valueNameIssue(name) });
|
|
6536
|
+
const t = typeof value;
|
|
6537
|
+
if (t !== "number" && t !== "string") {
|
|
6538
|
+
errors.push({ path, message: "set value must be a number or string", hint: `got ${t}` });
|
|
6539
|
+
} else if (t === "number" && !Number.isFinite(value)) {
|
|
6540
|
+
errors.push({ path, message: "set value must be a finite number" });
|
|
6541
|
+
}
|
|
6542
|
+
}
|
|
6543
|
+
}
|
|
6544
|
+
}
|
|
6545
|
+
}
|
|
6546
|
+
function validateStates(v, errors) {
|
|
6547
|
+
if (v === void 0) return;
|
|
6548
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
6549
|
+
errors.push({ path: "$.states", message: "states must be a plain object of name -> initial value" });
|
|
6550
|
+
return;
|
|
6551
|
+
}
|
|
6552
|
+
for (const [name, initial] of Object.entries(v)) {
|
|
6553
|
+
if (!isValueName(name)) {
|
|
6554
|
+
errors.push({ path: `$.states.${name}`, ...valueNameIssue(name) });
|
|
6555
|
+
}
|
|
6556
|
+
const t = typeof initial;
|
|
6557
|
+
if (t !== "number" && t !== "string") {
|
|
6558
|
+
errors.push({
|
|
6559
|
+
path: `$.states.${name}`,
|
|
6560
|
+
message: "state initial must be a number or string",
|
|
6561
|
+
hint: `got ${t}`
|
|
6562
|
+
});
|
|
6563
|
+
} else if (t === "number" && !Number.isFinite(initial)) {
|
|
6564
|
+
errors.push({ path: `$.states.${name}`, message: "state initial must be a finite number" });
|
|
6565
|
+
}
|
|
6566
|
+
}
|
|
6567
|
+
}
|
|
6568
|
+
function validateValues(v, errors) {
|
|
6569
|
+
if (v === void 0) return;
|
|
6570
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
6571
|
+
errors.push({ path: "$.values", message: "values must be a plain object of name -> expression" });
|
|
6572
|
+
return;
|
|
6573
|
+
}
|
|
6574
|
+
for (const [name, expression] of Object.entries(v)) {
|
|
6575
|
+
if (!isValueName(name)) {
|
|
6576
|
+
errors.push({ path: `$.values.${name}`, ...valueNameIssue(name) });
|
|
6577
|
+
}
|
|
6578
|
+
if (typeof expression !== "string" || expression.trim() === "") {
|
|
6579
|
+
errors.push({
|
|
6580
|
+
path: `$.values.${name}`,
|
|
6581
|
+
message: "value expression must be a non-empty string",
|
|
6582
|
+
hint: '`"{inflow} - {done}"` \u306E\u5F62\u3067\u66F8\u304F'
|
|
6583
|
+
});
|
|
6584
|
+
continue;
|
|
6585
|
+
}
|
|
6586
|
+
for (const issue of checkValueExpression(expression, name)) {
|
|
6587
|
+
errors.push({ path: `$.values.${name}`, ...issue });
|
|
6588
|
+
}
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6591
|
+
function \u6574\u3048\u305F\u5C0F\u898B\u51FA\u3057(v) {
|
|
6592
|
+
if (v === void 0) return void 0;
|
|
6593
|
+
const t = v.trim();
|
|
6594
|
+
return t.length > 0 ? t : void 0;
|
|
6595
|
+
}
|
|
4576
6596
|
function jsonToDoc(json) {
|
|
4577
6597
|
const p0 = { line: 0 };
|
|
4578
6598
|
const actors = json.actors.map((a) => {
|
|
@@ -4614,28 +6634,44 @@ function jsonToDoc(json) {
|
|
|
4614
6634
|
cardinality: s.cardinality,
|
|
4615
6635
|
labelOffsetX: s.labelOffsetX,
|
|
4616
6636
|
labelOffsetY: s.labelOffsetY,
|
|
6637
|
+
overlay: s.overlay,
|
|
4617
6638
|
// CAR-1693 Phase 1: DSL 表面 pos → 内部 AST layoutPos
|
|
4618
6639
|
layoutPos: s.pos,
|
|
4619
6640
|
pos: p0
|
|
4620
6641
|
}));
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
6642
|
+
const states = Object.entries(json.states ?? {}).map(([name, initial]) => ({
|
|
6643
|
+
name,
|
|
6644
|
+
initial,
|
|
6645
|
+
pos: p0
|
|
6646
|
+
}));
|
|
6647
|
+
const phases = (json.animation ?? []).map((p) => ({
|
|
6648
|
+
name: p.step,
|
|
6649
|
+
durationMs: Math.round((p.duration ?? 1.4) * 1e3),
|
|
6650
|
+
highlight: p.focus,
|
|
6651
|
+
body: p.body,
|
|
6652
|
+
badge: p.badge,
|
|
6653
|
+
// 段の中で動かす分 (#1186)。 記法側の `tweens` / `sets` と同じ形に写す。
|
|
6654
|
+
// 空の配列を置かないのは、記法側が「無ければ field ごと持たない」 形だから
|
|
6655
|
+
...p.tween && Object.keys(p.tween).length > 0 ? {
|
|
6656
|
+
tweens: Object.entries(p.tween).map(([state, [from, to]]) => ({ state, from, to, pos: p0 }))
|
|
6657
|
+
} : {},
|
|
6658
|
+
...p.set && Object.keys(p.set).length > 0 ? { sets: Object.entries(p.set).map(([state, value]) => ({ state, value, pos: p0 })) } : {},
|
|
6659
|
+
pos: p0
|
|
6660
|
+
}));
|
|
6661
|
+
const animate = states.length > 0 || phases.length > 0 ? { states, phases, pos: p0 } : void 0;
|
|
4633
6662
|
return {
|
|
4634
6663
|
title: json.title,
|
|
4635
6664
|
type: json.type,
|
|
6665
|
+
// 前後の空白を落としてから見る。 記法側 (`v05/parser.ts`) が `trim()` してから
|
|
6666
|
+
// 空かどうかを判定するため、 揃えないと **空白だけの値で入口ごとに図が変わる**
|
|
6667
|
+
// (記法は書かなかった扱い、 JSON は中身のない帯を描く。 Round 2 の指摘で実測)
|
|
6668
|
+
...\u6574\u3048\u305F\u5C0F\u898B\u51FA\u3057(json.eyebrow) !== void 0 ? { eyebrow: \u6574\u3048\u305F\u5C0F\u898B\u51FA\u3057(json.eyebrow), eyebrowPos: p0 } : {},
|
|
4636
6669
|
actors,
|
|
4637
6670
|
flow: flow2,
|
|
4638
6671
|
animate,
|
|
6672
|
+
// 他の値から決まる値 (#1181)。 書いた順に並べる = 解く順は参照から決まるので順序に
|
|
6673
|
+
// 意味は無いが、知らせの並びが書いた順になる
|
|
6674
|
+
values: json.values ? Object.entries(json.values).map(([name, expression]) => ({ name, expression, pos: p0 })) : void 0,
|
|
4639
6675
|
viewport: json.viewport ? { ...json.viewport, pos: p0 } : void 0,
|
|
4640
6676
|
lanes: json.lanes ? Object.fromEntries(
|
|
4641
6677
|
Object.entries(json.lanes).map(([id, l]) => {
|
|
@@ -4682,8 +6718,12 @@ var diagram_default = {
|
|
|
4682
6718
|
},
|
|
4683
6719
|
type: {
|
|
4684
6720
|
type: "string",
|
|
4685
|
-
enum: ["sequence", "flow", "swimlane", "er", "state", "topology", "solidity", "gantt", "class", "pie", "c4", "mind"],
|
|
4686
|
-
description:
|
|
6721
|
+
enum: ["sequence", "flow", "swimlane", "er", "state", "topology", "solidity", "gantt", "class", "pie", "bar", "line", "funnel", "tree", "journey", "quadrant", "c4", "mind"],
|
|
6722
|
+
description: '\u56F3\u306E\u7A2E\u985E\u3002 \u578B\u3054\u3068\u306B actors \u306E\u66F8\u304D\u65B9\u304C\u9055\u3046\u3002 [\u95A2\u4FC2\u3092\u63CF\u304F] sequence (\u6642\u7CFB\u5217\u306E\u547C\u3073\u51FA\u3057) / flow (\u51E6\u7406\u306E\u6D41\u308C) / swimlane (\u8CAC\u52D9\u3054\u3068\u306E\u6D41\u308C) / er (DB \u306E schema) / state (\u72B6\u614B\u306E\u9077\u79FB) / topology (network) / solidity (contract) / class (UML \u306E class) / c4 (architecture) / mind (\u767A\u60F3\u306E\u679D\u5206\u304B\u308C) \u306F actors \u306B\u540D\u524D\u3092\u4E26\u3079 flow \u306B\u77E2\u5370\u3092\u66F8\u304F\u3002 [\u5024\u3092\u63CF\u304F] pie (\u5272\u5408) / bar (\u68D2\u306E\u9AD8\u3055) / line (\u7DDA\u306E\u9AD8\u3055\u3001 \u66F8\u3044\u305F\u9806\u306B\u4E26\u3076) \u306F actors \u306B `- \u540D\u524D: "45"` \u306E\u5F62\u3067\u6570\u3092\u66F8\u304F\u3002 funnel (\u6BB5\u3054\u3068\u306B\u6E1B\u308B\u6570) \u3082\u540C\u3058\u5F62\u3002 [\u8A9E\u3092\u63CF\u304F] journey (\u4F53\u9A13\u306E\u8D77\u4F0F) \u306F `- \u767B\u9332: "\u4E0D\u6E80"` \u306E\u5F62\u3067 \u6700\u9AD8 / \u6E80\u8DB3 / \u666E\u901A / \u4E0D\u6E80 / \u6012\u308A \u306E\u3069\u308C\u304B\u3092\u66F8\u304F\u3002 quadrant (2 \u8EF8\u306E\u4ED5\u5206\u3051) \u306F `- \u91CD\u8907\u524A\u9664: "\u5DE6\u4E0A"` \u306E\u5F62\u3067 \u5DE6\u4E0A / \u53F3\u4E0A / \u5DE6\u4E0B / \u53F3\u4E0B \u306E\u3069\u308C\u304B\u3092\u66F8\u304F\u3002 [\u6642\u671F\u3092\u63CF\u304F] gantt (\u5DE5\u7A0B\u306E\u4E26\u3073) \u306F `- \u8A2D\u8A08: "1\u6708"` \u306E\u5F62\u3067\u59CB\u307E\u308A\u306E\u6642\u671F\u3092\u66F8\u304D\u3001 flow \u306E\u77E2\u5370\u3067\u524D\u5F8C\u95A2\u4FC2\u3092\u66F8\u304F\u3002 [\u89AA\u5B50\u3092\u63CF\u304F] tree (\u89AA\u5B50\u306E\u5165\u308C\u5B50) \u306F actors \u306B\u540D\u524D\u3092\u4E26\u3079 flow \u306E\u77E2\u5370\u3067\u89AA\u5B50\u3092\u66F8\u304F (\u77E2\u5370\u306E\u5148\u304C\u5B50)'
|
|
6723
|
+
},
|
|
6724
|
+
eyebrow: {
|
|
6725
|
+
type: "string",
|
|
6726
|
+
description: "\u56F3\u8868\u306E\u7BB1\u306E\u4E0A\u306B\u51FA\u3059\u5C0F\u898B\u51FA\u3057 (\u7701\u7565\u53EF)\u3002 \u52B9\u304F\u306E\u306F\u56F3\u5168\u4F53\u3092 1 \u7BB1\u306B\u3059\u308B\u578B (pie / bar / line / funnel / tree / journey / quadrant / mind / gantt) \u3060\u3051\u3002 \u7BB1\u3054\u3068\u306B\u5206\u304B\u308C\u308B\u578B\u3067\u306F\u76F8\u624B\u304C\u6C7A\u307E\u3089\u306A\u3044\u305F\u3081\u3001 actors[].eyebrow \u306B\u66F8\u304F"
|
|
4687
6727
|
},
|
|
4688
6728
|
actors: {
|
|
4689
6729
|
type: "array",
|
|
@@ -4735,13 +6775,39 @@ var diagram_default = {
|
|
|
4735
6775
|
guard: { type: "string", description: "state \u9077\u79FB\u306E\u6761\u4EF6 (kind: state \u7528)" },
|
|
4736
6776
|
cardinality: { type: "string", description: "ER \u306E\u591A\u91CD\u5EA6 (1..N \u7B49\u3001 kind: er \u7528)" },
|
|
4737
6777
|
labelOffsetX: { type: "number", description: "\u30E9\u30D9\u30EB\u4F4D\u7F6E x \u8ABF\u6574" },
|
|
4738
|
-
labelOffsetY: { type: "number", description: "\u30E9\u30D9\u30EB\u4F4D\u7F6E y \u8ABF\u6574" }
|
|
6778
|
+
labelOffsetY: { type: "number", description: "\u30E9\u30D9\u30EB\u4F4D\u7F6E y \u8ABF\u6574" },
|
|
6779
|
+
overlay: { type: "boolean", description: "true \u3067\u8AAC\u660E\u6587\u3092\u77E2\u5370\u306E\u7DDA\u306E\u4E0A\u306B\u91CD\u306D\u308B (\u5206\u5C90\u56F3\u306E\u6761\u4EF6\u30E9\u30D9\u30EB\u7528)" }
|
|
4739
6780
|
}
|
|
4740
6781
|
}
|
|
4741
6782
|
},
|
|
6783
|
+
states: {
|
|
6784
|
+
type: "object",
|
|
6785
|
+
description: "\u72B6\u614B\u306E\u521D\u671F\u5024\u3002 \u540D\u524D -> \u521D\u671F\u5024 \u306E object\u3002 optional\u3002 \u7BB1\u306E\u6587\u5B57\u306B `{\u540D\u524D}` \u3092\u7F6E\u304F\u3068\u3001 \u3053\u3053\u306B\u66F8\u3044\u305F\u5024\u304C\u63CF\u753B\u6642\u306B\u7F6E\u304D\u63DB\u308F\u308B\u3002 \u6BB5\u3067\u52D5\u304B\u3059\u306B\u306F animation[].tween / animation[].set \u3092\u4F7F\u3046\u3002",
|
|
6786
|
+
additionalProperties: false,
|
|
6787
|
+
patternProperties: {
|
|
6788
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": {
|
|
6789
|
+
type: ["number", "string"],
|
|
6790
|
+
description: "\u521D\u671F\u5024\u3002 \u6570\u304B\u6587\u5B57\u5217\u3002 \u540D\u524D\u306F\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046"
|
|
6791
|
+
}
|
|
6792
|
+
},
|
|
6793
|
+
examples: [{ inflow: 0, done: 0 }]
|
|
6794
|
+
},
|
|
6795
|
+
values: {
|
|
6796
|
+
type: "object",
|
|
6797
|
+
description: "\u4ED6\u306E\u5024\u304B\u3089\u81EA\u52D5\u3067\u6C7A\u307E\u308B\u5024\u3002 \u540D\u524D -> \u5F0F \u306E object\u3002 optional\u3002 \u5F0F\u306B\u306F\u56DB\u5247 (+ - * /) \u3068\u62EC\u5F27\u3001 \u6BD4\u8F03 (> >= < <= == !=)\u3001 min / max \u304C\u66F8\u3051\u308B\u3002 \u4ED6\u306E\u5024\u306F {\u540D\u524D} \u3067\u8AAD\u3080\u3002 \u89E3\u304F\u306E\u306F\u63CF\u753B\u5074\u3067\u3001 \u53C2\u7167\u3057\u305F\u5024\u304C\u52D5\u3051\u3070\u8FFD\u968F\u3059\u308B\u3002",
|
|
6798
|
+
additionalProperties: false,
|
|
6799
|
+
patternProperties: {
|
|
6800
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": {
|
|
6801
|
+
type: "string",
|
|
6802
|
+
minLength: 1,
|
|
6803
|
+
description: "\u5F0F\u3002 \u4F8B `{inflow} - {done}`"
|
|
6804
|
+
}
|
|
6805
|
+
},
|
|
6806
|
+
examples: [{ waiting: "{inflow} - {done}", busy: "{waiting} > 80" }]
|
|
6807
|
+
},
|
|
4742
6808
|
animation: {
|
|
4743
6809
|
type: "array",
|
|
4744
|
-
description: "\u30A2\u30CB\u30E1\u30FC\u30B7\u30E7\u30F3 phase \u914D\u5217\u3002 \u5404 phase \u3067 focus \u5BFE\u8C61\u3092 highlight \u3059\
|
|
6810
|
+
description: "\u30A2\u30CB\u30E1\u30FC\u30B7\u30E7\u30F3 phase \u914D\u5217\u3002 \u5404 phase \u3067 focus \u5BFE\u8C61\u3092 highlight \u3057\u3001 tween / set \u3067 states \u306E\u5024\u3092\u52D5\u304B\u3059\u3002 optional\u3002",
|
|
4745
6811
|
items: {
|
|
4746
6812
|
type: "object",
|
|
4747
6813
|
required: ["step"],
|
|
@@ -4751,7 +6817,28 @@ var diagram_default = {
|
|
|
4751
6817
|
duration: { type: "number", minimum: 0.1, description: "phase \u6642\u9593 (\u79D2\u3001 default 1.4)" },
|
|
4752
6818
|
focus: { type: "array", items: { type: "string" }, description: "\u3053\u306E phase \u3067 active \u5316\u3059\u308B actor \u540D or edge 'A -> B' \u306E\u914D\u5217" },
|
|
4753
6819
|
body: { type: "string", description: "phase \u8AAC\u660E\u6587" },
|
|
4754
|
-
badge: { type: "string", description: "phase \u4E2D\u306B\u8868\u793A\u3059\u308B badge label" }
|
|
6820
|
+
badge: { type: "string", description: "phase \u4E2D\u306B\u8868\u793A\u3059\u308B badge label" },
|
|
6821
|
+
tween: {
|
|
6822
|
+
type: "object",
|
|
6823
|
+
description: "\u3053\u306E phase \u3067\u88DC\u9593\u3059\u308B\u72B6\u614B\u3002 \u72B6\u614B\u540D -> [\u958B\u59CB\u5024, \u7D42\u4E86\u5024]\u3002 \u540D\u524D\u306F\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046",
|
|
6824
|
+
additionalProperties: false,
|
|
6825
|
+
patternProperties: {
|
|
6826
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": {
|
|
6827
|
+
type: "array",
|
|
6828
|
+
items: { type: "number" },
|
|
6829
|
+
minItems: 2,
|
|
6830
|
+
maxItems: 2
|
|
6831
|
+
}
|
|
6832
|
+
}
|
|
6833
|
+
},
|
|
6834
|
+
set: {
|
|
6835
|
+
type: "object",
|
|
6836
|
+
description: "\u3053\u306E phase \u306E\u5207\u66FF\u3067\u5DEE\u3057\u66FF\u3048\u308B\u72B6\u614B\u3002 \u72B6\u614B\u540D -> \u5024\u3002 \u540D\u524D\u306F\u82F1\u5B57\u304B _ \u3067\u59CB\u3081\u3001 \u82F1\u6570\u5B57\u3068 _ \u3060\u3051\u3092\u4F7F\u3046",
|
|
6837
|
+
additionalProperties: false,
|
|
6838
|
+
patternProperties: {
|
|
6839
|
+
"^[a-zA-Z_][a-zA-Z0-9_]*$": { type: ["number", "string"] }
|
|
6840
|
+
}
|
|
6841
|
+
}
|
|
4755
6842
|
}
|
|
4756
6843
|
}
|
|
4757
6844
|
},
|
|
@@ -4865,6 +6952,6 @@ function isV05Source(src) {
|
|
|
4865
6952
|
return true;
|
|
4866
6953
|
}
|
|
4867
6954
|
|
|
4868
|
-
export { DIAGRAM_BOUNDARY_PADDING, MAX_INPUT_BYTES, MAX_INPUT_ELEMENTS, MAX_PART_SCALE, NODE_KIND_ALIAS, NODE_KIND_VALID, PRESET_TYPES, RELATIVE_GAP_DEFAULT, TONE_ALIAS, autoFix, compileToCdl, computeDiagramBoundingBox, countBytes, countDiagramElements, countDocElements, describeOversize, describeOversizeSource, diagramJsonSchema, isColorValue, jsonToDiagram, lintDiagram, measureActorBoxes, normalizePartScale, orderByDependency, parseFocusEntry, parseRelativePos, parseTextDsl, parseTextDslV05, partBoxInFrame, partDrawsInDiagram, partIsMeasurable, partRenderSize, partScaleFactor, partTargetScale, partTargetSize, partVisualSize, partsGridCenters, pointsOutside, rectsOverlap, resolveRelativePos, stripExternalPaint, stripQuotes, textDslToDiagram, validateDragonJson, writeActorPosition };
|
|
6955
|
+
export { DIAGRAM_BOUNDARY_PADDING, MAX_INPUT_BYTES, MAX_INPUT_ELEMENTS, MAX_PART_SCALE, NODE_KIND_ALIAS, NODE_KIND_VALID, PRESET_TYPES, RELATIVE_GAP_DEFAULT, TONE_ALIAS, TOP_LEVEL_KEYS, autoFix, compileToCdl, computeDiagramBoundingBox, countBytes, countDiagramElements, countDocElements, describeOversize, describeOversizeSource, diagramJsonSchema, isColorValue, jsonToDiagram, lintDiagram, measureActorBoxes, normalizePartScale, orderByDependency, parseFocusEntry, parseRelativePos, parseTextDsl, parseTextDslV05, partBoxInFrame, partDrawsInDiagram, partIsMeasurable, partRenderSize, partScaleFactor, partTargetScale, partTargetSize, partVisualSize, partsGridCenters, pointsOutside, rectsOverlap, resolveRelativePos, stripExternalPaint, stripQuotes, textDslToDiagram, validateDragonJson, writeActorPosition };
|
|
4869
6956
|
//# sourceMappingURL=index.js.map
|
|
4870
6957
|
//# sourceMappingURL=index.js.map
|