@fmsim/figure-capabilities 0.0.0-stage → 3.0.0-beta.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.
@@ -0,0 +1,7 @@
1
+ export type AnimationConfig = {
2
+ [key: string]: any;
3
+ };
4
+ export interface AnimationPreset {
5
+ [state: string]: AnimationConfig | string | null;
6
+ }
7
+ export declare const ANIMATION_DEFAULT: AnimationPreset;
@@ -0,0 +1,6 @@
1
+ export const ANIMATION_DEFAULT = {
2
+ WARN: null,
3
+ CRITICAL: null,
4
+ default: null
5
+ };
6
+ //# sourceMappingURL=animation-default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation-default.js","sourceRoot":"","sources":["../src/animation-default.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,iBAAiB,GAAoB;IAChD,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;CACd,CAAA","sourcesContent":["export type AnimationConfig = {\n [key: string]: any\n}\n\nexport interface AnimationPreset {\n [state: string]: AnimationConfig | string | null\n}\n\nexport const ANIMATION_DEFAULT: AnimationPreset = {\n WARN: null,\n CRITICAL: null,\n default: null\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import type { FigureCapabilityDescriptor } from '@hatiolab/things-scene';
2
+ /** The lists a holder's legend properties offer: what the board that runs it has (fmsim reads them from its API). */
3
+ export interface CarrierHolderLegendOptions {
4
+ legends?: unknown;
5
+ animations?: unknown;
6
+ }
7
+ /**
8
+ * The properties a carrier holder adds (ADR-0167 decision 11): its two carrier legends and whether carriers show their
9
+ * text. The legend lists are the running board's: given where the descriptor is registered, none in the modeller.
10
+ */
11
+ export declare function carrierHolderProperties(options?: CarrierHolderLegendOptions): ({
12
+ type: string;
13
+ label: string;
14
+ name: string;
15
+ property: {
16
+ options: {};
17
+ };
18
+ } | {
19
+ type: string;
20
+ label: string;
21
+ name: string;
22
+ property?: undefined;
23
+ })[];
24
+ /**
25
+ * `fmsim.CarrierHolder` (ADR-0167 decision 11): what a holder of MCS carriers is, worn by fmsim's own holders and by a
26
+ * figure alike. It needs Holdable and Capacity under it, or FlowNode, which takes both in; it reads the holder's fixed data -- STATUS, the representative
27
+ * CARRIERNAME and MULTICARRIERS bottom first, a carrier's CARRIERNAME, CARRIERTYPE, EMPTYTYPE and CARRIERSTATUS -- and
28
+ * gives the carriers on its places its two carrier legends.
29
+ */
30
+ export declare const CARRIER_HOLDER: FigureCapabilityDescriptor;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The properties a carrier holder adds (ADR-0167 decision 11): its two carrier legends and whether carriers show their
3
+ * text. The legend lists are the running board's: given where the descriptor is registered, none in the modeller.
4
+ */
5
+ export function carrierHolderProperties(options = {}) {
6
+ var _a, _b;
7
+ return [
8
+ {
9
+ type: 'select',
10
+ label: 'carrier-legend-name',
11
+ name: 'carrierLegendName',
12
+ property: {
13
+ options: (_a = options.legends) !== null && _a !== void 0 ? _a : []
14
+ }
15
+ },
16
+ {
17
+ type: 'select',
18
+ label: 'carrier-animation-name',
19
+ name: 'carrierAnimationName',
20
+ property: {
21
+ options: (_b = options.animations) !== null && _b !== void 0 ? _b : []
22
+ }
23
+ },
24
+ {
25
+ type: 'boolean',
26
+ label: 'show-carrier-text',
27
+ name: 'showCarrierText'
28
+ }
29
+ ];
30
+ }
31
+ /**
32
+ * `fmsim.CarrierHolder` (ADR-0167 decision 11): what a holder of MCS carriers is, worn by fmsim's own holders and by a
33
+ * figure alike. It needs Holdable and Capacity under it, or FlowNode, which takes both in; it reads the holder's fixed data -- STATUS, the representative
34
+ * CARRIERNAME and MULTICARRIERS bottom first, a carrier's CARRIERNAME, CARRIERTYPE, EMPTYTYPE and CARRIERSTATUS -- and
35
+ * gives the carriers on its places its two carrier legends.
36
+ */
37
+ export const CARRIER_HOLDER = {
38
+ name: 'fmsim.CarrierHolder',
39
+ label: 'Carrier holder',
40
+ note: 'MCS 캐리어를 받는다 — 홀더 데이터에서 캐리어를 만들고, 자리에 올라간 캐리어에 캐리어 범례와 애니메이션을 넘긴다',
41
+ version: '1',
42
+ needs: [['Holdable', 'FlowNode'], ['Capacity', 'FlowNode']],
43
+ properties: carrierHolderProperties(),
44
+ /* Its carriers come from MCS data: where fmsim registers it, an items binding of the figure's rests (ADR-0167 decision 17). */
45
+ takes: () => ({ items: true }),
46
+ data: [
47
+ { name: 'STATUS' },
48
+ { name: 'CARRIERNAME' },
49
+ { name: 'MULTICARRIERS' },
50
+ { name: 'CARRIERTYPE' },
51
+ { name: 'EMPTYTYPE' },
52
+ { name: 'CARRIERSTATUS' }
53
+ ]
54
+ };
55
+ //# sourceMappingURL=carrier-holder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carrier-holder.js","sourceRoot":"","sources":["../src/carrier-holder.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,UAAsC,EAAE;;IAC9E,OAAO;QACL;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,qBAAqB;YAC5B,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE;gBACR,OAAO,EAAE,MAAA,OAAO,CAAC,OAAO,mCAAI,EAAE;aAC/B;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,wBAAwB;YAC/B,IAAI,EAAE,sBAAsB;YAC5B,QAAQ,EAAE;gBACR,OAAO,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,EAAE;aAClC;SACF;QACD;YACE,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,iBAAiB;SACxB;KACF,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAA+B;IACxD,IAAI,EAAE,qBAAqB;IAC3B,KAAK,EAAE,gBAAgB;IACvB,IAAI,EAAE,mEAAmE;IACzE,OAAO,EAAE,GAAG;IACZ,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC3D,UAAU,EAAE,uBAAuB,EAAW;IAC9C,+HAA+H;IAC/H,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAI,EAAE;QACJ,EAAE,IAAI,EAAE,QAAQ,EAAE;QAClB,EAAE,IAAI,EAAE,aAAa,EAAE;QACvB,EAAE,IAAI,EAAE,eAAe,EAAE;QACzB,EAAE,IAAI,EAAE,aAAa,EAAE;QACvB,EAAE,IAAI,EAAE,WAAW,EAAE;QACrB,EAAE,IAAI,EAAE,eAAe,EAAE;KAC1B;CACF,CAAA","sourcesContent":["import type { FigureCapabilityDescriptor } from '@hatiolab/things-scene'\n\n/** The lists a holder's legend properties offer: what the board that runs it has (fmsim reads them from its API). */\nexport interface CarrierHolderLegendOptions {\n legends?: unknown\n animations?: unknown\n}\n\n/**\n * The properties a carrier holder adds (ADR-0167 decision 11): its two carrier legends and whether carriers show their\n * text. The legend lists are the running board's: given where the descriptor is registered, none in the modeller.\n */\nexport function carrierHolderProperties(options: CarrierHolderLegendOptions = {}) {\n return [\n {\n type: 'select',\n label: 'carrier-legend-name',\n name: 'carrierLegendName',\n property: {\n options: options.legends ?? []\n }\n },\n {\n type: 'select',\n label: 'carrier-animation-name',\n name: 'carrierAnimationName',\n property: {\n options: options.animations ?? []\n }\n },\n {\n type: 'boolean',\n label: 'show-carrier-text',\n name: 'showCarrierText'\n }\n ]\n}\n\n/**\n * `fmsim.CarrierHolder` (ADR-0167 decision 11): what a holder of MCS carriers is, worn by fmsim's own holders and by a\n * figure alike. It needs Holdable and Capacity under it, or FlowNode, which takes both in; it reads the holder's fixed data -- STATUS, the representative\n * CARRIERNAME and MULTICARRIERS bottom first, a carrier's CARRIERNAME, CARRIERTYPE, EMPTYTYPE and CARRIERSTATUS -- and\n * gives the carriers on its places its two carrier legends.\n */\nexport const CARRIER_HOLDER: FigureCapabilityDescriptor = {\n name: 'fmsim.CarrierHolder',\n label: 'Carrier holder',\n note: 'MCS 캐리어를 받는다 — 홀더 데이터에서 캐리어를 만들고, 자리에 올라간 캐리어에 캐리어 범례와 애니메이션을 넘긴다',\n version: '1',\n needs: [['Holdable', 'FlowNode'], ['Capacity', 'FlowNode']],\n properties: carrierHolderProperties() as never,\n /* Its carriers come from MCS data: where fmsim registers it, an items binding of the figure's rests (ADR-0167 decision 17). */\n takes: () => ({ items: true }),\n data: [\n { name: 'STATUS' },\n { name: 'CARRIERNAME' },\n { name: 'MULTICARRIERS' },\n { name: 'CARRIERTYPE' },\n { name: 'EMPTYTYPE' },\n { name: 'CARRIERSTATUS' }\n ]\n}\n"]}
@@ -0,0 +1,40 @@
1
+ import type { FigureCapabilityDescriptor } from '@hatiolab/things-scene';
2
+ import type { FigureAsset, FigureDataBinding } from '@hatiolab/figure-model';
3
+ /** The codes of a carrier's load (EMPTYTYPE) fmsim fixes: a figure's thickness is given for these only (ADR-0167 12). */
4
+ export declare const CARRIER_LOAD_CODES: readonly ["FULL", "EMPTY", "EMPTYEMPTY"];
5
+ /** The thickness a figure starts with for each code: full, then empty. */
6
+ export declare const CARRIER_FILL_START: {
7
+ FULL: number;
8
+ EMPTY: number;
9
+ EMPTYEMPTY: number;
10
+ };
11
+ /** Why a figure's settings cannot be taken: parts and the input that are not the figure's, keys and values out of place. */
12
+ export declare function carrierSettingsIssues(settings: Record<string, unknown> | undefined, asset: FigureAsset): string[];
13
+ /**
14
+ * The tables the capability hands the ADR-0166 engine: the load's colour (role carrier-legend, fmsim's carrier legend
15
+ * by default) on the load parts, the condition's colour and blink (role carrier-animation, fmsim's default animation) on
16
+ * the body parts or else the load parts, and the thickness by the figure's own fixed table -- no legend, so a legend
17
+ * never gives it.
18
+ */
19
+ export declare function carrierDataInterface(settings: Record<string, unknown> | undefined): {
20
+ schema: {
21
+ name: string;
22
+ label: string;
23
+ kind: 'text';
24
+ }[];
25
+ bindings: FigureDataBinding[];
26
+ } | undefined;
27
+ /**
28
+ * What the capability takes over (ADR-0167 decision 17): the load and body parts' looks and the load's input. Where fmsim
29
+ * registers it, a binding of the figure's on them rests; operato-board, which does not, draws by the binding.
30
+ */
31
+ export declare function carrierTargets(settings: Record<string, unknown> | undefined): {
32
+ parts: string[];
33
+ inputs: string[];
34
+ };
35
+ /**
36
+ * `fmsim.Carrier` (ADR-0167 decision 12): a carrier's look that works when it is put on -- no binding of the author's.
37
+ * The author picks the load parts, the body parts if any, and, for a figure whose thickness follows its load (roll,
38
+ * foil, reel), the input made by 「상태에 따라 크기」 and its value for FULL, EMPTY and EMPTYEMPTY.
39
+ */
40
+ export declare const CARRIER_FIGURE: FigureCapabilityDescriptor;
@@ -0,0 +1,113 @@
1
+ import { ANIMATION_DEFAULT } from './animation-default.js';
2
+ import { LEGEND_CARRIER, legendColor } from './legends.js';
3
+ /** The codes of a carrier's load (EMPTYTYPE) fmsim fixes: a figure's thickness is given for these only (ADR-0167 12). */
4
+ export const CARRIER_LOAD_CODES = ['FULL', 'EMPTY', 'EMPTYEMPTY'];
5
+ /** The thickness a figure starts with for each code: full, then empty. */
6
+ export const CARRIER_FILL_START = { FULL: 100, EMPTY: 0, EMPTYEMPTY: 0 };
7
+ const SETTING_KEYS = ['loadParts', 'bodyParts', 'fill'];
8
+ /** A table entry from one of fmsim's default legends: its colour (a colour or `{ color }`) and effect. */
9
+ function lookOf(entry) {
10
+ const color = legendColor(entry);
11
+ const effect = entry && typeof entry === 'object' ? entry.effect : undefined;
12
+ return Object.assign(Object.assign({}, (color ? { color } : {})), (effect && typeof effect === 'object' ? { effect: effect } : {}));
13
+ }
14
+ /** Why a figure's settings cannot be taken: parts and the input that are not the figure's, keys and values out of place. */
15
+ export function carrierSettingsIssues(settings, asset) {
16
+ var _a;
17
+ const s = (settings !== null && settings !== void 0 ? settings : {});
18
+ const parts = new Set(asset.appearance.map(a => a.target));
19
+ const out = [];
20
+ for (const key of Object.keys(s))
21
+ if (!SETTING_KEYS.includes(key))
22
+ out.push(`${key} 은(는) 이 능력의 설정이 아닙니다.`);
23
+ if (!Array.isArray(s.loadParts) || !s.loadParts.length)
24
+ out.push('적재물 부품을 하나 이상 고릅니다.');
25
+ for (const key of ['loadParts', 'bodyParts'])
26
+ for (const part of Array.isArray(s[key]) ? s[key] : [])
27
+ if (!parts.has(part))
28
+ out.push(`${part} 부품이 없습니다.`);
29
+ if (s.fill !== undefined) {
30
+ const input = asset.document.model.inputs.find(i => i.id === s.fill.input && i.role === 'state');
31
+ if (!input)
32
+ out.push(`적재량 입력 ${String(s.fill.input)} 이(가) 이 피규어의 상태 입력이 아닙니다.`);
33
+ for (const [code, value] of Object.entries((_a = s.fill.values) !== null && _a !== void 0 ? _a : {})) {
34
+ if (!CARRIER_LOAD_CODES.includes(code))
35
+ out.push(`${code} 은(는) 정해진 코드(FULL · EMPTY · EMPTYEMPTY)가 아닙니다.`);
36
+ else if (input && !(Number.isFinite(value) && value >= input.min && value <= input.max))
37
+ out.push(`${code} 의 적재량 ${value} 이(가) 범위 ${input.min}~${input.max} 밖입니다.`);
38
+ }
39
+ }
40
+ return out;
41
+ }
42
+ /**
43
+ * The tables the capability hands the ADR-0166 engine: the load's colour (role carrier-legend, fmsim's carrier legend
44
+ * by default) on the load parts, the condition's colour and blink (role carrier-animation, fmsim's default animation) on
45
+ * the body parts or else the load parts, and the thickness by the figure's own fixed table -- no legend, so a legend
46
+ * never gives it.
47
+ */
48
+ export function carrierDataInterface(settings) {
49
+ var _a, _b, _c, _d;
50
+ const s = (settings !== null && settings !== void 0 ? settings : {});
51
+ const load = (_a = s.loadParts) !== null && _a !== void 0 ? _a : [];
52
+ if (!load.length)
53
+ return undefined;
54
+ const body = ((_b = s.bodyParts) === null || _b === void 0 ? void 0 : _b.length) ? s.bodyParts : load;
55
+ const loadTable = Object.fromEntries(Object.entries(LEGEND_CARRIER).map(([code, entry]) => [code, lookOf(entry)]));
56
+ const conditionTable = Object.fromEntries(Object.entries(ANIMATION_DEFAULT).map(([code, entry]) => [code, lookOf(entry)]));
57
+ const bindings = [
58
+ { id: 'fmsim-carrier-load', label: '적재', accessor: 'EMPTYTYPE', rule: 'table', lookup: 'code', targets: { parts: [...load] }, table: loadTable, legend: { role: 'carrier-legend' } },
59
+ { id: 'fmsim-carrier-condition', label: '상태', accessor: 'CARRIERSTATUS', rule: 'table', lookup: 'code', targets: { parts: [...body] }, table: conditionTable, legend: { role: 'carrier-animation' } }
60
+ ];
61
+ if ((_c = s.fill) === null || _c === void 0 ? void 0 : _c.input) {
62
+ const values = Object.assign(Object.assign({}, CARRIER_FILL_START), ((_d = s.fill.values) !== null && _d !== void 0 ? _d : {}));
63
+ const full = { values: { [s.fill.input]: values.FULL } };
64
+ bindings.push({
65
+ id: 'fmsim-carrier-fill',
66
+ label: '적재량',
67
+ accessor: 'EMPTYTYPE',
68
+ rule: 'table',
69
+ lookup: 'code',
70
+ targets: { inputs: [s.fill.input] },
71
+ /* Another code, or none, is full (ADR-0167 12). */
72
+ table: Object.assign(Object.assign({}, Object.fromEntries(CARRIER_LOAD_CODES.map(code => [code, { values: { [s.fill.input]: values[code] } }]))), { default: full })
73
+ });
74
+ }
75
+ return {
76
+ schema: [
77
+ { name: 'EMPTYTYPE', label: '적재', kind: 'text' },
78
+ { name: 'CARRIERSTATUS', label: '상태', kind: 'text' }
79
+ ],
80
+ bindings
81
+ };
82
+ }
83
+ /**
84
+ * What the capability takes over (ADR-0167 decision 17): the load and body parts' looks and the load's input. Where fmsim
85
+ * registers it, a binding of the figure's on them rests; operato-board, which does not, draws by the binding.
86
+ */
87
+ export function carrierTargets(settings) {
88
+ var _a, _b, _c;
89
+ const s = (settings !== null && settings !== void 0 ? settings : {});
90
+ return { parts: [...new Set([...((_a = s.loadParts) !== null && _a !== void 0 ? _a : []), ...((_b = s.bodyParts) !== null && _b !== void 0 ? _b : [])])], inputs: ((_c = s.fill) === null || _c === void 0 ? void 0 : _c.input) ? [s.fill.input] : [] };
91
+ }
92
+ /**
93
+ * `fmsim.Carrier` (ADR-0167 decision 12): a carrier's look that works when it is put on -- no binding of the author's.
94
+ * The author picks the load parts, the body parts if any, and, for a figure whose thickness follows its load (roll,
95
+ * foil, reel), the input made by 「상태에 따라 크기」 and its value for FULL, EMPTY and EMPTYEMPTY.
96
+ */
97
+ export const CARRIER_FIGURE = {
98
+ name: 'fmsim.Carrier',
99
+ label: 'Carrier',
100
+ note: 'fmsim 캐리어 — 켜기만 하면 적재물 부품에 캐리어 범례의 색, 몸체 부품에 캐리어 애니메이션의 색 · 점멸이 들고, 두께가 바뀌는 피규어는 적재량을 고정 표로 정한다',
101
+ version: '1',
102
+ needs: ['item'],
103
+ data: [{ name: 'EMPTYTYPE' }, { name: 'CARRIERSTATUS' }, { name: 'CARRIERNAME' }, { name: 'CARRIERTYPE' }],
104
+ settings: [
105
+ { key: 'loadParts', kind: 'parts', label: '적재물 부품', required: true },
106
+ { key: 'bodyParts', kind: 'parts', label: '몸체 부품' },
107
+ { key: 'fill', kind: 'input-table', label: '적재량', keys: CARRIER_LOAD_CODES, start: CARRIER_FILL_START }
108
+ ],
109
+ check: carrierSettingsIssues,
110
+ dataInterface: carrierDataInterface,
111
+ takes: carrierTargets
112
+ };
113
+ //# sourceMappingURL=carrier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carrier.js","sourceRoot":"","sources":["../src/carrier.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FigureCapabilityDescriptor } from '@hatiolab/things-scene'\nimport type { FigureAsset, FigureDataBinding, FigureDataTableEntry } from '@hatiolab/figure-model'\n\nimport { ANIMATION_DEFAULT } from './animation-default.js'\nimport { LEGEND_CARRIER, legendColor } from './legends.js'\n\n/** The codes of a carrier's load (EMPTYTYPE) fmsim fixes: a figure's thickness is given for these only (ADR-0167 12). */\nexport const CARRIER_LOAD_CODES = ['FULL', 'EMPTY', 'EMPTYEMPTY'] as const\n/** The thickness a figure starts with for each code: full, then empty. */\nexport const CARRIER_FILL_START = { FULL: 100, EMPTY: 0, EMPTYEMPTY: 0 }\n\nconst SETTING_KEYS = ['loadParts', 'bodyParts', 'fill']\n\ninterface CarrierSettings {\n loadParts?: string[]\n bodyParts?: string[]\n fill?: { input: string; values?: Record<string, number> }\n}\n\n/** A table entry from one of fmsim's default legends: its colour (a colour or `{ color }`) and effect. */\nfunction lookOf(entry: unknown): FigureDataTableEntry {\n const color = legendColor(entry)\n const effect = entry && typeof entry === 'object' ? (entry as { effect?: unknown }).effect : undefined\n return { ...(color ? { color } : {}), ...(effect && typeof effect === 'object' ? { effect: effect as FigureDataTableEntry['effect'] } : {}) }\n}\n\n/** Why a figure's settings cannot be taken: parts and the input that are not the figure's, keys and values out of place. */\nexport function carrierSettingsIssues(settings: Record<string, unknown> | undefined, asset: FigureAsset): string[] {\n const s = (settings ?? {}) as CarrierSettings & Record<string, unknown>\n const parts = new Set(asset.appearance.map(a => a.target))\n const out: string[] = []\n for (const key of Object.keys(s)) if (!SETTING_KEYS.includes(key)) out.push(`${key} 은(는) 이 능력의 설정이 아닙니다.`)\n if (!Array.isArray(s.loadParts) || !s.loadParts.length) out.push('적재물 부품을 하나 이상 고릅니다.')\n for (const key of ['loadParts', 'bodyParts'] as const)\n for (const part of Array.isArray(s[key]) ? s[key]! : []) if (!parts.has(part)) out.push(`${part} 부품이 없습니다.`)\n if (s.fill !== undefined) {\n const input = asset.document.model.inputs.find(i => i.id === s.fill!.input && i.role === 'state')\n if (!input) out.push(`적재량 입력 ${String(s.fill.input)} 이(가) 이 피규어의 상태 입력이 아닙니다.`)\n for (const [code, value] of Object.entries(s.fill.values ?? {})) {\n if (!(CARRIER_LOAD_CODES as readonly string[]).includes(code)) out.push(`${code} 은(는) 정해진 코드(FULL · EMPTY · EMPTYEMPTY)가 아닙니다.`)\n else if (input && !(Number.isFinite(value) && value >= input.min! && value <= input.max!)) out.push(`${code} 의 적재량 ${value} 이(가) 범위 ${input.min}~${input.max} 밖입니다.`)\n }\n }\n return out\n}\n\n/**\n * The tables the capability hands the ADR-0166 engine: the load's colour (role carrier-legend, fmsim's carrier legend\n * by default) on the load parts, the condition's colour and blink (role carrier-animation, fmsim's default animation) on\n * the body parts or else the load parts, and the thickness by the figure's own fixed table -- no legend, so a legend\n * never gives it.\n */\nexport function carrierDataInterface(settings: Record<string, unknown> | undefined): { schema: { name: string; label: string; kind: 'text' }[]; bindings: FigureDataBinding[] } | undefined {\n const s = (settings ?? {}) as CarrierSettings\n const load = s.loadParts ?? []\n if (!load.length) return undefined\n const body = s.bodyParts?.length ? s.bodyParts : load\n const loadTable = Object.fromEntries(Object.entries(LEGEND_CARRIER).map(([code, entry]) => [code, lookOf(entry)]))\n const conditionTable = Object.fromEntries(Object.entries(ANIMATION_DEFAULT).map(([code, entry]) => [code, lookOf(entry)]))\n const bindings: FigureDataBinding[] = [\n { id: 'fmsim-carrier-load', label: '적재', accessor: 'EMPTYTYPE', rule: 'table', lookup: 'code', targets: { parts: [...load] }, table: loadTable, legend: { role: 'carrier-legend' } },\n { id: 'fmsim-carrier-condition', label: '상태', accessor: 'CARRIERSTATUS', rule: 'table', lookup: 'code', targets: { parts: [...body] }, table: conditionTable, legend: { role: 'carrier-animation' } }\n ]\n if (s.fill?.input) {\n const values = { ...CARRIER_FILL_START, ...(s.fill.values ?? {}) }\n const full = { values: { [s.fill.input]: values.FULL } }\n bindings.push({\n id: 'fmsim-carrier-fill',\n label: '적재량',\n accessor: 'EMPTYTYPE',\n rule: 'table',\n lookup: 'code',\n targets: { inputs: [s.fill.input] },\n /* Another code, or none, is full (ADR-0167 12). */\n table: { ...Object.fromEntries(CARRIER_LOAD_CODES.map(code => [code, { values: { [s.fill!.input]: values[code] } }])), default: full }\n })\n }\n return {\n schema: [\n { name: 'EMPTYTYPE', label: '적재', kind: 'text' },\n { name: 'CARRIERSTATUS', label: '상태', kind: 'text' }\n ],\n bindings\n }\n}\n\n/**\n * What the capability takes over (ADR-0167 decision 17): the load and body parts' looks and the load's input. Where fmsim\n * registers it, a binding of the figure's on them rests; operato-board, which does not, draws by the binding.\n */\nexport function carrierTargets(settings: Record<string, unknown> | undefined): { parts: string[]; inputs: string[] } {\n const s = (settings ?? {}) as CarrierSettings\n return { parts: [...new Set([...(s.loadParts ?? []), ...(s.bodyParts ?? [])])], inputs: s.fill?.input ? [s.fill.input] : [] }\n}\n\n/**\n * `fmsim.Carrier` (ADR-0167 decision 12): a carrier's look that works when it is put on -- no binding of the author's.\n * The author picks the load parts, the body parts if any, and, for a figure whose thickness follows its load (roll,\n * foil, reel), the input made by 「상태에 따라 크기」 and its value for FULL, EMPTY and EMPTYEMPTY.\n */\nexport const CARRIER_FIGURE: FigureCapabilityDescriptor = {\n name: 'fmsim.Carrier',\n label: 'Carrier',\n note: 'fmsim 캐리어 — 켜기만 하면 적재물 부품에 캐리어 범례의 색, 몸체 부품에 캐리어 애니메이션의 색 · 점멸이 들고, 두께가 바뀌는 피규어는 적재량을 고정 표로 정한다',\n version: '1',\n needs: ['item'],\n data: [{ name: 'EMPTYTYPE' }, { name: 'CARRIERSTATUS' }, { name: 'CARRIERNAME' }, { name: 'CARRIERTYPE' }],\n settings: [\n { key: 'loadParts', kind: 'parts', label: '적재물 부품', required: true },\n { key: 'bodyParts', kind: 'parts', label: '몸체 부품' },\n { key: 'fill', kind: 'input-table', label: '적재량', keys: CARRIER_LOAD_CODES, start: CARRIER_FILL_START }\n ],\n check: carrierSettingsIssues,\n dataInterface: carrierDataInterface,\n takes: carrierTargets\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { ANIMATION_DEFAULT, type AnimationConfig, type AnimationPreset } from './animation-default.js';
2
+ export { LEGEND_CARRIER, legendColor, type Legend, type LegendEntry } from './legends.js';
3
+ export { CARRIER_HOLDER, carrierHolderProperties, type CarrierHolderLegendOptions } from './carrier-holder.js';
4
+ export { CARRIER_FIGURE, CARRIER_FILL_START, CARRIER_LOAD_CODES, carrierDataInterface, carrierSettingsIssues, carrierTargets } from './carrier.js';
5
+ /** Every capability fmsim defines, for a modeller to register. */
6
+ export declare const FMSIM_FIGURE_CAPABILITIES: import("@hatiolab/things-scene").FigureCapabilityDescriptor[];
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /*
2
+ * What fmsim puts on a figure (ADR-0167): its capabilities' descriptors, their pure functions and fmsim's default
3
+ * tables -- no scene, DOM or API. fmsim's machine registers them with its mixins; operato-figure's modeller registers
4
+ * the descriptors alone.
5
+ */
6
+ export { ANIMATION_DEFAULT } from './animation-default.js';
7
+ export { LEGEND_CARRIER, legendColor } from './legends.js';
8
+ export { CARRIER_HOLDER, carrierHolderProperties } from './carrier-holder.js';
9
+ export { CARRIER_FIGURE, CARRIER_FILL_START, CARRIER_LOAD_CODES, carrierDataInterface, carrierSettingsIssues, carrierTargets } from './carrier.js';
10
+ import { CARRIER_HOLDER } from './carrier-holder.js';
11
+ import { CARRIER_FIGURE } from './carrier.js';
12
+ /** Every capability fmsim defines, for a modeller to register. */
13
+ export const FMSIM_FIGURE_CAPABILITIES = [CARRIER_HOLDER, CARRIER_FIGURE];
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,iBAAiB,EAA8C,MAAM,wBAAwB,CAAA;AACtG,OAAO,EAAE,cAAc,EAAE,WAAW,EAAiC,MAAM,cAAc,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAmC,MAAM,qBAAqB,CAAA;AAC9G,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElJ,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,kEAAkE;AAClE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA","sourcesContent":["/*\n * What fmsim puts on a figure (ADR-0167): its capabilities' descriptors, their pure functions and fmsim's default\n * tables -- no scene, DOM or API. fmsim's machine registers them with its mixins; operato-figure's modeller registers\n * the descriptors alone.\n */\nexport { ANIMATION_DEFAULT, type AnimationConfig, type AnimationPreset } from './animation-default.js'\nexport { LEGEND_CARRIER, legendColor, type Legend, type LegendEntry } from './legends.js'\nexport { CARRIER_HOLDER, carrierHolderProperties, type CarrierHolderLegendOptions } from './carrier-holder.js'\nexport { CARRIER_FIGURE, CARRIER_FILL_START, CARRIER_LOAD_CODES, carrierDataInterface, carrierSettingsIssues, carrierTargets } from './carrier.js'\n\nimport { CARRIER_HOLDER } from './carrier-holder.js'\nimport { CARRIER_FIGURE } from './carrier.js'\n\n/** Every capability fmsim defines, for a modeller to register. */\nexport const FMSIM_FIGURE_CAPABILITIES = [CARRIER_HOLDER, CARRIER_FIGURE]\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 범례 항목: 색 하나, 또는 표 항목과 같은 모양의 객체 `{ color, effect, values, … }` (ADR-0166 7). 객체 항목의 다른 칸(2D 애니메이션
3
+ * 등)은 그 옆에 남는다. 색만 쓰는 곳은 legendColor 로 읽는다.
4
+ */
5
+ export type LegendEntry = string | {
6
+ color?: string;
7
+ [field: string]: unknown;
8
+ };
9
+ export interface Legend {
10
+ [key: string]: LegendEntry;
11
+ }
12
+ /** 범례 항목의 색: 문자열이면 그 색, `{ color }` 면 그 color. 둘 다 아니면 undefined */
13
+ export declare function legendColor(entry: unknown): string | undefined;
14
+ /** 캐리어 적재(EMPTYTYPE)의 fmsim 기본 범례: 2D 캐리어 · 스토커 게이지와 fmsim.Carrier 피규어의 기본표가 같이 쓴다 */
15
+ export declare const LEGEND_CARRIER: Legend;
@@ -0,0 +1,15 @@
1
+ /** 범례 항목의 색: 문자열이면 그 색, `{ color }` 면 그 color. 둘 다 아니면 undefined */
2
+ export function legendColor(entry) {
3
+ if (typeof entry === 'string')
4
+ return entry;
5
+ const color = entry && typeof entry === 'object' ? entry.color : undefined;
6
+ return typeof color === 'string' ? color : undefined;
7
+ }
8
+ /** 캐리어 적재(EMPTYTYPE)의 fmsim 기본 범례: 2D 캐리어 · 스토커 게이지와 fmsim.Carrier 피규어의 기본표가 같이 쓴다 */
9
+ export const LEGEND_CARRIER = {
10
+ FULL: '#4AA7FE',
11
+ EMPTY: '#8BDA5B',
12
+ EMPTYEMPTY: '#019D59',
13
+ default: '#F0F0F0'
14
+ };
15
+ //# sourceMappingURL=legends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legends.js","sourceRoot":"","sources":["../src/legends.ts"],"names":[],"mappings":"AAUA,oEAAoE;AACpE,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,MAAM,KAAK,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAE,KAA6B,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IACnG,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtD,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAW;IACpC,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,UAAU,EAAE,SAAS;IACrB,OAAO,EAAE,SAAS;CACnB,CAAA","sourcesContent":["/**\n * 범례 항목: 색 하나, 또는 표 항목과 같은 모양의 객체 `{ color, effect, values, … }` (ADR-0166 7). 객체 항목의 다른 칸(2D 애니메이션\n * 등)은 그 옆에 남는다. 색만 쓰는 곳은 legendColor 로 읽는다.\n */\nexport type LegendEntry = string | { color?: string; [field: string]: unknown }\n\nexport interface Legend {\n [key: string]: LegendEntry\n}\n\n/** 범례 항목의 색: 문자열이면 그 색, `{ color }` 면 그 color. 둘 다 아니면 undefined */\nexport function legendColor(entry: unknown): string | undefined {\n if (typeof entry === 'string') return entry\n const color = entry && typeof entry === 'object' ? (entry as { color?: unknown }).color : undefined\n return typeof color === 'string' ? color : undefined\n}\n\n/** 캐리어 적재(EMPTYTYPE)의 fmsim 기본 범례: 2D 캐리어 · 스토커 게이지와 fmsim.Carrier 피규어의 기본표가 같이 쓴다 */\nexport const LEGEND_CARRIER: Legend = {\n FULL: '#4AA7FE',\n EMPTY: '#8BDA5B',\n EMPTYEMPTY: '#019D59',\n default: '#F0F0F0'\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,33 @@
1
1
  {
2
2
  "name": "@fmsim/figure-capabilities",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "fmsim 이 피규어에 입히는 능력의 정의(descriptor)와 그 순수 함수, fmsim 기본표. 장면·DOM·API 의존이 없어 operato-figure 모델러와 fmsim 장면이 같이 읽는다 (ADR-0167).",
4
+ "author": "heartyoh",
5
+ "version": "3.0.0-beta.0",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "@fmsim:registry": "https://registry.npmjs.org"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/heartyoh/fmsim.git",
19
+ "directory": "packages/figure-capabilities"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "prepublish": "tsc",
24
+ "test": "jest --config jest.config.js"
25
+ },
26
+ "peerDependencies": {
27
+ "@hatiolab/figure-model": "*",
28
+ "@hatiolab/things-scene": "*"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.8.2"
32
+ }
33
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.